STM32F4的AD采样的结果是12位的,即采样的最大值为4096。而参考电压是3.3V,所以3.3V与4096是对应的。当然3.3V只是理想状态,实际上可能略有偏差。假设单片机的AD采集引脚电压为x,实际单片机的参考电压为z伏,读取到的AD值与x的对应关系如下:
再分析温度采集电路中,电压值与电阻值的关系。
两个等式联立,可以得出AD与电阻的关系:
程序中可以得到AD值以后计算出电阻值,然后查表,根据电阻值算出温度值。
此处可以做一些优化,既然要查表,那么能否干脆不计算了,把所有的计算工作都放到查表中?
把某个温度下,对应的电阻值带入公式,可以算出这个温度下对应的AD值。我把零下30℃到150℃的 AD值,不是电阻值算出来,放在了数组中:
const u16 tempRes_buf[181] = { 3876, 3863, 3849, 3835, 3819, 3804, 3787,
3769, 3751, 3732, 3712, 3692, 3670, 3648, 3625, 3601, 3576, 3550, 3523, 3496,
3467, 3438, 3408, 3377, 3344, 3312, 3278, 3243, 3208, 3171, 3134, 3096, 3057,
3018, 2978, 2937, 2896, 2854, 2811, 2768, 2725, 2681, 2637, 2592, 2547, 2502,
2457, 2411, 2366, 2320, 2274, 2229, 2183, 2138, 2092, 2048, 2003, 1958, 1914,
1871, 1827, 1784, 1742, 1700, 1659, 1618, 1578, 1538, 1499, 1461, 1423, 1386,
1350, 1314, 1279, 1245, 1211, 1179, 1146, 1115, 1084, 1054, 1025, 996, 968, 941,
915, 889, 864, 839, 815, 792, 769, 747, 726, 705, 685, 665, 646, 628, 610, 592,
575, 558, 542, 527, 512, 497, 483, 469, 456, 443, 430, 418, 406, 395, 383, 373,
362, 352, 342, 333, 323, 314, 306, 297, 289, 281, 273, 266, 259, 252, 245, 238,
232, 225, 219, 214, 208, 202, 197, 192, 187, 182, 177, 173, 168, 164, 160, 155,
152, 148, 144, 140, 137, 133, 130, 127, 124, 121, 118, 115, 112, 109, 107, 104,
102, 99, 97, 94, 92, 90, 88, 86, 84, 82, 80, 78, 76, 75, 73};
然后可以编写查表函数:
/**
* @brief 通过查表法,根据AD值计算温度
* @param AD值
* @Note 温度范围是-30~150度 如果超过范围,返回32767 ℃。10K上拉,3950 10K热敏电阻
* @retval 温度值
*/
short calcuTem(u16 ad_value)
{
short tempValue= 0x7fff;
if ((ad_value < 3877)&&(ad_value > 72))
{
for (short i = 0 ; i < 181 ; i++)
{
if (ad_value > tempRes_buf[i])
{
tempValue = i-30;
break;
}
}
}
//else err return 0x7fff
return tempValue;
}
主函数的打印语句也做相应修改:
while (1)
{
HAL_Delay(1000);
short tempA = calcuTem(ADC1_RANK1_AVG);
short tempB = calcuTem(ADC1_RANK2_AVG);
printf("采样次数: %dn",ADC_CHANNEL_CNT/2);
printf("温度A的AD值是 %d ;温度是%d ℃n ",ADC1_RANK1_AVG,tempA);
printf("温度B的AD值是 %d ;温度是%d ℃n ",ADC1_RANK2_AVG,tempB);
}
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』