第9章STC12C5A60S2单片机的片内A/D转换器9.1A/D转换器的内部结构9.2A/D转换器的相关寄存器9.3A/D转换器的应用第9章STC12C5A60S2单片机的片内A/D转换器•传统的单片机只能处理数字量信息,但在应用中经常需要处理一些连续变化的模拟量,例如温度、流量、电压、频谱等,这就需要先经过A/D转换转变成单片机可以处理的数字量。•STC90C58AD、STC12C5A60S2、STC12C5410AD等单片机内部集成了8路10位A/D转换电路,转换速度可达到250KHz(25万次/秒),即转换周期为4μs。9.1A/D转换的内部结构STC12C5A60S2单片机的A/D转换的输入端在P1口(P1.7-P1.0),上电复位后,P1口为弱上拉,用户可以通过程序将8路中的任何一路设置为A/D转换,不需作为A/D使用的口可继续作为I/O口使用。时序与控制逻辑电路D/A转换器输出缓冲器N位寄存器比较器时钟启动EOCVXVNOEN位数字量输出逐次逼近A/D转换器原理图从最高位开始的逐位试探法逐次逼近型A/D转换器转换原理:模拟量输入逐次逼近式:转换前,N位寄存器写入的数据先由最高位置1,DAC输出值与被测的模拟值进行比较:如果“低于”,该位的1被保留;如果“高于”该位的1被清除。然后下一位再置1,再比较,决定是否保留……直至最低位完成同一过程。写入的数据从最高位到最低位都试探过一遍的最终值就是A/D转换的结果。9.2A/D转换器的相关寄存器与A/D转换器相关的寄存器有:•P1口模拟功能控制寄存器P1ASF•A/D转换器控制寄存器ADC_CONTR•A/D转换结果寄存器ADC_RES、ADC_RESL•辅助寄存器AUXR1•与A/D中断有关的寄存器IE、IPH和IP1.P1口模拟功能控制寄存器P1ASF(地址9DH)•当P1口中某引脚要作为A/D使用时,要将P1ASF寄存器中该引脚所对应的位置1,即该引脚设置为模拟功能;•通过MOVP1ASF,#DATA指令实现。2.ADC控制寄存器ADC_CONTR(地址BCH)•启动A/D转换之前一定要保证A/D转换器的电源已打开,并且首次开启内部A/D转换电源时,需要适当的延时,等内部电源稳定后,再启动A/D转换。A/D转换结束后关闭A/D转换器的电源可降低功耗。ADC_POWER:A/D转换器的电源控制位。当该位为1时,开启A/D转换器电源;当该位为0时,关闭A/D转换器电源。SPEED1、SPEED0:转换速度控制位。对SPEED1、SPEED0两位取不同的值时,A/D转换所需的时间不同,具体情况如表9-1所示SPEED1SPEED0A/D转换所需时间1190个时钟周期转换一次10180个时钟周期转换一次01360个时钟周期转换一次00540个时钟周期转换一次ADC_FLAG:A/D转换器转换结束标志位,当A/D转换完成后,硬件自动将ADC_FLAG位置1,但要通过程序将其清0。ADC_START:转换启动控制位。将该位设置为1时,启动转换。转换结束后,该位自动清0。下次需要启动A/D转换时,必须再次将该位置1。CHS2、CHS1、CHS0:模拟输入通道选择。当CHS2、CHS1、CHS0三位取不同的值时,选择P1口不同的引脚作为模拟输入通道,具体情况如表9-2所示。CHS2CHS1CHS0模拟输入通道选择000P1.0作为A/D输入001P1.1作为A/D输入010P1.2作为A/D输入011P1.3作为A/D输入100P1.4作为A/D输入101P1.5作为A/D输入110P1.6作为A/D输入111P1.7作为A/D输入3.A/D转换结果寄存器ADC_RES、ADC_RESL(地址0BDH、0BEH)•用于保存A/D转换结果。•当辅助寄存器AUXR1(参见图2-8)中ADRJ(A/D转换结果寄存器的数据格式调整控制)位为0时,10位A/D转换结果的高8位存放在ADC_RES中,低2位存放在ADC_RESL的低2位中。•ADRJ位为1时,10位A/D转换结果的高2位存放在ADC_RES寄存器的低2位中,低8位存放在ADC_RESL寄存器中。•10位A/D转换的结果与输入电压的关系为:(ADC_RES[1:0],ADC_RESL[7:0])=210inVVCC9.3A/D转换器的应用实现A/D转换的步骤如下:(1)设置P1ASF寄存器,确定P1口的相应引脚作为模拟输入通道,设置辅助寄存器AUXR1中的ADRJ位确定转换结果保存格式;(2)设置A/D转换控制寄存器ADC_CONTR,打开A/D转换电源,确定转换速度和转换通道;(3)启动A/D转换。上电后首次打开内部AD转换模拟电源时,需适当延时,待内部模拟电源稳定后,再启动A/D转换。(4)A/D转换启动后经4个时钟周期延时可以通过软件查询ADC_CONTR寄存器中的ADC_FLAG位是否为1,当ADC_FLAG为1时表明A/D转换结束。AD转换结束后需将ADC_FLAG位清0。【例9-1】设单片机的系统时钟频率为12MHz,利用STC12C5A60S2单片机中的A/D转换模块,将测温电阻PT1000的阻值随温度变化所形成的电压信号转换成数字信号,单片机读取后存放于30H、31H单元,如图9-5所示。【例9-1】设单片机的系统时钟频率为12MHz,利用STC12C5A60S2单片机中的A/D转换模块,将测温电阻PT1000的阻值随温度变化所形成的电压信号转换成数字信号,单片机读取后存放于30H、31H单元,如图9-5所示。•分析:首先将PT1000阻值变化所反应出的电压信号经仪表放大器AD623放大成0-5V的电压信号。经单片机内部的A/D转换器转换成数字量,为了提高转换的精确度,尽量减小电源噪声的影响,可连续采集64次,并对A/D转换的结果求和,相当于实现16位的A/D转换。•汇编语言子程序AD_RESULT1EQU30H;A/D转换结果的高8位AD_RESULT2EQU31H;A/D转换结果的低8位P1ASFEQU9DHAUXR1EQUA2HADC_CONTREQUBCHAD_CONVERT:MOVP1ASF,#01H;选择P1.0为A/D转换模拟量的输入ORLAUXR1,#00000100B;选择ADRJ位为1MOVA,#0E0HMOVADC_CONTR,A;开启A/D转换的电源MOVAD_RESULT1,#00HMOVAD_RESULT2,#00HLCALLDELAY_10μs;等待A/D转换电源稳定MOVA,#11101000BMOVADC_CONTR,A;启动A/D转换MOVR6,#64;R6作为计数器AD_CONVERT1:LCALLAD_CONV;调用A/D转换的子程序DJNZR6,AD_CONVERT1;64次转换未结束,继续转换MOVA,#0MOVADC_CONTR,A;清ADC_FLAG位,并停止AD转换RETAD_CONV:MOVA,ADC_CONTRJNBACC.4,AD_CONV;等待A/D转换结束MOVA,#11101000BMOVADC_CONTR,A;再次启动AD转换MOVA,ADC_RESL;读转换结果的低8位ADDA,AD_RESULT2;与低8位结果相加MOVAD_RESULT2,A;将得到的结果存放至31H单元MOVA,ADC_RES;读转换结果的高两位ANLA,#03H;屏蔽ADC_RES寄存器的高6位ADDCA,AD_RESULT1;与高8位结果相加MOVAD_RESULT1,A;将得到的结果存放至30H单元RETDELAY_10μs:MOVR5,#1EHDJNZR5,$RETC51程序:#includeSTC12C5A.h#includeintrins.h//声明本征函数库unsignedinttemp,result;unsignedcharnum=0x40;//设置A/D转换次数voidAD_CONV();//A/D转换函数的声明voidDELAY_10μs();//延时10μs函数的声明voidmain(){P1ASF=0x01;选择P1.0为A/D转换模拟量的输入AUXR1=0x04;选择ADRJ位为1ADC_CONTR=0xE0;//开启动A/D转换的电源DELAY_10μs();//延时10μsADC_CONTR=0xE8;//启动A/D转换while(num!=0){AD_CONV();//调用A/D转换函数num--;//计数值减1}while(1);}voidAD_CONV(){do{temp=ADC_CONTR;//读A/D转换的控制寄存器的内容}while((temp&0x10)!=0x10);//等待A/D转换结束ADC_CONTR=0xE8;//再次启动A/D转换temp=ADC_RESL;//读转换结果的低8位result+=temp;//累加转换结果temp=ADC_RES;//读转换结果的高2位temp=temp&0x0003;//屏蔽转换结果的高6位temp=_irol_(temp,8);//将转换结果左移8位result+=temp;//累加转换结果}voidDELAY_10μs()//延时10μs函数{unsignedchara;for(a=30;a0;a--);}