51 单片机实战教程(17 内部ADC转换器)

您所在的位置:网站首页 51单片机VIL 51 单片机实战教程(17 内部ADC转换器)

51 单片机实战教程(17 内部ADC转换器)

#51 单片机实战教程(17 内部ADC转换器)| 来源: 网络整理| 查看: 265

       STC15W系列有内部集成了8路10bit ADC转换器,该转换器是逐次比较型。其输入通道切换是通过内部模拟开关实现的。其原理结构如下:

        转换结果存储在ADC-RES, ADC_RESL寄存器中。ADC-RES可以存储高8位也可存储高2位,缺省状态下是存储高8位,ADC_RESL存储低2位,当CLK_DIV寄存器的bit5设置为1时,ADC-RES存储高2位,ADC_RESL存储低8位。

        与ADC相关的功能寄存器如下:

 

 

 

   STC15W系列单片机的ADC没有单独的参考电压输入管脚,是以单片机的供电电压做参考电压。由于电源噪声,ADC转换结果会受到一些影响。如果要得到比较精确的结果,我们可以通过第9通道,读取内部BandGap参考电压的ADC结果,来比较修正。单片机的内部BandGap参考电压是很准确的。当下载程序时勾选下面红框中的项

BandGap参考电压将会存储在指定的内存位置中,当程序存储区内存大于1K时,存储位置为存储内存结尾位置减8,如STC15W4K61,BandGap参考电压的存储地址在0xF3FF-8,即0xF3F7。存储电压的单位为毫伏。

        读取第九通道ADC值的方法如下:将寄存器P1ASF赋值为0x00,按正常读取通道0的ADC值的方法读取通道0的ADC值,其结果就是第九通道ADC值,即BandGap参考电压的ADC值。

        基于目前对STC15W系列单片机ADC的了解,就可以动手写ADC的库函数了,新建两个文件分别以stcadc.h,stcadc.c存入C51 Template文件夹下Library文件夹中。完成后的头文件如下:

/*stcadc.h Designed by Bill Liu Version 0.0 Modified last by Bill Liu on 06/13/2022 */ #ifndef __STCADC_H__ #define __STCADC_H__ #include "mtype.h" #include "delay.h" #include "stc15w4k.h" extern ui16 code Vbg_ROM; // band gap voltage stord at memory end address -8, define at main.c or main.h extern FSYSCLOCK FSCLK; // typedef enum { ADC_CH0 = 0x01, //ADC Channel P1.0 ADC_CH1 = 0x02, //ADC Channel P1.1 ADC_CH2 = 0x04, //ADC Channel P1.2 ADC_CH3 = 0x08, //ADC Channel P1.3 ADC_CH4 = 0x10, //ADC Channel P1.4 ADC_CH5 = 0x20, //ADC Channel P1.5 ADC_CH6 = 0x40, //ADC Channel P1.6 ADC_CH7 = 0x80 //ADC Channel P1.7 } ADC_CH; // typedef enum { CLK_C540 = 0, //540 clk cycle covert a time CLK_C360, //360 clk cycle covert a time CLK_C180, //180 clk cycle covert a time CLK_C90, //90 clk cycle covert a time }ADC_SPEED; /*********************************************************** Function: ADC_EnableChn(BOOL mAble, ADC_CH myCh); Return value: void Discription: configure ADC_CH I/O ADC mode enable/disable Example: ADC_EnableChn(1, ADC_CH0); //ADC_CH1 ADC enable ***********************************************************************/ void ADC_EnableChn(BOOL mAble, ADC_CH myCh); /*********************************************************** Function: ADC_PowerOn(); Return value: void Discription: ADC power on Example: ADC_PowerOn(); ***********************************************************************/ void ADC_PowerOn(); /*********************************************************** Function: ADC_PowerOff(); Return value: void Discription: ADC power switch off Example: ADC_PowerOff(); ***********************************************************************/ void ADC_PowerOff(); /*********************************************************** Function: ADC_SpeedConfig(ADC_SPEED mSpeed); Return value: void Discription: configure ADC speed Example: ADC_SpeedConfig(CLK_C360); ***********************************************************************/ void ADC_SpeedConfig(ADC_SPEED mSpeed); /*********************************************************** Function: ADC_GetFlag(); Return value: void Discription: get ADC finish flag Example: ui8 tem = ADC_GetFlag(); ***********************************************************************/ ui8 ADC_GetFlag(); /*********************************************************** Function: ADC_GetFlag(); Return value: void Discription: get ADC finish flag Example: ui8 tem = ADC_GetFlag(); ***********************************************************************/ void ADC_ResetFlag(); /*********************************************************** Function: ADC_Start(); Return value: void Discription: ADC start Example: ADC_Start(); ***********************************************************************/ void ADC_Start(); /*********************************************************** Function: ADC_ChnSel(ADC_CH mSel); Return value: void Discription: select ADC channel Example: ADC_ChnSel(ADC_CH0); ***********************************************************************/ void ADC_ChnSel(ADC_CH mSel); /*********************************************************** Function: ADC_Init(ADC_SPEED mSel); Return value: void Discription: init ADC speed and set power on Example: ADC_ChnSel(CLK_C360); ***********************************************************************/ void ADC_Init(ADC_SPEED mSel); /*********************************************************** Function: ADC_GetResult(ADC_CH Chx); Return value: ui16 Discription: get x channel ADC result Example: ui16 tem = ADC_GetResult(ADC_CH2); ***********************************************************************/ ui16 ADC_GetResult(ADC_CH Chx); /*********************************************************** Function: ADC_GetBandGapRes(); Return value: ui16 Discription: get band gap voltage ADC result Example: ui16 tem = ADC_GetBandGapRes(); ***********************************************************************/ ui16 ADC_GetBandGapRes(); /*********************************************************** Function: ADC_GetBgVoltage(); Return value: ui16 Discription: get mcu band voltage Example: ui16 tem =ADC_GetBgVoltage(); //unit: mV ***********************************************************************/ ui16 ADC_GetBgVoltage(); /*********************************************************** Function: ADC_ChnVoltage(ADC_CH Chx); Return value: ui16 Discription: get x channel input voltage Example: ui16 tem =ADC_ChnVoltage(ADC_CH2); //unit: mV ***********************************************************************/ ui16 ADC_ChnVoltage(ADC_CH Chx); #endif

