说起STC15通道ADC范例这个8次平均代码,当然没有问题。
我之前用20脚STC8G1K08又多出好多脚感觉不爽,近期改8脚STC8G1K08A (练练多脚复用,体积没小多少,还厚一些,才便宜几毛,好手工焊而已)。双路ADC(因引脚不够,其中1路直接改用15通道先测MCU供电电压VCC,再换算电池电压了,另外一路P55脚复用,P30P31串口调试ISPLED复用等等)。之前2个通道ADC代码全部放在一起共用不少代码,只顺序切换通道读取转换一下,没有刻意中间隔一段时间(之前2个空操作,这次有地方就多加了3个),也没用8次平均方法,每次都一次顺利读取转换成功。可能是我之前测的内置2个都是电池电压,比较稳定或者精度要求没那么高吧(这次另外一路测的光敏电阻和1M大电阻分压值,光敏电阻还并联了一个LED,罕见见的。。。。玩呗)!
void BAT() //VCC电压ADC15,P55电压ADC5,低电量告警及充电指示等(早晚光控代码另列); P3031P55三脚复用最简方案用 230523;
{
u16 res, *BGV; //res:ADC结果(分辨率); *BGV:指针变量;
res=0; // 230524:int全改为u16没有问题(但得同时改!);
BGV = (u16 idata *)0xef; //获取内部电压(1次即可),内部1.19V参考源值存放在idata中,EFH高字节F0H低字节;单位mV;
P5IE=P5M1=0x20, R=G=b=1; //1、ADC前:P55允许输入短暂置高阻,关彩灯可提高ADC稳定准确度!
//2. ADC设置(2句共用):
ADCCFG = 0x2f; //设置ADC时钟为系统时钟/2/16 (含右对齐);
ADCTIM = 0x3f; //设置ADC内部时序:(手册建议3f,2A~3F);
//3、ADC15: VCC和Vbat电压检测;
ADC_CONTR = 0xcf; //使能ADC模块,并选择第15通道,启动转换3合1;
_nop_(),_nop_(),_nop_(),_nop_(),_nop_(); //参考手册2个空操作
while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
ADC_CONTR &= ~0x20; //清完成标志
// ADC_CONTR &= 0x7F; //ADC转换完即断电更省电; (这里后面再一起关);
res = (ADC_RES << 8) | ADC_RESL; //读取ADC结果 (右对齐:高2位低8位,前面自动补0);
VCC =(u16)(1024L * *BGV/res); //先算1次后面再分好; 再处理Vbat修正值+150;
Vbat=VCC+150L; //
//4、ADC5: VP55电压检测/早晚判断;
ADC_CONTR = 0xc5; //使能ADC模块,并选择第15通道,启动转换3合1;
_nop_(),_nop_(),_nop_(),_nop_(),_nop_(); //参考手册2个空操作
while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
ADC_CONTR &= ~0x20; //清完成标志
ADC_CONTR &= 0x7F; //ADC转换完即断电更省电; (这里后面再一起关);
res = (ADC_RES << 8) | ADC_RESL; //读取ADC结果 (右对齐:高2位低8位,前面自动补0);
VP55 =(u16)((u32)VCC*(u32)res >>10); //220524:/1024改右移10位快,注意变量运算转换避免溢出错误等;
if(CHG==0) //5、低电量告警/自动待机; 未充电有效; 230518;
{
if(Vbat>=3438 && Vbat<=3480) //1-5%告警:红灯PD2秒快慢闪1遍;同时关大灯;
{W=R=G=b=1, dl_ms(100),R=0,dl_ms(50),R=1,dl_ms(100),R=0,dl_ms(100),R=1;}
if(Vbat<3438) { W=R=G=b=1, status=2;} //<1%灯全灭转状态2:自动待机;
}
else //6、充电状态指示:4种; 不进PD不待机! 230516;
{status=3, R=G=b=1; //转状态3:充电指示;先灭彩灯;
if (Vbat>4132) {G=0,dl_ms( 100),G=1, dl_ms( 500);} // 100%:绿灯常闪; 可当提醒; (95%当充满保护,全按0℃,+5mV);
else
{if (Vbat>4077) {G=0,dl_ms(1000),G=1, dl_ms( 100);} // > 90%:绿灯亮1秒, 闪1次;
else
{if (Vbat>3918) {G=0,dl_ms(1000),G=1, R=0,dl_ms( 100), R=1;} // > 75%:绿灯亮1秒,红灯闪1次; 230502 增加1档;
else
{if(Vbat>3716) {R=0,dl_ms(1000),R=1, G=0,dl_ms( 100), G=1;} // > 50%:红灯亮1秒,绿灯闪1次;
else {R=0,dl_ms(1000),R=1, dl_ms( 100);} //<= 50%:红灯亮1秒, 闪1次;
}}}}
}
|