標題: 學51單片機-基于PCF8591的AD采樣和DA輸出 [打印本頁]
作者: jiajiamei 時間: 2015-4-8 22:48
標題: 學51單片機-基于PCF8591的AD采樣和DA輸出
首先思考一個問題,我們的世界是數字的還是模擬的?
當然是模擬的了,所有的量都是在一定范圍內連續變化的。我們為了能夠更加方便的描述這些量,對它們進行了數字化。而數字量就不一樣了,它是分立的的幾個值。
舉個例子,我們形容一個人的身高,模擬的說法是一米七到一米七五之間,數字的說法就是一米七三。
接下來說AD轉換器,它的出現也是為了讓我們能更方便、更直接的描述電壓的高低。AD轉換器,英文全稱為Analog-to-Digital Converter,是模擬量到數字量的一個轉換過程,主要用于電壓的采集。它的出現就如同有了一把尺子,很容易就能量出電壓的高低。
在電子設備中,經常要檢測各種模擬量:溫度、壓力、速度、流量、重力加速度等等,這些模擬量都被相應的傳感器轉換為電壓信號,我們只需要測量電壓的高低,就能得到相應參數。
AD的主要參數有哪些?
1、AD的位數:表明這個AD共有2^n個刻度,8位AD,輸出的刻度是0~255.
2、分辨率:就是AD能夠分辨的最小的模擬量變化,假設5.10V的系統用8位的AD采樣,那么它能分辨的最小電壓就是5.10/255=0.02V。
3、INL:Interger NONliner 積分非線性度,表示了ADC器件在所有的數值點上對應的模擬值,和真實值之間誤差最大的那一點的誤差值。也就是,輸出數值偏離線性最大的距離。單位是LSB(即最低位所表示的量)。比如12位ADC:TLC2543,INL值為1LSB。那么,如果基準4.095V,測某電壓得的轉換結果是1000,那么,真實電壓值可能分布在0.999~1.001V之間。
4、DNL:Differencial NonLiner-差分非線性度,理論上說,模數器件相鄰量個數據之間,模擬量的差值都是一樣的。就相一把疏密均勻的尺子。但實際并不如此。一把分辨率1毫米的尺子,相鄰兩刻度之間也不可能都是1毫米整。那么,ADC相鄰兩刻度之間最大的差異就叫差分非線性值(Differencial NonLiner)。DNL值如果大于1,那么這個ADC甚至不能保證是單調的,輸入電壓增大,在某個點數值反而會減小。這種現象在SAR(逐位比較)型ADC中很常見。
5、基準源:有內部基準源、外部基準源等等。
6、轉換速率:也就是轉換周期的倒數,轉換周期就是完成一次AD轉換所需的時間。
今天要用到的器件是PCF8591,為什么選它?太多的開發板上用它做演示了,而且還是IIC總線通信的。既學習了AD采樣,又學習了IIC總線。
先上應用電路:
如上圖所示,PCF8591的9腳和10腳,一個是數據線SDA,一個是時鐘線SCL。分別接到單片機的P2.0 , P2.1上面。
為什么選這兩個引腳?因為51單片機上沒有IIC總線接口,需要用普通的IO模擬,所以它隨便選了兩個IO接上就行。
VREF是什么?基準電壓,也是它能測量的最大電壓。
如何控制?今天先不說IIC總線,只說控制流程。
看器件手冊可以知道:
分四步:
1、發送地址字節,選擇該器件。
2、發送控制字節,選擇相應通道。 //
3、重新發送地址字節,選擇該器件。
4、接收目標通道的數據。
這次的程序流程是:AD采樣,串口發送,循環執行。
下面是AD采樣源代碼:
本程序下載鏈接(附帶
PCF8591中文資料pdf資料):
PCF8591AD采樣.rar
(459.16 KB, 下載次數: 948)
2015-4-8 22:46 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
-------------------------------------------------------------------------------------
下面介紹PCF8591的DA輸出:
忽然發現,已經寫到AD/DA這里來了。嚴格來說,已經不是51單片機的內容了,而是周邊應用電路的一些東西。這些東西涉及的知識面比較廣,什么都有可能提到。
關于AD/DA,或者其它設備,我的學習思路是先模仿,再深究。
因為無論是課本也好,器件手冊也好,大部分講的都是原理或者寄存器,起到的是一個工具書的作用,類似于語文課上用的字典。但是這就出現了一個問題,很多人想通過看課本或者看器件手冊的方式來掌握這些設備。
這個思路有問題嗎?沒有問題嗎?
還記得我剛才說的話么,它們就類似于語文課上用的字典,但是,有誰是通過看字典學會說話的!!!
我們都是通過模仿別人學會說話的,遇到不認識的字才去查字典!但是很多人或者很多學校都把這兩件事的順序搞反了。
記得之前我在英飛凌官網進行芯片選型,網頁都翻爛了,找不到合適的。因為英飛凌不是我家開的,我不能保證每次都能順利的找到我想要的東西。
但是,我同事參加了一次電子展,在展會上遇到了英飛凌的展臺,然后問他們,他們一聽我們的需求,馬上找出一堆能滿足我們要求的芯片。
這就是思路的問題!
扯遠了,說回到DA控制。
DA轉換(Digital to Analog),是將數字量變成模擬量的一個過程。AD與DA剛好是相反的兩個過程,AD是把模擬信號變成單片機可識別的數字信號;DA是把單片機可識別的數字信號變成連續變化的模擬量。這兩種功能的應用范圍都非常廣泛!
主要參數如下,具體什么意思就不講了,大家可以百度一下。(因為我編不出來了...)
1)分辯率(Resolution)
2) 轉換速率(Conversion Rate)
3)量化誤差 (Quantizing Error)
4)偏移誤差(Offset Error)
5)滿刻度誤差(Full Scale Error)
6)線性度(Linearity)
其他指標還有:絕對精度(Absolute Accuracy) ,相對精度(Relative Accuracy),微分非線性,單調性和無錯碼,總諧波失真(Total Harmonic Distotortion縮寫THD)和積分非線性。
看到這么多參數,是不是很暈?
搞了這些年電子,感觸最深的有一點是:無論做什么,先求有,再求好!
不要總想一口吃個胖子,沒那么多天才。參數是很多,但是沒要求你一下子全都記住,甚至你可以只記一兩個。先把大致的應用流程跑一遍,跑下來,你才對這個設備有一個整體的概念,然后針對你的要求,比對相應的參數,進行修改、調試。
哪怕是在工作中,也不一定會考慮全部的參數。例如轉換時間,我到現在也沒認真看PIC內部的AD采樣轉換時間有多久,因為有些設備對實時性要求很低,速度慢一些也沒事。
然后是控制流程,認真看器件手冊的,或者看了昨天日志的,都知道是怎樣一個流程:
第一步:寫器件地址;
第二步:寫控制位。
第三步:寫入數據。
好了,上程序。通過DA輸出漸變電壓控制LED,形成呼吸燈的效果。里面有個警告:
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
大家可以研究下,如何消除警告。
程序源碼如下:
- /**********************51單片機學習例程************************
- * 平臺: Keil U34 + STC89C52RD
- * 名稱:IIC協議 PCF8591ADDA轉換 ,此程序通過IIC協議對DAAD芯片操作, 并輸出模擬量,用LED亮度漸變指示
- * 編寫:起航
- * 晶振:11.0592MHZ
- ******************************************************************/
- #include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
- #include <intrins.h> //包含NOP空指令函數_nop_();
- #define AddWr 0x90 //寫數據地址
- #define AddRd 0x91 //讀數據地址
- sbit RST=P2^4; //關掉時鐘芯片輸出
- sbit Sda=P2^0; //定義總線連接端口
- sbit Scl=P2^1;
- sbit Fm=P2^3; //FM
- sbit dula=P2^6;
- sbit wela=P2^7;
- // bit ADFlag; //定義AD采樣標志位
- unsigned char code Datatab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//7段數共陰碼管段碼表
- data unsigned char Display[8];//定義臨時存放數碼管數值
- /*------------------------------------------------
- 延時程序
- ------------------------------------------------*/
- void mDelay(unsigned char j)
- {
- unsigned int i;
- for(;j>0;j--)
- {
- for(i=0;i<125;i++)
- {;}
- }
- }
- /*------------------------------------------------
- 初始化定時器1
- ------------------------------------------------*/
- void Init_Timer1(void)
- {
- TMOD |= 0x10;
- TH1=0xff; /* Init value */
- TL1=0x00;
- //PT1=1; /* 優先級 */
- EA=1; /* interupt enable */
- ET1=1; /* enable timer1 interrupt */
- TR1=1;
- }
- /*------------------------------------------------
- 啟動IIC總線
- ------------------------------------------------*/
- void Start(void)
- {
- Sda=1;
- _nop_();
- Scl=1;
- _nop_();
- Sda=0;
- _nop_();
- Scl=0;
- }
- /*------------------------------------------------
- 停止IIC總線
- ------------------------------------------------*/
- void Stop(void)
- {
- Sda=0;
- _nop_();
- Scl=1;
- _nop_();
- Sda=1;
- _nop_();
- Scl=0;
- }
- /*------------------------------------------------
- 應答IIC總線
- ------------------------------------------------*/
- void Ack(void)
- {
- Sda=0;
- _nop_();
- Scl=1;
- _nop_();
- Scl=0;
- _nop_();
- }
- /*------------------------------------------------
- 發送一個字節
- ------------------------------------------------*/
- void Send(unsigned char Data)
- {
- unsigned char BitCounter=8;
- unsigned char temp;
- do
- {
- temp=Data;
- Scl=0;
- _nop_();
- if((temp&0x80)==0x80)
- Sda=1;
- else
- Sda=0;
- Scl=1;
- temp=Data<<1;
- Data=temp;
- BitCounter--;
- }
- while(BitCounter);
- Scl=0;
- }
- /*------------------------------------------------
- 寫入DA數模轉換值
- ------------------------------------------------*/
- void DAC(unsigned char Data)
- {
- Start();
- Send(AddWr); //寫入芯片地址
- Ack();
- Send(0x40); //寫入控制位,使能DAC輸出
- Ack();
- Send(Data); //寫數據
- Ack();
- Stop();
-
- }
- void fmg(void)//fm關
- {
- Fm=1; // 關 fm
- }
- void cmg(void)//數碼管鎖存函數 關時鐘DS1302
- {
- dula=1;
- P0=0x00;
- dula=0;
- wela=1;
- P0=0x00;
- wela=0;
- RST=0; // 關時鐘DS1302
- }
- /*------------------------------------------------
- 主程序
- ------------------------------------------------*/
- void main()
- {
- unsigned char num; //DA數模輸出變量
- Init_Timer1();
- cmg();//數碼管鎖存
- fmg();
- while(1)
- {
- DAC(num); //DA輸出,可以用LED模擬電壓變化
- num++; //累加,到256后溢出變為0,往復循環。顯示在LED上亮度逐漸變化
- mDelay(20); //延時用于清晰看出變化
- }
- }
復制代碼下載鏈接:
PCF8591DAC_LED.zip
(29.03 KB, 下載次數: 409)
2015-4-8 22:46 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者: 槑呆呆 時間: 2015-5-28 18:23
請問樓主,PCF8591適合做心電信號的AD采樣嗎?求指導啊
作者: hahaha123 時間: 2015-6-27 19:37
看了一下,剛學哎
作者: leafye 時間: 2015-7-21 16:47
正在學習AD/DA!謝謝
作者: 764200352 時間: 2015-7-26 11:15
不錯,正在學ad/da
作者: 喜歡句號 時間: 2015-8-8 11:18
很好很強大
作者: mr.coco 時間: 2015-8-12 17:43
//unsigned char code Datatab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//data unsigned char Display[8];
警告應該是因為這兩句是多余的
作者: wzc1339 時間: 2015-10-6 16:04
樓主,我是小白。收獲好多,謝謝
作者: badpeter 時間: 2015-11-19 11:13
很好的東西~謝謝樓主
作者: badpeter 時間: 2015-11-19 11:14
很好的東西,謝謝樓主
作者: 火云邪神 時間: 2015-11-27 11:35
請問“發送一個字節”這一段程序是干啥用的,為啥要用著個程序呢,謝謝我是小白
作者: zdluffy 時間: 2015-11-28 15:52
很好的東西~謝謝樓主
作者: 駒哥來記得喊我i 時間: 2015-12-1 19:31
剛開始學數模轉換,謝謝樓主啦。
作者: mcs51hello 時間: 2015-12-3 10:47
深度好貼,謝謝樓主了。
作者: 你的溫柔給了誰 時間: 2015-12-21 10:50
很好的文章,剛好要用……
作者: kanganhui 時間: 2016-1-11 10:51
樓主東西很好,對我幫助很大
作者: li3781695 時間: 2016-1-18 23:35
學習了,學習了,感謝樓主
作者: tongwuting 時間: 2016-2-23 11:13

