逐次逼近原理 AD里面包含da,当输入电压Vin时,da的最高位是1,即为0.5Vref与输入信号比较,如果输入大于0.5Vref则比较器输出为1,同时da的最高位为1,反之DA最高位则为0,通过8次比较后得到8个01数据即完成ad转换。
现在说下程序中用到stc12单片机两个寄存器 A
_CO
R;主要用来配置ad启动的工作模式;还有个result的寄存器 程序中的注意点:配置完ADC_C
TR后要延时4个时钟周期 先把程序附上 #include "stc12.h" #include "intrins.h" #include "ad.h" uint ad; #define ADC_POWER 0X80
//ADC最高位给adc部分供电,类似于片选 #define ADC_
ART 0X08
//模数转换启动控制位 #define ADC_FLAG
0x10
//ad转换需要时间,这个是转换完成标志位 #define ADC_
EEDLL 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个
时钟周期的延时,才能保证值被写入ADC_CONTR寄存器 while (!(ADC_CONTR & ADC_FLAG));
//等待ADC_CONTR,这里的ADC_FLAG相当于一个常数,不是寄存器里面的某个位
//while(!ADC_FLAG); //ADC_FLAG=0; ADC_CONTR &= ~ADC_FLAG;
//Close ADC 将标志位清零等待下次硬件置1 ad=(ADC_RES<<2)+ADC_RE
; //打开10位AD采集功能
如果用8位AD 屏掉这句 把下一句改为
Vo=(float)(ADC_RESL)*500/256; 即可
//ADC_RES结果寄存器的高2位;ADC_RES结果寄存器的低8位
ad=(float)(ad)*5*100/1024;
//Return ADC result(为显示整数,这里将电压值扩大了十倍)
//10位AD采集 即2的10次方 满值为1024 这里用1024表示5伏的电压
//那么用采集到的数量值 除以1024 在乘以5 得到的值就是采集的电压数值 //这里 又*100 是为了扩大100倍 显示小数位
//ADC_RES*(5/256) 为采集的电压值
然后扩大10倍便于计算
return ad;
} 这里只是个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会出现错误,具体原因还不清楚 先说到这吧
-电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。
自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。