C8051F320內(nèi)部有一個(gè)10位逐次逼近型ADC,可以工作在單端方式或者差分方式。
一、簡(jiǎn)要原理
單片機(jī)內(nèi)集成了2個(gè)多路選擇器,分別作為ADC的正輸入信號(hào)和負(fù)輸入。
正輸入端由寄存器AMX0P控制輸入信號(hào),可以是P1~P3、溫度傳感器、VDD之一;
負(fù)輸入端由寄存器AMX0N控制輸入信號(hào),可以是P1~P3、VREF、GND之一。
單負(fù)輸入端選擇GND時(shí),采用單端方式;其他情況則采用差分方式,即用正端相對(duì)于負(fù)端的電壓進(jìn)行轉(zhuǎn)換。
*采用并行口作為輸入信號(hào)時(shí),必須將對(duì)應(yīng)輸入引腳設(shè)為模擬輸入,并且對(duì)應(yīng)的SKIP要設(shè)置為1,即跳過(guò)
二、寄存器
1、轉(zhuǎn)換結(jié)果保存在兩個(gè)8位寄存器ADC0H和ADC0L中,由于轉(zhuǎn)換結(jié)果是10位,可以自由選擇在寄存器中采用左對(duì)齊或者右對(duì)齊(下詳)
單端方式下,轉(zhuǎn)換結(jié)果直接保存為10位的無(wú)符號(hào)數(shù)
差分方式下,結(jié)果保存為10位有符號(hào)整數(shù)(原說(shuō)明:2的補(bǔ)碼。未深究)
2、溫度傳感器的輸出電壓由下面公式?jīng)Q定:
V = 2.86(T)+ 776 (單位mv) 從圖表看,最高只能在1000mv左右,也就是100°時(shí)僅1V上下
3、AD啟動(dòng)方式
有六種啟動(dòng)方式,包括四個(gè)定時(shí)器溢出啟動(dòng)、特定位置1啟動(dòng)和P0.6上升沿啟動(dòng)。(下詳)
采用中斷時(shí),中斷號(hào)interrupt 10
4、跟蹤方式 對(duì)跟蹤不是很理解!
5、寄存器AMX0P,正輸入通道選擇寄存器
00H~10H,對(duì)應(yīng)P1.0~P3.0 0x1E對(duì)應(yīng)溫度傳感器 0x1F對(duì)應(yīng)VDD
寄存器XMXON,負(fù)輸入通道選擇寄存器
00H~10H,對(duì)應(yīng)P1.0~P3.0 0x1E對(duì)應(yīng)VREF 0x1F對(duì)應(yīng)GND,此時(shí)為單端方式
6、寄存器ADC0CF,配置寄存器,控制轉(zhuǎn)換時(shí)鐘,和數(shù)據(jù)保存方向
D7~D3 時(shí)鐘控制位,大意就是分頻數(shù),系統(tǒng)時(shí)鐘與AD時(shí)鐘的比值減1
D2,為0時(shí)數(shù)據(jù)右對(duì)齊,為1時(shí)左對(duì)齊
7、寄存器ADC0CN,控制寄存器。
D7,AD使能,0時(shí)禁止轉(zhuǎn)換
D6,跟蹤方式,不懂
D5,中斷標(biāo)志位,要手動(dòng)清0
D4,讀取時(shí)為忙標(biāo)志位,寫(xiě)入時(shí)可為啟動(dòng)標(biāo)志位,但不知道要不要清0
D3,窗口比較中斷標(biāo)志,不是很清楚
D2~D0 轉(zhuǎn)換方式選擇,且受到D6影響。具體未深究。
8、寄存器REF0CN,電壓基準(zhǔn)控制器
與AD的關(guān)系不完全明朗
D3 決定了電壓基準(zhǔn) D2 使能溫度傳感器
下面是完整例程,但不包含12864的C文件。
完整例程下載地址:http://www.zg4o1577.cn/f/c8051sad.rar
#include "c8051f3xx.h"
#include "12864.h"
完整例程下載地址:http://www.zg4o1577.cn/f/c8051sad.rar
#include "c8051f3xx.h"
#include "12864.h"
#define uchar unsigned char
#define uint unsigned int
#define uint unsigned int
sfr16 TMR2RL = 0xca; // Timer2 reload value定時(shí)器2重載值
sfr16 TMR2 = 0xcc; // Timer2 counter定時(shí)器2計(jì)數(shù)器
sfr16 TMR2 = 0xcc; // Timer2 counter定時(shí)器2計(jì)數(shù)器
//這兩行相當(dāng)好用,直接把T2的四個(gè)8位寄存器重新定義成2個(gè)16位寄存器!!!!!!
uchar adnum3,adnum2,adnum1; //打算用來(lái)顯示的數(shù)百位、十位和個(gè)位,在這里沒(méi)有進(jìn)行運(yùn)算,只是直接的AD結(jié)果 sbit led0=P0^5; //連了個(gè)發(fā)光二極管觀察有沒(méi)有死機(jī)。。 uchar code table[]="0123456789"; //顯示數(shù)據(jù)用 uchar code hang1[17]="1234567"; //以下四行為12864初始顯示的內(nèi)容,不重要 uchar code hang2[17]="123456789 "; uchar code hang3[17]="2011-7-10 星期日"; uchar code hang4[17]=" 00:00:00 "; void Timer2_ISR (void) interrupt 5 // T2只是用來(lái)溢出的,沒(méi)程序,清標(biāo)志位而已 { TF2H = 0; } void Adc_ConvComplete_ISR (void) interrupt 10 //AD中斷程序,除了清標(biāo)志位,只是把數(shù)據(jù)送到12864第三行 { AD0INT = 0; lcd_pos(3,0); adnum3 = ADC0H/100; adnum2 = (ADC0H%100)/10; adnum1 = (ADC0H%100)%10; disp_only(tableaa[adnum3]); disp_only(tableaa[adnum2]); disp_only(tableaa[adnum1]); } void Port_Init (void) //端口初始化,哪個(gè)位要輸入,就要設(shè)為模擬,并跳過(guò) { P1MDIN = 0x7F; P0MDIN = 0xff; P2MDIN = 0xff; P3MDIN = 0x00; P0MDOUT |= 0xfF; P1MDOUT |= 0x0F; P2MDOUT |= 0x0C; P1SKIP = 0x80; P0SKIP = 0x00; P2SKIP = 0x00; XBR0 = 0x00; XBR1 = 0x40; } void Timer_Init (void) { TMR2CN = 0x00; CKCON &= ~0xF0; TMR2RL = 0; TMR2 = 0xffff; ET2 = 1; TR2 = 1; } void ADC0_Init (void) { REF0CN = 0x0E; // VDD作為基準(zhǔn)電壓,啟用內(nèi)部溫度傳感器 AMX0P = 0x10; // 10是P3.0,試過(guò)07(1.7)和1E(溫度),都沒(méi)問(wèn)題 ADC0CF = 0xFC; // 11111,32分頻? (*表示分頻數(shù)-1=31) D2為1,左對(duì)齊 AMX0N = 0x1F; // 單端方式 ADC0CN = 0xC2; // T2溢出作為啟動(dòng)信號(hào) EIE1 |= 0x08; // 開(kāi)中斷 } void System_Init (void) { PCA0MD &= ~0x40; OSCICN |= 0x03; Port_Init (); Timer_Init (); ADC0_Init (); } void DelayMS(uint x) { uchar i; while(x--) { for(i=120;i>0;i--); } } void main(void) { System_Init (); lcd_init(); clr_screen(); DelayMS(100); lcd_pos(0,0); disp_chinese(hang1); lcd_pos(1,0); disp_chinese(hang2); lcd_pos(2,0); disp_chinese(hang3); lcd_pos(3,0); disp_chinese(hang4); EA = 1; while (1) { led0=~led0; DelayMS(5500); } }
測(cè)試結(jié)果:
1、用開(kāi)發(fā)板上的電位器,可以讓高位結(jié)果在0~255之間變化
2、用溫度傳感器,室溫下顯示高位為65,*近筆記本風(fēng)扇數(shù)秒后變成66,說(shuō)明溫度有變化,因?yàn)槭歉呶唬幻黠@,也沒(méi)計(jì)算。
3、用全新的南孚電池一節(jié),顯示穩(wěn)定的121。
____________________________________________________________________________
一、修改程序,將10位數(shù)字量轉(zhuǎn)換成0~1023顯示在屏幕上
*用變位器,可以實(shí)現(xiàn)1~1023的變化,1和0之間無(wú)法穩(wěn)定,直接接地也無(wú)法顯示0
*用一節(jié)全新電池,顯示485,VDD為3V,偏差不大。
二、再修改程序,將正輸入設(shè)為溫度傳感器
*顯示263,稍微加熱后變成265,仍然覺(jué)得不夠明顯
*263對(duì)應(yīng)電壓約770mv,根據(jù)公式換算溫度是負(fù)數(shù)。。。。
在筆記本散熱口放了一會(huì)升到268,還是低!