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