19.6.4 利用ADC第15通道测量外部电压或电池电压
STC8H系列ADC的第15通道用于测量内部固定信号源1.19V,由于内部固定信号源很稳定,约为1.19V, 且不会随芯片的工作电压的改变而变化,所以可以通过测量内部固定信号源1.19V,然后通过ADC的值便 可反推出外部电压或外部电池电压。 ===也可以使用ADC的第15通道固定接的内部固定信号源1.19V,反推外部ADCx通道输入电压 C语言代码
//测试工作频率为11.0592MHz #include "stc8h.h" #include "intrins.h" #define FOSC 11059200UL #define BRT (65536-(FOSC / 115200+2) / 4) //加2操作是为了让Keil编译器 //自动实现四舍五入运算 int *BGV; //内部参考信号源值存放在idata中 //idata的EFH地址存放高字节 //idata的F0H地址存放低字节 //电压单位为毫伏(mV) bit busy; void UartIsr() interrupt 4 { if(TI) { TI = 0; busy = 0; } if(RI) { RI = 0; } } void UartInit() { SCON= 0x50; TMOD= 0x00; TL1= BRT; TH1= BRT >> 8; TR1= 1; AUXR= 0x40; busy= 0; } void UartSend(char dat) { while(busy); busy= 1; SBUF= dat; } void ADCInit() { ADCTIM= 0x3f; //设置ADC内部时序 ADCCFG= 0x2f; //设置ADC时钟为系统时钟/2/16 ADC_CONTR= 0x8f; //使能ADC模块,并选择第15通道 } int ADCRead() { intres; ADC_CONTR|= 0x40; //启动AD转换 _nop_(); _nop_(); while(!(ADC_CONTR & 0x20)); //查询ADC完成标志 ADC_CONTR&= ~0x20; //清完成标志 res= (ADC_RES << 8) | ADC_RESL; //读取ADC结果 returnres; } void main() { intres; intvcc; inti; P_SW2|= 0x80; //使能访问XFR P0M0= 0x00; P0M1= 0x00; P1M0= 0x00; P1M1= 0x00; P2M0= 0x00; P2M1= 0x00; P3M0= 0x00; P3M1= 0x00; P4M0= 0x00; P4M1= 0x00; P5M0= 0x00; P5M1= 0x00; BGV= (int idata *)0xef; ADCInit(); //ADC初始化 UartInit(); //串口初始化 ES= 1; EA= 1; // ADCRead(); // ADCRead(); //前两个数据建议丢弃 res= 0; for(i=0; i<8; i++) { res += ADCRead(); //读取8次数据 } res>>= 3; //取平均值 vcc= (int)(4096L * *BGV / res); //(12位ADC算法)计算VREF管脚电压,即电池电压 // vcc= (int)(1024L * *BGV / res); //(10位ADC算法)计算VREF管脚电压,即电池电压 //注意,此电压的单位为毫伏(mV) UartSend(vcc>> 8); //输出电压值到串口 UartSend(vcc); while(1); }
上面方法是使用ADC的第15通道反推外部电池电压的。在ADC测量范围内,ADC外部待测量电压与ADC的测量值是成正比例的,所以也可以使用ADC的第15通道反推外部通道输入电压,假设当前已获取了内部固定信号源电压为BGV,内部固定信号源的ADC测量值为resbg,外部ADCx通道输入电压的ADC测量值为resx,则外部通道输入电压 Vx=BGV / resbg * resx; |