专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

STC12C5A60S2中的AD转换

作者:池塘里的鲨鱼   来源:会员整理上传   点击数:  更新时间:2014年05月22日   【字体:

逐次逼近原理 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相当于一个常数,不是寄存器里面的某个位
    //while(!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; 即可
                                    //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会出现错误,具体原因还不清楚
 
 
先说到这吧
关闭窗口

相关文章