随手小记一下,如果有错误还望大佬指正。
至关重要的就是确定型号,程序其实没多少东西。
首先你要先确定你的热敏电阻的型号,如果你是从淘宝购买,可以去问客服。如果你不知道型号如何,可以列一个表,在STM中利用你的分压公式,计算出你的电阻在温度多少的时候,电阻是多少。程序在下方,如图。要想问参考温度怎么得到的,那就是用另一个温度传感器。
热敏电阻的电阻值是随着温度的变化而变化的,温度越高电阻越小。
static float temp_res[61] = {
43.1172,41.1663,39.3153,37.5587,35.891,
34.3074,32.8029,31.3734,30.0145,28.7225,
27.4936,26.3245,25.2119,24.1527,23.1442,
22.1835,21.2682,20.3959,19.5644,18.7714,
18.0151,17.2935,16.6048,15.9475,15.3198,
14.7203,14.1475,13.6003,13.0772,12.5771,
12.0988,11.6413,11.2037,10.7848,10.3839,
10,9.6324,9.2802,8.9428,8.6195,
8.3096,8.0124,7.7275,7.4541,7.1919,
6.9403,6.6987,6.4669,6.2442,6.0304,
5.825,5.6276,5.438,5.2557,5.0804,
4.9119,4.7498,4.5939,4.4439,4.2995,
4.1605
}; //数组的【0】代表-10摄氏度,数组最高到50摄氏度 每增加一个数就上升一度 对应的元素代表此温度下的电组值 以K为单位
建好数组后,就要想怎么将阻值采集出来,由于只能采集电压值,所以你要在外围搭建一个小电路,我才用的是串联分压,与10K电阻串联。在中点采集的电压即是这个电阻电压。
AD采集代码
void sys_adc_init(void)
{
GPIO_DeInit(GPIOB);//复位GPIOB
GPIO_Init(GPIOB,GPIO_Pin_0,GPIO_Mode_In_FL_No_IT);//初始化B0为浮空输入
CLK_PeripheralClockConfig (CLK_Peripheral_ADC1,ENABLE);//开启ADC时钟
ADC_Init (ADC1,ADC_ConversionMode_Single,ADC_Resolution_12Bit,ADC_Prescaler_1);//ADC1,单次采样,12位,1分频
ADC_Cmd(ADC1,ENABLE);//ADC1使能
ADC_ChannelCmd (ADC1,ADC_Channel_18,ENABLE);//ADC1 18通道使能 18通道是B0 通道号对应什么引脚在PDF里
}
u16 sys_adc_read(void)
{
ADC_SoftwareStartConv (ADC1);//开启软件转换
while(!ADC_GetFlagStatus (ADC1,ADC_FLAG_EOC));//等待转换结束
ADC_ClearFlag (ADC1,ADC_FLAG_EOC);//清除相关标识
return ADC_GetConversionValue (ADC1);
}
计算电阻公式
float compute_res(u16 adc_value) //计算对应ad值下的电阻值
{
float res;
res = (float)(10 * adc_value) / (float)(4095 - adc_value); //10是与热敏电阻串联的电阻大小 以K为单位
return res;
}
进行电阻值在数组区间查询:
void find_temp(float real_res) //计算出电阻值后,用for循环查询估摸出处于哪个区间里。
{
for(u8 i=0;i<61;i++) //正着数找到温度最大值
{
if(real_res > temp_res[i])
{
temp_max_flag = i;
break;
}
}
//其实这两个温度就是差1度,也可以temp_min_flag = temp_max_flag - 1;
for(int8_t i=60;i>=0;i--)//倒着数找温度最小值
{
if(real_res < temp_res[i])
{
temp_min_flag = i;
break;
}
}
}
//温度最低值
temp_min = -20 + temp_min_flag; //-20是最低温度
真实温度计算:
/********************
看看再这个温度区间里,真实的value占多少,一度这个区间的
相当于在这1度的区间内,将其线性化
********************/
temp_real_region = temp_res[temp_min_flag] - c; //c是计算的电阻值。
temp_region = temp_res[temp_min_flag] - temp_res[temp_max_flag];
d = temp_real_region / temp_region;
//真实温度就是最小温度,加上占的那区间的百分比
temp = (float)temp_min + d;
主函数:
void main(void)
{
u16 u16_adc1_value;//记录每次采集的AD值
int16_t temp_min;//当前阻值温度的可能的最小值
float c,d;//防止直接给函数赋值失败,先让其计算一下
float temp_real_region,temp_region,temp; //计算真实温度的变量
sys_clock_init();//时钟初始化
sys_adc_init();//AD初始化
usart_init(115200);//串口初始化
while (1)
{
u16_adc1_value = sys_adc_read(); //取出电压值
c = compute_res(u16_adc1_value);//计算
find_temp(c);
temp_min = -10 + temp_min_flag; //估摸一下温度准不准
/********************
看看再这个温度区间里,真实的value占多少,一度这个区间的
********************/
temp_real_region = temp_res[temp_min_flag] - c;
temp_region = temp_res[temp_min_flag] - temp_res[temp_max_flag];
d = temp_real_region / temp_region;
//真实温度就是最小温度,加上占的那区间的百分比
temp = (float)temp_min + d;
mprintf("阻值value结果为: ");
mprintf("%dn",u16_adc1_value);
mprintf("最高阻值为: ");
mprintf("%fn",c);
mprintf("最低温度为: ");
mprintf("%dn",temp_min);
mprintf("真实温度为: ");
mprintf("%fn",temp);
}
}
得到的结果:
经过电压表测量,AD值正确,电阻值正确, 经查表,温度值在电阻值区间内。
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』