完成后的源代码如下:

/*stcadc.c Designed by Bill Liu Version 0.0 Modified last by Bill Liu on 12/21/2021 */ #include "stcadc.h" //*********************************************************************** void ADC_EnableChn(BOOL mAble, ADC_CH myCh) { if(mAble) P1ASF |= myCh; else P1ASF &= ~myCh; } //End of ADC_EnableChn(BOOL mAble, ADC_CH myCh) //***************************************************** void ADC_PowerOn() //switch on A/D power { ADC_CONTR |=0x80; } //End of ADC_PowerOn() //***************************************************** void ADC_PowerOff() //switch off A/D power { ADC_CONTR &=0x7F; } //End of ADC_PowerOff() //***************************************************** void ADC_SpeedConfig(ADC_SPEED mSpeed) { ui8 tem = ADC_CONTR; SetBits(&tem, 6, 5, mSpeed); ADC_CONTR = tem; } //End of ADC_SpeedConfig(ADC_SPEED mSpeed) //***************************************************** ui8 ADC_GetFlag()//get A/D flag state { return GetBit(ADC_CONTR, 4); } //End of ADC_GetFlag() //***************************************************** void ADC_ResetFlag() //reset A/D flag { ADC_CONTR &= ~0x10; } //End of ADC_ResetFlag() //***************************************************** void ADC_Start() //start A/D conversion { ui8 tem = ADC_CONTR; tem |= 0x80; tem |= 0x08; ADC_CONTR = tem; } //End of ADC_Start() //***************************************************** void ADC_ChnSel(ADC_CH mSel) { ui8 tem = ADC_CONTR; switch(mSel) { case ADC_CH0: SetBits(&tem,2,0,0x00); break; case ADC_CH1: SetBits(&tem,2,0,0x01); break; case ADC_CH2: SetBits(&tem,2,0,0x02); break; case ADC_CH3: SetBits(&tem,2,0,0x03); break; case ADC_CH4: SetBits(&tem,2,0,0x04); break; case ADC_CH5: SetBits(&tem,2,0,0x05); break; case ADC_CH6: SetBits(&tem,2,0,0x06); break; case ADC_CH7: SetBits(&tem,2,0,0x07); break; } ADC_CONTR = tem; } //End of ADC_ChnSel(ui8 mSel) //**************************************************** void ADC_Init(ADC_SPEED mSel) { CLK_DIV &= ~0x20; //ADC_RES store high 2 bits ADC_RES=0; ADC_RESL=0; ADC_SpeedConfig(mSel); ADC_ResetFlag(); ADC_PowerOn(); Delayxms(2,FSCLK); } //End of ADC_Init(ADC_SPEED mSel) //**************************************************** ui16 ADC_GetResult(ADC_CH Chx) { ui16 tem; ADC_RES=0; ADC_RESL=0; ADC_EnableChn(1, Chx); ADC_ChnSel(Chx); ADC_ResetFlag(); ADC_Start();//start A/D conversion Delayxus(2,FSCLK); while(!ADC_GetFlag()); ADC_ResetFlag(); tem = ADC_RES; tem


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3