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文件夹中。完成后的头文件如下:
#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; void ADC_EnableChn(BOOL mAble, ADC_CH myCh); void ADC_PowerOn(); void ADC_PowerOff(); void ADC_SpeedConfig(ADC_SPEED mSpeed); ui8 ADC_GetFlag(); void ADC_ResetFlag(); void ADC_Start(); void ADC_ChnSel(ui8 mSel); void ADC_Init(ADC_SPEED mSel); ui16 ADC_GetResult(ADC_CH Chx); ui16 ADC_GetBandGapRes(); ui16 ADC_GetBgVoltage(); ui16 ADC_ChnVoltage(ADC_CH Chx); #endif
完成后的源代码如下:
#include "stcadc.h" / #ifndef __MAIN_H_ #define __MAIN_H_ #include "mtype.h" #include "delay.h" #include "stcuart.h" #include "stcio.h" #include "myport.h" #include "stcadc.h" const FSYSCLOCK FSCLK = F30MHz; //define system clock frequency 30MHz, FSYSCLOCK was defined in mtype.h const ui32 FSCLK1 = 30000000L; //define system clock frequency 30MHz ui16 code Vbg_ROM _at_ 0xf3f7; //band gap voltage stord at memory end address -8 i8 mstr[25] =""; void SundBuzzerx10ms(ui8 x);
测试程序源文件:
#include "main.h" void main() { STCIO_InitPortsBits(P0|P1|P2|P3|P4, 0xFF, BI_IO); P3 = 0xFF; P0 = 0xFF; UartS1_Init(VBAUD_8BITS,G1,T2,9600); STCIO_InitP3Bit(SCT_BIT1, PP_OUT); ADC_Init(1); SundBuzzerx10ms(50); Delay10xms(50, FSCLK); SundBuzzerx10ms(50); while(1) { LongToString(Vbg_ROM,mstr); UartS1_SendString(mstr); UartS1_SendString("rn"); LongToString(ADC_GetBandGapRes(),mstr); UartS1_SendString(mstr); UartS1_SendString("rn"); LongToString(ADC_GetResult(4),mstr); UartS1_SendString(mstr); UartS1_SendString("rn"); LongToString(ADC_ChnVoltage(ADC_CH4),mstr); UartS1_SendString(mstr); UartS1_SendString("rn"); Delay10xms(200, FSCLK); } } //End of main() //********************************************* void SundBuzzerx10ms(ui8 x) { BUZZER = 0; Delay10xms(x, FSCLK); BUZZER = 1; } //End of SundBuzzerx10ms(ui8 x)
编译后下载到IAP15W4K61S4单片机中,在串口口助手中得到的结果如下:
说明库函数能够正常运行。以上代码文件已上传到CSDN,文件名为STC ADC Library Source Code.rar, 如下离线查看,可去下载。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)