[APM32F0] APM32F003 NTC测温

[复制链接]
1066|0
 楼主| JunKook 发表于 2023-2-19 18:07 | 显示全部楼层 |阅读模式
极海APM32F003系列MCU在满足高性能与稳定性的同时,也具有小体积、小封装,低成本等优势,助力客户以更经济的成本获取更加复杂、创新的产品功能。由于其主要针对一些对成本比较敏感的应用,外设资源以常用为主,所以APM32F003系列MCU并没有集成内置的温度传感器的功能。在众多应用领域中,有时候也会遇到一些应用场景需要MCU的资源并不多,封装尽可能小,但是需要检测MCU工作环境的温度。这样的应用如果选择一颗集成温度传感器的MCU,势必会增加应用成本,并且造成资源浪费。此时,如果一颗低成本、高性能的MCU,再加一个热敏电阻测温,能同时满足低成本和测温的需求,这不妨是最佳的选择。
下面就给大家介绍一下使用APM32F003F6P6和一个热敏电阻实现测温的应用。
NTC介绍
NTC是负温度系数的简写,全称是Negative temperature coefficient,是一种随温度上升时,电阻值呈指数关系减小的热敏电阻,常用作温度传感器。这里有一个式子表示负温度系数的电阻值:
RT=R0*exp(B (1/T-1/T0))

RT为周围温度为T (K) 时的电阻值,R0是周围温度为T0 (K) 时的电阻值,注意这里的温度是开尔文温度。B为常数,它也是材料常数,一般在25摄氏度下测得。

温度测量电路
如下图所示,温度测量常用电阻串联分压,ADC采样的方式进行。本例中APM32F6P6的供电电压VCC为5V,为了提高测温精度,串联电阻采用了15KΩ和4.3KΩ。
ADC.png
温度转换
通过ADC得到采样值后,如果转换得到温度呢?这里有两种计算方法,一种是公式法,一种是查表法,下面将一一介绍。
  • 公式法
首先第一步是找到自己的热敏电阻的数据手册,查找B值和25℃的电阻值,本例中使用的热敏电阻型号是SDNT2012X473F4150FTF,25℃的阻值47KΩ,B值为4150,其温度-阻值特性曲线如下图所示。
2.png
然后我们在程序中定义好这些参数:
  1. float ntc_series_resistance = 15000.0; //NTC的串联电阻
  2. float ntc_b_value = 4150.0;            //B值
  3. float ntc_r25 = 47000.0;               //25℃时的电阻
  4. float kelvins_zero = 273.15;           //绝对零度
  5. uint16_t system_power_voltage = 5000;  //系统参考电压是5V
  6. float T25 = 298.15;                    //25 = kelvins_zero + 25
这里的计算逻辑就是先通过ADC采样得到NTC和4.3KΩ的电压推算出串联电阻15KΩ的分压,然后再计算出线路电流,再计通过欧姆定律从计算出热敏电阻和4.3KΩ之和的阻值,减去4.3KΩ后得到热敏电阻的阻值,最后通过公式计算出温度。务必注意,这些计算,需要引入math.h
  1. uint16_t adc_value;
  2.         uint32_t ntc_voltage;
  3.         float ntc_current;
  4.         float ntc_resistance;
  5.         float temperature;
  6.        
  7.         adc_value = Get_Adc(); //获取ADC采样值
  8.         ntc_voltage = adc_value * 5000 / 4095; //采样值转换为电压(mV)
  9.         ntc_current = ((system_power_voltage- ntc_voltage) / ntc_series_resistance); //计算NTC的电流(mA)       
  10.         ntc_resistance = (ntc_voltage / ntc_current) - 4300; //计算NTC电阻值(Ω)
  11.         temperature = (ntc_b_value * T25) / (T25 * (log(ntc_resistance) - log(ntc_r25)) + ntc_b_value);
  12.         temperature -= kelvins_zero; //计算最终温度
  13.        
  14.         return temperature;

  • 查表发
一般而言,厂家会提供NTC电阻的温度与电阻表,如下图所示,基于这个表,我们只需要计算出当前热敏电阻的阻值Rt,然后查照此表,得到最接近的温度值即可。




R-T.png
程序中我们使用二分法查表,程序实现如下:
  1. /*!
  2. * [url=home.php?mod=space&uid=247401]@brief[/url]       Find_Table 二分查找算法->查温度表
  3. *                               
  4. * @param       表地址、表长度、要查找的数据  
  5. *
  6. * @retval      数据在表中的位置  
  7. *
  8. * [url=home.php?mod=space&uid=536309]@NOTE[/url]        查找数据在表中对应的位置 表中数据从大到小
  9. */
  10. uint8_t Find_Table(float *table, uint8_t table_len, float data)
  11. {
  12.         uint8_t st, ed, m;
  13.         uint8_t i = 0;

  14.         st = 0;
  15.         ed = table_len - 1;

  16.         if (data >= table[st]) return st;
  17.         else if (data <= table[ed]) return ed;

  18.         while (st < ed) {
  19.                 m = (st + ed) / 2;

  20.                 if (data == table[m] ) break;
  21.                 if (data < table[m] && data > table[m+1]) {
  22.                         if ((table[m] - data) > (data - table[m+1])) {
  23.                                 m = m + 1;
  24.                         }
  25.                         break;
  26.                 }

  27.                 if (data > table[m]) {
  28.                         ed = m;
  29.                 } else {
  30.                         st = m;
  31.                 }

  32.                 if (i++ > table_len) break;
  33.         }

  34.         if (st > ed ) return 0;

  35.         return m;
  36. }
首先我们需要通过ADC采样值计算后得到热敏电阻值,然后通过二分法查表函数找到当前热敏电阻值在表中的位置,从而得到对应的温度值,程序实现如下:
  1. int8_t Get_Temperature_Value(void)
  2. {
  3.         uint16_t any_value;
  4.         uint16_t ntc_voltage;
  5.         float ntc_res;
  6.         int8_t temp;
  7.        
  8.         any_value = Get_Adc(); //获取ADC采样值
  9.         ntc_voltage = any_value * 5000 / 4095; //采样值转换为电压(mV)
  10.         ntc_res = ((ntc_voltage * 15000) / (5000 - ntc_voltage)) - 4300; //计算NTC电阻值(Ω)
  11.         ntc_res = ntc_res / 1000;//计算NTC电阻值(KΩ)
  12.        
  13.         any_value = Find_Table(table_res, 152, ntc_res); //二分法查表
  14.         //通过热敏电阻在表中的位置得到对应的温度值
  15.         if (any_value < 151) {
  16.                 temp = any_value - 30;
  17.         } else {
  18.                 temp = 125;
  19.         }
  20.        
  21.         return temp;
  22. }
以上就是通过超低成本MCU APM32F003F6P6和热敏电阻实现温度测量的例程分享,欢迎大家评论区讨论交流。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:极海半导体
简介:珠海极海半导体有限公司是一家致力于开发工业级/车规级微控制器、模拟与混合信号IC及系统级芯片的集成电路设计型企业。极海团队拥有20年集成电路设计经验和嵌入式系统开发能力,可为客户提供核心可靠的芯片产品及方案,实现准确感应、安全传输和实时控制,助力客户在智慧家居、高端消费电子、工业控制、汽车电子、智慧能源以及通信设施等领域的拓展创新。

15

主题

55

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部