前段时间买了个晶体测试仪,很好奇他能测得供电的电池电压。我以前一直用ADC采样,不管用什么电源供电,电压如何变化,所得最大值1023对应一定是当前供电电压,它是怎么获得供电电压的真实电压值的呢。
网上学习了下,原来AVR单片机有内置的基准电压,比如Promini的328P芯片内部基准电压是1.1V。就是说不管供电电压多大,用ADC采样出来的0~1023这数值对应的电压值是0V~1.1V,超过了1.1V仍然是1023。AVR文档中也指出这个基准值有一定偏差。
不过重点是需要设置成内部基准电压测量,查文档得知:
ADMUX = _BV(REFS1) | _BV(REFS0);
将REFS1和REFS0寄存器位置1,就是打开了内部参考电压。当然这样就不能用Arduino自带的函数取ADC了,得自己设置寄存器。
我是这么配的
// 使用内部1.1V基准电压
ADMUX = _BV(REFS1) | _BV(REFS0);
//使用14pin脚,也就是arduino的A0脚
ADMUX |= _BV(REFS0);
//4分频,这采样速度有点快
ADCSRA = _BV(ADPS1);
//忘记这个寄存器位是干什么的了
ADCSRA |= _BV(ADEN);
//采样函数
int Sampler()
{
ADCSRA |= _BV(ADSC);
loop_until_bit_is_set(ADCSRA, ADIF);
int val = ADC;
bitClear(ADCSRA, ADIF);
return val;
}
但是1.1V的基准电压值太低,测量电压必须比它小。所以给需要测试的电压分压一下。我用了1个150k,1个10k电阻串联,然后A0脚连到2个电阻中间测量,15分之一的电压值肯定在1.1v以下了。
然后把取到的值换成电压值:
电压值 = ((采样值/1023) * 1.1 ) * (150 + 10)/ 10;
当然这仍然是有误差的,用万用表测150k的电阻值其实只有147k,10k只有9.7k,为了减少误差,我把公式分开写了。最后结果和万用表测的比较接近了。