最重要的公式
要记住ADC测量结果无非就是一个代表电压量的值,管脚上的模拟信号转换为12位二进制数据(0xFFF),例如:如果参考电压是5V,ADC输入也是5V,那ADC转换结果就是0xFFF;如果参考电压是5V,ADC输入是2.5V,那ADC转换结果就是0xFFF除以2。ADC转换结果除以满量程ADC值(即0xFFF)就是与参考电压的比例,这个比例乘以参考电压就是实际电压值(Vain)。
计算代码如下:
// CN Spec, 18.1.1, P193, ADC_DATA = 4095 * (Vain/Vref)
// So: Vain = (ADC_DATA * Vref) / 4095, Vref is 'VDD voltage'
adc_mgnts[ch].vol = ((adc_mgnts[ch].aver_adc_data * Vref_vol) / 0xFFF);
怎么得到参考电压Vref?
Vref可以通过计算获得,或者测量得到。
要求不高可以直接用万用表量管脚pin9,即Vdd的电压(我直接测到就是接近5V),后面计算参考电压的就不用看了。
计算参考电压Vref的方法见下面代码,其实官方例程里用ADC测量VDD的代码。
先计算Band-gap(见中文spec例程P195),再用读取到的Band-gap值通过ADC计算VDD值(见中文spec例程P196)
// CN Spec, 18.1.4, P196, VDD voltage
Vref_vol = ((0xFFF * Bandgap_Voltage) / adc_mgnts[(ADC_CH_BAND_GAP)].aver_data);
温度传感器LM50计算温度
上面的ADC转换得到电压值后,通过公式得到温度值。为了方便传输,并提高温度精度到0.01摄氏度,这里用到了modf函数提取double类型的整数部分,得到的结果除以100即是摄氏度。
#include <math.h>
#define TEMP_REAL_DATA_MULTIPLE_NUM 100
/* get VDD volume value, unit is 0.01℃ */
int get_temp_value_by_adc_data(double adc_data)
{
double out;
double f;
double big_adc_data;
int vol_mV = 0;
/* T = (VO - 500 mV) / 10 mV/℃ */
big_adc_data = (((adc_data) - 500.0) / 10);
big_adc_data *= TEMP_REAL_DATA_MULTIPLE_NUM;
f = modf(big_adc_data, &out);
vol_mV = (int)out;
#if (defined DEBUG_MSG) && (defined EN_ADC_COMPUTE_DEBUG)
printf("ADC: temp value fmod %e =%f, real out=%e(%d)"CRLF, adc_data, f, out, vol_mV);
#endif
return vol_mV;
}
|