当前位置:   article > 正文

STM32 热敏电阻测量温度_stm32测电阻

stm32测电阻

一、硬件

STM32F103C8T6、热敏电阻传感器、OLED。

二、热敏电阻传感器的介绍

一个DO输出口,输出数字量,根据外界的温度是否超过传感器的阈值,输出0或1;一个AO口,输出模拟量。温度的检测要通过模拟量转换而来。

三、代码实现

要使得单片机读到的模拟量转换成温度需要经过以下步骤:1、读取的数值转电压;2、电压转电阻、3、根据公式计算实际的温度。

1、ADC读取。ADC怎么读取可以看之前的读取光敏电阻的文章,过程类似,就是引脚不一样。代码如下。

  1. //初始化ADC
  2. //这里我们仅以规则通道为例
  3. //我们默认将开启通道0~3
  4. void temp_Adc_Init(void)
  5. {
  6. ADC_InitTypeDef ADC_InitStructure;
  7. GPIO_InitTypeDef GPIO_InitStructure;
  8. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE ); //使能ADC1通道时钟
  9. RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
  10. //PA1 作为模拟通道输入引脚
  11. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
  13. GPIO_Init(GPIOA, &GPIO_InitStructure);
  14. ADC_DeInit(ADC1); //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
  15. ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
  16. ADC_InitStructure.ADC_ScanConvMode = DISABLE; //模数转换工作在单通道模式
  17. ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //模数转换工作在单次转换模式
  18. ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
  19. ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
  20. ADC_InitStructure.ADC_NbrOfChannel = 6; //顺序进行规则转换的ADC通道的数目
  21. ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
  22. ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
  23. ADC_ResetCalibration(ADC1); //使能复位校准
  24. while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
  25. ADC_StartCalibration(ADC1); //开启AD校准
  26. while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
  27. ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
  28. }
  29. //获得ADC值
  30. //ch:通道值 0~3
  31. u16 temp_Get_Adc(u8 ch)
  32. {
  33. //设置指定ADC的规则组通道,一个序列,采样时间
  34. ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
  35. ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
  36. while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束
  37. return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
  38. }
  39. u16 temp_Get_Adc_Average(u8 ch,u8 times)
  40. {
  41. u32 temp_val=0;
  42. u8 t;
  43. for(t=0;t<times;t++)
  44. {
  45. temp_val+=temp_Get_Adc(ch);
  46. Delay_ms(5);
  47. }
  48. return temp_val/times;
  49. }

2、采样值转电压、求电阻

求电压,我用的STM32F103C8T6,采用12位ADC采样,所以采样的最大值也就是2^12=4096,而单片机的电压是3.3v,所以读到的电压 = 读取的采样值/4096 * 3.3V。

求电阻,如图

 vcc = 3.3V,  热敏电阻的电压在上面求了,比值算一下就知道热敏电阻当前的阻值了

代码如下

  1. //模拟量转电阻
  2. float temp_Get_R(u16 adct)
  3. {
  4. //单片机3.3v 供电 ==3v,先求出电压
  5. float v1 = (float)(adct*3.3)/4096;//ntc上的电压
  6. float v2 = 3.3 - v1;
  7. float r = (v1/v2)*10;
  8. return r;
  9. }

3、温度计算

根据开尔文公式,可以直接得到当前的开尔文温度Tn公式如下:B=(lnR25 - lnRntc)/(1/T25 - 1/Tn)

其中单片机不能用math.h ,所以求对数的函数要自己实现。

参数介绍:

B,是一个系数,与热敏电阻本身系数有关(百度说这个由厂家提供),3435(问卖家即可)

R25是上拉电阻的阻值,

Rntc是上面求出来的热敏电阻的阻值

T25:25℃下的开尔文温度,也就是298.15K

Tn:此时计算得到的实际开尔文温度(要得到摄氏度 C=Tn-273.15 )

代码如下

在头问价中定义的一些参数

  1. #define T25 298.15 //电压转温度的公式的采用
  2. #define R25 10
  3. #define B 3435
  1. //实现ln(x) 的计算
  2. double myln(double a)
  3. {
  4. int N = 15;//取了前15+1项来估算
  5. int k,nk;
  6. double x,xx,y;
  7. x = (a-1)/(a+1);
  8. xx = x*x;
  9. nk = 2*N+1;
  10. y = 1.0/nk;
  11. for(k=N;k>0;k--)
  12. {
  13. nk = nk - 2;
  14. y = 1.0/nk+xx*y;
  15. }
  16. return 2.0*x*y;
  17. }
  18. float Get_Kelvin_Temperature(u16 t)
  19. {
  20. float N1,N2,N3,N4;
  21. float Rntc = temp_Get_R(t);
  22. N1 = (myln(R25)-myln(Rntc))/B;
  23. N2 = 1/T25 - N1;
  24. N3 = 1/N2;
  25. N4 = N3-273.15;//开尔文转摄氏度
  26. return N4;
  27. }

4、主函数

  1. float temp2 = Get_Kelvin_Temperature(adct);
  2. u16 t = (u16)temp2;
  3. OLED_ShowNum(1,7,t,4);//工作范围是20-80

四、实物情况

T是热敏电阻测的温度 12度

temperature 是之前用DHT11测的温度,12度 ,两者之间误差很小,说明ok了家人们。。。。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/天景科技苑/article/detail/855026
推荐阅读
相关标签
  

闽ICP备14008679号