樓主,這兩個圈里的器件指的應該是同一個器件吧?那為什么第152行代碼中器件地址是SLAVEADDR,而第159行代碼中器件地址是SLAVEADDR+1?為什么要加1呢?
作者: tongwuting 時間: 2016-2-24 08:39
我突然明白了,152行的SLAVEADDR是要寫,159行的SLAVEADDR+1是要讀,所以要加1
作者: yyzzm 時間: 2016-5-10 16:27
學習了,謝謝!
作者: 模霸世界 時間: 2016-5-13 11:56
DA輸出之前沒怎么了解 今天惡補 謝謝
作者: aether17 時間: 2016-5-21 09:52
謝謝分享!!
作者: bismarck 時間: 2016-5-26 14:33
很好,十分有用。感謝分享。
作者: sunny360day 時間: 2016-5-30 10:45
請問,你們有遇到DA輸出的時候電壓不夠的情況嗎?測到VCC有5.19V,但是輸出最大只能到4.42V,
作者: 逆風天使 時間: 2016-6-15 18:09
請問轉換周期怎么計算,或者說具體采樣頻率怎么計算
作者: zhangdoudou 時間: 2016-6-21 15:41
PCF8591和PCF8591T有什么區別嗎?是不是管腳不同?
作者: yd665c 時間: 2016-10-3 11:57
樓主威武 樓主萬歲萬歲萬萬歲
作者: 梁偉波 時間: 2016-11-5 23:58
終于在這找到了,正需要
作者: 米99不好 時間: 2016-11-9 20:30
漲姿勢
作者: 米99不好 時間: 2016-11-9 20:31
加油啊
作者: 這么近、那么遠 時間: 2016-11-17 17:25
貌似很不錯
作者: select326 時間: 2016-12-17 21:40
感謝分享
作者: 緣分注定生死 時間: 2017-3-27 15:50
沒有黑幣啊,好苦惱。。。。。。。
作者: ttttyx2 時間: 2017-4-19 22:15
w2 w3是什么東西??
作者: qxw199586 時間: 2017-4-22 13:26
很給力!!
作者: zhao416129 時間: 2017-5-7 09:52
謝謝樓主,畢設正好需要這個器件
作者: zhao416129 時間: 2017-5-12 10:59
謝謝樓主,!!!
作者: 小51hei56565 時間: 2017-8-22 11:06
請問,我沒加上拉電阻,數值一直在跳,等我加上上拉電阻,求平均值后 數據會穩定下來嗎
作者: haveme 時間: 2018-2-7 09:45
厲害啊,好東西
作者: emily929627260 時間: 2018-4-23 10:00
還沒看見 不知道是不是深度好文,現在正在登陸
作者: 284213945 時間: 2018-5-10 20:51
學習了,學習了,感謝樓主
作者: 111199 時間: 2018-6-4 23:16
學習中666
作者: ~Roll~、 時間: 2018-7-9 17:01
學到了很多,謝謝樓主
作者: 青寧 時間: 2018-8-30 19:14
謝樓主分享,論壇有你更精彩
作者: liven丶 時間: 2018-11-20 20:44
雖然帖子很好,不過少了電路圖沒法對應學,共享的資料也有程序而已
作者: 時光倒影 時間: 2018-12-12 19:43
謝謝分享
作者: zhouwei0815 時間: 2018-12-13 11:47
很好的資料 正好在研究逐日系統 可以用到這個
作者: liu631208 時間: 2019-1-18 19:41
很好很強,初入門有點看不懂
作者: 277563114 時間: 2019-2-20 14:55
請問樓主ad程序里面的ans定義了之后值是怎么取的呢
我好像沒有看到有哪里給ans賦了值
作者: 13306446378 時間: 2019-4-8 20:39
幫助很大
作者: rebios 時間: 2019-8-23 17:45
T1定時器打開了,在程序中是做什么用的
作者: 003 時間: 2020-6-7 14:30
樓主,你好,ad差分輸入的轉換結果跟單端輸入的轉換結果是一樣的嗎
作者: vscos 時間: 2022-1-11 19:17
那是這個IIC地址的0位是代表讀寫的位,0時是只讀,1時可以寫入
作者: Listentoyou 時間: 2022-3-1 10:24
樓主,FPC8591的DA轉換就往里寫0-255數據就可以了嗎,因為我看另外一個ISP協議的xpt2046居然是用單片機時鐘芯片產生pwm來DA的,有點復雜,pcf8591好多都是和你這個類似的,我把矩陣按鍵輸入的電壓值(0-5.0v)轉換成0-255,好像Proteus 8 Professional仿真出來有點問題
部分代碼:
DA_8=DA_buf[1]*51+DA_buf[3]*5; //轉換輸出的電壓,
PCF8591_DAC(0x43,DA_8); //DA轉換
作者: hefqeury 時間: 2023-12-1 16:37
pcf8591在Altium中怎么找,在哪個庫
歡迎光臨 (http://m.zg4o1577.cn/bbs/) |
Powered by Discuz! X3.1 |
主站蜘蛛池模板:
伊人伊人网
|
中文字幕在线观看
|
国产精品毛片一区二区在线看
|
国产伦精品一区二区三区四区视频
|
久久在线精品
|
国产精品一二三区
|
久久久久精
|
亚洲精品乱码久久久久久按摩
|
亚洲日本国产
|
一区在线观看
|
国产精品不卡
|
国产久|
久久久蜜桃一区二区人
|
毛片黄片免费看
|
免费在线看黄
|
男女激情网站免费
|
国产在线不卡
|
亚洲品质自拍视频网站
|
亚洲精品成人在线
|
国产在线小视频
|
黑人巨大精品欧美黑白配亚洲
|
日韩精品免费看
|
a免费观看
|
久草精品在线
|
天天爱综合
|
天天av网
|
欧美视频免费在线
|
久久久久久国产精品
|
91av视频|
97精品超碰一区二区三区
|
欧美精品综合在线
|
欧美 日韩 国产 在线
|
精品伊人
|
亚洲男女激情
|
成人精品一区二区
|
亚洲精品国产第一综合99久久
|
毛片软件
|
国产美女在线观看
|
精品欧美一区二区三区免费观看
|
欧美一区二区三区久久精品
|
精品国产黄a∨片高清在线
成人区精品一区二区婷婷
日本一区二区视频
|