逐次逼近原理 AD里面包含da,當(dāng)輸入電壓Vin時(shí),da的最高位是1,即為0.5Vref與輸入信號(hào)比較,如果輸入大于0.5Vref則比較器輸出為1,同時(shí)da的最高位為1,反之DA最高位則為0,通過(guò)8次比較后得到8個(gè)01數(shù)據(jù)即完成ad轉(zhuǎn)換。
現(xiàn)在說(shuō)下程序中用到stc12單片機(jī)兩個(gè)寄存器 ADC_CONTR;主要用來(lái)配置ad啟動(dòng)的工作模式;還有個(gè)result的寄存器
程序中的注意點(diǎn):配置完ADC_CONTR后要延時(shí)4個(gè)時(shí)鐘周期
先把程序附上
#include "stc12.h"
#include "intrins.h"
#include "ad.h"
uint ad;
#define ADC_POWER 0X80 //ADC最高位給adc部分供電,類似于片選
#define ADC_START 0X08 //模數(shù)轉(zhuǎn)換啟動(dòng)控制位
#define ADC_FLAG 0x10 //ad轉(zhuǎn)換需要時(shí)間,這個(gè)是轉(zhuǎn)換完成標(biāo)志位
#define ADC_SPEEDLL 0X00 //540 clock
#define ADC_SPEEDL 0X20 //360 clock
#define ADC_SPEEDH 0X40 //180 clock
#define ADC_SPEEDHH 0X60 //90 clock
uchar ADCresult(uchar aa) //這里的參數(shù)是哪個(gè)口來(lái)ad轉(zhuǎn)換
{
P1ASF=0X01; //這里的選擇和用哪一個(gè)P1口作為ad采樣
ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ADC_START|aa;
//ADC_CONTR=0X88|aa;
_nop_();
_nop_();
_nop_();
_nop_();//設(shè)置ADC_CONTR寄存器后需加4個(gè)CPU時(shí)鐘周期的延時(shí),才能保證值被寫(xiě)入ADC_CONTR寄存器
while (!(ADC_CONTR & ADC_FLAG)); //等待ADC_CONTR,這里的ADC_FLAG相當(dāng)于一個(gè)常數(shù),不是寄存器里面的某個(gè)位
//ADC_FLAG=0;
ADC_CONTR &= ~ADC_FLAG; //Close ADC 將標(biāo)志位清零等待下次硬件置1
ad=(ADC_RES<<2)+ADC_RESL; //打開(kāi)10位AD采集功能 如果用8位AD 屏掉這句 把下一句改為 Vo=(float)(ADC_RESL)*500/256; 即可
//那么用采集到的數(shù)量值 除以1024 在乘以5 得到的值就是采集的電壓數(shù)值
//這里 又*100 是為了擴(kuò)大100倍 顯示小數(shù)位
}
這里只是個(gè)ad.c源文件,這里有幾個(gè)問(wèn)題想說(shuō)一下
1.怎么知道是10位還是8位的ad結(jié)果;你可以在ADCresult(uchar aa)最前面加一條AUXR1&=0x04;什么意思呢,轉(zhuǎn)換結(jié)果的低2位放在ADC_RES,高8位ADC_RESL中
2為什么不用//while(!ADC_FLAG);
//ADC_FLAG=0;這兩條因?yàn)锳DC_FLAG相當(dāng)于常量前面用宏定義
而頭文件里只有ADC_CONTR的地址映射;但是如果在頭文件中用sbit ADC_FLAG=ADC_CONTR^4會(huì)出現(xiàn)錯(cuò)誤,具體原因還不清楚
先說(shuō)到這吧