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