AD模块.docx
《AD模块.docx》由会员分享,可在线阅读,更多相关《AD模块.docx(13页珍藏版)》请在冰豆网上搜索。
AD模块
模-数转换原理
ADC的转换原理根据ADC的电路形式有所不同。
ADC电路通常由两部分组成,它们是:
采样、保持电路和量化、编码电路。
其中量化、编码电路是最核心的部件,任何ADC转换电路都必须包含这种电路。
ADC电路的形式很多,通常可以并为两类:
间接法:
它是将采样-保持的模拟信号先转换成与模拟量成正比的时间或频率,然后再把它转换为数字量。
这种通常是采用时钟脉冲计数器,它又被称为计数器式。
它的工作特点是:
工作速度低,转换精度高,抗干扰能力强。
直接法:
通过基准电压与采样-保持信号进行比较,从而转换为数字量。
它的工作特点是:
工作速度高,转换精度容易保证。
模—数转换的过程有四个阶段,即采样、保持、量化和编码。
采样是将连续时间信号变成离散时间信号的过程。
经过采样,时间连续、数值连续的模拟信号就变成了时间离散、数值连续的信号,称为采样信号。
采样电路相当于一个模拟开关,模拟开关周期性地工作。
理论上,每个周期内,模拟开关的闭合时间趋近于0。
在模拟开关闭合的时刻(采样时刻),我们就“采”到模拟信号的一个“样本”。
量化是将连续数值信号变成离散数值信号的过程。
理论上,经过量化,我们就可以将时间离散、数值连续的采样信号变成时间离散、数值离散的数字信号。
我们知道,在电路中,数字量通常用二进制代码表示。
因此,量化电路的后面有一个编码电路,将数字信号的数值转换成二进制代码。
然而,量化和编码总是需要一定时间才能完成,所以,量化电路的前面还要有一个保持电路。
保持是将时间离散、数值连续的信号变成时间连续、数值离散信号的过程。
在量化和编码期间,保持电路相当于一个恒压源,它将采样时刻的信号电压“保持”在量化器的输入端。
虽然逻辑上保持器是一个独立的单元,但是,工程上保持器总是与采样器做在一起。
两者合称采样保持器。
八位串行A/D转换器ADC0832简介
ADC0832是美国国家半导体公司生产的一种8位分辨率、双通道A/D转换芯片。
由于它体积小,兼容性强,性价比高而深受单片机爱好者及企业欢迎,其目前已经有很高的普及率。
ADC083X是市面上常见的串行模—数转换器件系列。
ADC0831、ADC0832、ADC0834、ADC0838是具有多路转换开关的8位串行I/O模—数转换器,转换速度较高(转换时间32uS),单电源供电,功耗低(15mW),适用于各种便携式智能仪表。
本章以ADC0832为例,介绍其使用方法。
ADC0832是8脚双列直插式双通道A/D转换器,能分别对两路模拟信号实现模—数转换,可以用在单端输入方式和差分方式下工作。
ADC0832采用串行通信方式,通过DI数据输入端进行通道选择、数据采集及数据传送。
8位的分辨率(最高分辨可达256级),可以适应一般的模拟量转换要求。
其内部电源输入与参考电压的复用,使得芯片的模拟电压输入在0~5V之间。
具有双数据输出可作为数据校验,以减少数据误差,转换速度快且稳定性能强。
独立的芯片使能输入,使多器件挂接和处理器控制变的更加方便。
ADC0832具有以下特点:
·8位分辨率;
·双通道A/D转换;
·输入输出电平与TTL/CMOS相兼容;
·5V电源供电时输入电压在0~5V之间;
·工作频率为250KHZ,转换时间为32μS;
·一般功耗仅为15mW;
·8P、14P—DIP(双列直插)、PICC多种封装;
·商用级芯片温宽为0°Cto+70°C,工业级芯片温宽为-40°Cto+85°C;
图3ADC0832引脚图
芯片接口说明:
·CS_片选使能,低电平芯片使能。
·CH0模拟输入通道0,或作为IN+/-使用。
·CH1模拟输入通道1,或作为IN+/-使用。
·GND芯片参考零电位(地)。
·DI数据信号输入,选择通道控制。
·DO数据信号输出,转换数据输出。
·CLK芯片时钟输入。
·Vcc/REF电源输入及参考电压输入(复用)
ADC0832的工作原理:
正常情况下ADC0832与单片机的接口应为4条数据线,分别是CS、CLK、DO、DI。
但由于DO端与DI端在通信时并未同时使用并与单片机的接口是双向的,所以在I/O口资源紧张时可以将DO和DI并联在一根数据线上使用。
当ADC0832未工作时其CS输入端应为高电平,此时芯片禁用,CLK和DO/DI的电平可任意。
当要进行A/D转换时,须先将CS使能端置于低电平并且保持低电平直到转换完全结束。
此时芯片开始转换工作,同时由处理器向芯片时钟(CLK)输入端输入时钟脉冲,DO/DI端则使用DI端输入通道功能选择的数据信号。
在第一个时钟脉冲的下沉之前DI端必须是高电平,表示启始信号。
在第二、三个脉冲下沉之前DI端应输入两位数据用于选择通道功能。
通道地址
通道
工作方式说明
SGL/DIF
ODD/SIGN
0
1
0
0
+
-
差分方式
0
1
-
+
1
0
+
单端输入方式
1
1
+
表1:
通道地址设置表
如表1所示,当此两位数据为“1”、“0”时,只对CH0进行单通道转换。
当2位数据为“1”、“1”时,只对CH1进行单通道转换。
当两位数据为“0”、“0”时,将CH0作为正输入端IN+,CH1作为负输入端IN-进行输入。
当两位数据为“0”、“1”时,将CH0作为负输入端IN-,CH1作为正输入端IN+进行输入。
到第三个脉冲的下降之后DI端的输入电平就失去输入作用,此后DO/DI端则开始利用数据输出DO进行转换数据的读取。
从第4个脉冲下降沿开始由DO端输出转换数据最高位Data7,随后每一个脉冲的下降沿DO端输出下一位数据。
直到第11个脉冲时发出最低位数据Data0,一个字节的数据输出完成。
也正是从此位开始输出下一个相反字节的数据,即从第11个字节的下降沿输出Data0。
随后输出8位数据,到第19个脉冲时数据输出完成,也标志着一次A/D转换的结束。
最后将CS置高电平禁用芯片,直接将转换后的数据进行处理就可以了。
时序说明请参照图4。
作为单通道模拟信号输入时ADC0832的输入电压是0—5V且8位分辨率时的电压精度为19.53mV,即(5/256)V。
如果作为由IN+与IN-输入的输入时,可是将电压值设定在某一个较大范围之内,从而提高转换的宽度。
但值得注意的是,在进行IN+与IN-的输入时,如果IN-的电压大于IN+的电压则转换后的数据结果始终为00H。
ADC0832的工作时序
图4ADC0832工作时序
ADC0832软硬件设计实例
通过以上的理论学习之后,对模—数转换应该有了一定的了解,接下来就根据上文的指导,对ADC0832进行实际应用,以加深印象。
本实例功能是将通道1上采样到的电压显示在LED数码管上,通过改变通道1的输入电压变化,观察输出读数。
硬件原理图
图7硬件原理图
程序流程图
图8软件流程图
相信看到这里,你应该可以理解我们是如何利用单片机来进行模数转换的处理了,你也可以根据自己的需要来写些AD模数转换相关的应用程序,如数字温度计,湿度传感应用,压力传感应用等等。
由于篇幅有限,读者朋友可以通过网站或电子邮件一起交流与学习。
在下几期中,我们将陆续介绍51单片机综合学习系统的其它功能原理与应用。
STC单片机的相关程序如下:
#include//定义的系统头文件和全局变量
#include
#defineucharunsignedchar
#defineuintunsignedint
#defineDogReset()WDT_CONTR=0x35
//T1定时0.1ms.作为系统计时用,
#definevT01ms2
#definevT10ms10
#definevT100ms10
#definevT01S100//1s=10ms*100
#definevT0HVal0xfe//0xff//0xfe//0xf6
#definevT0LVal0x33//0x9c//0x0c//0x4c
ucharcodedisplay_AD_channel_ID[2]={0x00,0x01};
staticunsignedchardataCS;
uchardataAD_channel_result[2][5];//各通道A/D转换结果。
前是通道号;后是转换的值
uintcT01ms;
ucharcT10ms;
ucharcT100ms;
ucharcT01s;
ucharTHTL;
bitOutFlag;
voiddelay_ms(registeruintCount){
registerucharT;
for(;Count>0;Count--){
for(T=0;T<80;T++){
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
DogReset();
}
}
voidsend_char_com(unsignedcharOutData){
SBUF=OutData;//输出字符
while(!
TI);//空语句判断字符是否发完
TI=0;//清TI
}
voidsend_string_com(uchar*str,ucharstrlen){
uchari;
for(i=strlen;i>0;i--){
send_char_com(*str);
str++;
DogReset();
}
}
ucharAd_Change(ucharchannel){
uintAD_Result_Temp=0;
//---------------------将P1.0--P1.1设置成适合AD转换的模式
///P1=0xff;//将P1口置高,为A/D转换作准备
ADC_CONTR=ADC_CONTR|0x80;//1000,0000打开A/D转换电源
P1M0=0x03;//0000,0011用于A/D转换的P1.x口,先设为开漏
P1M1=0x03;//0000,0011P1.0--P1.1先设为开漏。
断开内部上拉电阻
delay_ms(20);//20
ADC_CONTR=ADC_CONTR&0xE0;//1110,0000清ADC_FLAG,ADC_START位和低3位
ADC_CONTR=ADC_CONTR|(display_AD_channel_ID[channel]&0x07);//设置当前通道号
delay_ms
(1);//延时使输入电压达到稳定
ADC_DATA=0;//清A/D转换结果寄存器
ADC_LOW2=0;
ADC_CONTR=ADC_CONTR|0x08;//0000,1000ADCS=1,启动转换
do{DogReset();}
while((ADC_CONTR&0x10)==0);//0001,0000等待A/D转换结束
ADC_CONTR=ADC_CONTR&0xE7;//1110,0111清ADC_FLAG位,停止A/D转换
AD_Result_Temp=((AD_Result_Temp|ADC_DATA)<<2)|(ADC_LOW2&0x03);
//保存返回AD转换的结果
//----------------------------转换成可由串口显示的字符
AD_channel_result[channel][0]=AD_Result_Temp/1000+0x30;
AD_channel_result[channel][1]=(AD_Result_Temp%1000)/100+0x30;
AD_channel_result[channel][2]=(AD_Result_Temp%100)/10+0x30;
AD_channel_result[channel][3]=AD_Result_Temp%10+0x30;
//------------------------串口监视
//send_char_com(ADC_DATA);//////发送转换的到的值,这里只是高8位,值的转换需要考虑
//send_char_com(ADC_LOW2);//////发送转换的到的值,这里只是低2位,值的转换需要考虑
//send_string_com(AD_channel_result[channel],4);
delay_ms(10);//
return(ADC_DATA);
}
ucharAD_Filter(void){
uchari;
ucharcTemp[32];
ucharcAverage;
for(i=32;i>0;i--){
cTemp[i]=Ad_Change(0);
cAverage=((cAverage+cTemp[i])>>1);
}
return(cAverage);
}
voidInitCom(unsignedcharBaudRate){
switch(BaudRate){
case1:
THTL=64;break;//波特率300
case2:
THTL=160;break;//600
case3:
THTL=208;break;//1200
case4:
THTL=232;break;//2400
case5:
THTL=244;break;//4800
case6:
THTL=250;break;//9600
case7:
THTL=253;break;//19200
case8:
THTL=255;break;//57600
default:
THTL=208;break;//1200
}
}
voidChip_initial(void){
IE=0;
//定时器控制字初始化
TMOD=0x21;//定时器1为方式2,定时器0为方式1
TCON=0x50;//设置外部中断类型
T2CON=0x0d;//选择定时器1为波特率发生器,T2为捕获工作方式
//ET2=1;
ET0=1;//允许定时器0、定时器2中断
//外部中断设置
EX0=0;//FFSK中断初始时关闭,有载波时再开启
EX1=0;
IT1=1;//外部中断0、1均为下降沿触发
IT0=1;
//启动定时器0
TH0=vT0HVal;//启动定时器0
TL0=vT0LVal;
TR0=1;
InitCom(6);//设置波特率为96001-7波特率300-19200
SCON=0x50;//串口方式1,允许接收
TH1=THTL;
TL1=THTL;
PCON=0x80;//波特率加倍控制,SMOD位
RI=0;//清收发标志
TI=0;
TR1=1;//启动定时器
IP=0x02;//PT2=1
IPH=0x02;//PT2H=1,PT0H=1
EA=1;
delay_ms(10);//延时是为了避免定时器0无法产生中断的问题
}
voidPara_initial(void){
OutFlag=0;
cT01ms=vT01ms;
cT10ms=vT10ms;
//cT100ms=vT100ms;
cT01s=vT01S;
CS=0;//设置CS为0不选任何的音源,如为1则选第1路
}
voidsystem_initial(void){
Chip_initial();
Para_initial();
DogReset();//已针对STC89C58RD+作修改.06-04-06
}
voidmain(void){
system_initial();
while
(1){
DogReset();
if(OutFlag){
OutFlag=0;
send_char_com(AD_Filter());
}
}
}
voidTrint0(void)interrupt1using1{
TR0=0;//时基1mS
TH0=vT0HVal;
TL0=vT0LVal;
TR0=1;
TF0=0;
if(!
(--cT01ms)){
cT01ms=vT01ms;
if(!
(--cT10ms)){
cT10ms=vT10ms;
if(!
(--cT01s)){
cT01s=vT01S;
OutFlag=1;
}
}
}
}
voidComInINT(void)interrupt4{
if(RI){//判断是不收完字符
switch(SBUF){
case0x61:
CS=1;break;//根据SBUF设置CS 接收'abcde'调试方便
case0x62:
CS=2;break;
case0x63:
CS=3;break;
case0x64:
CS=4;break;
case0x65:
CS=0;break;
}
P1=255;//P1口全为高电平,4-7通过反相为低不选任何音源,0-3为高用于读取按键
RI=0;//RI清零
}
}