src/main/sensors/voltage.c中的函数:
159 STATIC_UNIT_TESTED uint16_t voltageAdcToVoltage(const uint16_t src, const voltageSensorADCConfig_t *config)
1 {
2 // calculate battery voltage based on ADC reading
3 // result is Vbatt in 0.01V steps. 3.3V = ADC Vref, 0xFFF = 12bit adc, 110 = 10:1 voltage divider (10k:1k) * 100 for 0.01V
4 return ((((uint32_t)src * config->vbatscale * getVrefMv() / 10 + (0xFFF * 5)) / (0xFFF * config->vbatresdivval)) / config->vbatresdivmultiplier);
5 }
getVreMv()函数,默认返回是3300,对应3300mV;
config->vbatscale,默认值是110;
config->vbatresdivval,默认值是10;
config->vbatresdivmultiplier,默认值是1.
找到个at32f435的原理图,可能不一定完全对应的上,原理图里只用了一个adc,用的10K:1K测量的电池电压。
按我的逻辑,(adc值/0xfff)*3300,得到测量的adc电压值,然后放大11倍,就是电池电压了。可看这个公式,对应不上。
-----------------------------------------------------------
如果把原式中的+(0xfff*5)去掉,精简下:
((((uint32_t)src * config->vbatscale * getVrefMv() / 10) / (0xFFF * config->vbatresdivval)) / config->vbatresdivmultiplier);
= src * 110 * 3300 / 10 / (0xFFF * 10) / 1
= src * 110 * 3300 / 0xFFF
这样看,就和我的逻辑计算公式差不多了,只是查了10倍, 那么原式中的+0xFFF*5,有什么作用呢?
-----------------------------------------------------------
单独把0xFFF*5部分拿出来再除以后续部分:
0xFFF*5 / (0xFFF * 10) / 1 = 0.5
这么看,这部分是为了四舍五入?
感觉这个转换函数写的好繁琐。
----------------------------------------------
算错,src * 110 * 3300 / 10 / (0xFFF * 10) / 1, 应该是:
= src * 110 * 3300 / 0xFFF * 10 * 10
= src * 11 * 3300 / 0xFFF * 10
可以看作将adc值转换为电压值后,按分压电阻放大11备得到mV单位的电池电压,再除以10得到0.01V单位的电池电压。
算是明白了,就是觉得这个公式好繁琐。
最近编辑记录 Gentlepig (2024-07-12 10:42:50)
离线
经飞控群里二木仙人指点,去看了inav的代码:
455 uint16_t getVBatSample(void) {
1 // calculate battery voltage based on ADC reading
2 // result is Vbatt in 0.01V steps. 3.3V = ADC Vref, 0xFFF = 12bit adc, 1100 = 11:1 voltage divider (10k:1k)
3 return (uint64_t)adcGetChannel(ADC_BATTERY) * batteryMetersConfig()->voltage.scale * ADCVREF / (0xFFF * 1000);
4 }
这个就很容易理解了。
最近编辑记录 Gentlepig (2024-07-12 10:20:34)
离线