当前位置: 首页 > news >正文

库函数NTC采样温度的方法(STC8)

STC8的NTC采样方法

硬件连接

  • NTC电阻一端接VCC,另一端接GND,中间串联一个固定电阻(如10kΩ),连接至ADC输入引脚。
  • 确保ADC参考电压稳定,通常使用VCC或外部基准电压源。

ADC配置

  • 初始化ADC模块,选择对应的ADC通道和时钟分频。
  • 配置ADC结果格式(左对齐或右对齐),STC8通常支持10位或12位分辨率。
  • 启用ADC并等待稳定,可能需短暂延时。

温度计算

  • 读取ADC原始值,计算NTC电阻值:
    [
    R_{ntc} = \frac{R_{fixed} \times ADC_{value}}{ADC_{max} - ADC_{value}}
    ]
    其中 ( R_{fixed} ) 为固定电阻值,( ADC_{max} ) 为ADC最大值(如1023或4095)。
  • 使用Steinhart-Hart公式转换电阻值为温度:
    [
    \frac{1}{T} = A + B \cdot \ln(R_{ntc}) + C \cdot (\ln(R_{ntc}))^3
    ]
    参数A、B、C需根据NTC规格书提供的数据拟合。

代码示例

#include    "GPIO.h"
#include	"Delay.h"
#include 	"UART.h"	// 串口配置 UART_Configuration
#include 	"NVIC.h"	// 中断初始化NVIC_UART1_Init
#include 	"Switch.h"  // 引脚切换 UART1_SW_P30_P31
#include    "ADC.h"
#include	<math.h>	// log()// 定义一个结构体来存储NTC热敏电阻的参数
typedef struct {double r_naught;  // 参考电阻值 R25 (Ohm)double b_25_50;   // B值常数,适用于较低温范围 (e.g., < 50°C)double b_25_85;   // B值常数,适用于较高温范围 (e.g., >= 50°C)
} NtcParameters;/*** @brief 根据NTC热敏电阻的阻值计算温度(摄氏度),支持分段B值以提高精度。** @param resistance_ohm  实际测量到的电阻值 (Ohm)。* @param params          一个指向NtcParameters结构体的指针,包含热敏电阻的所有参数。* @return                计算出温度,单位为摄氏度 (°C)。*/
double ntc_to_celsius_segmented(double resistance_ohm, const NtcParameters* params) {const double T_NAUGHT_K = 298.15; // 参考温度 T0 (25°C) 的开尔文值double b_selected;                // 将被选择用于最终计算的B值double temp_kelvin_guess;double temp_celsius_guess;double temp_kelvin_final;// --- 步骤1: 使用默认的B值 (b_25_50) 计算初步温度 ---temp_kelvin_guess = 1.0 / ( (log(resistance_ohm / params->r_naught) / params->b_25_50) + (1.0 / T_NAUGHT_K) );temp_celsius_guess = temp_kelvin_guess - 273.15;// --- 步骤2: 根据初步温度选择更合适的B值 ---// 我们以50°C作为分段点if (temp_celsius_guess >= 50.0) {b_selected = params->b_25_85; // 温度较高,使用高温范围的B值} else {b_selected = params->b_25_50; // 温度较低,使用低温范围的B值}// --- 步骤3: 使用选定的B值进行最终的精确计算 ---temp_kelvin_final = 1.0 / ( (log(resistance_ohm / params->r_naught) / b_selected) + (1.0 / T_NAUGHT_K) );return temp_kelvin_final - 273.15;
}void GPIO_config() { GPIO_InitTypeDef info;// ===== UART1  P30  P31  准双向info.Mode = GPIO_PullUp; 				// 准双向info.Pin = GPIO_Pin_0 | GPIO_Pin_1;   	// 引脚GPIO_Inilize(GPIO_P3, &info);// P04 高阻输入info.Mode = GPIO_HighZ;     // 高阻输入info.Pin = GPIO_Pin_4;   	// 引脚GPIO_Inilize(GPIO_P0, &info);
}// 串口配置函数的定义
void UART_config(void) {// >>> 记得添加 NVIC.c, UART.c, UART_Isr.c <<<COMx_InitDefine		COMx_InitStructure;					//结构定义COMx_InitStructure.UART_Mode      = UART_8bit_BRTx;	//模式, UART_ShiftRight,UART_8bit_BRTx,UART_9bit,UART_9bit_BRTxCOMx_InitStructure.UART_BRT_Use   = BRT_Timer1;			//选择波特率发生器, BRT_Timer1, BRT_Timer2 (注意: 串口2固定使用BRT_Timer2)COMx_InitStructure.UART_BaudRate  = 115200ul;			//波特率, 一般 110 ~ 115200COMx_InitStructure.UART_RxEnable  = ENABLE;				//接收允许,   ENABLE或DISABLECOMx_InitStructure.BaudRateDouble = DISABLE;			//波特率加倍, ENABLE或DISABLEUART_Configuration(UART1, &COMx_InitStructure);		//初始化串口1 UART1,UART2,UART3,UART4NVIC_UART1_Init(ENABLE,Priority_1);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3UART1_SW(UART1_SW_P30_P31);		// 引脚选择, UART1_SW_P30_P31,UART1_SW_P36_P37,UART1_SW_P16_P17,UART1_SW_P43_P44
}/******************* AD配置函数 *******************/
void	ADC_config(void)
{ADC_InitTypeDef		ADC_InitStructure;		//结构定义ADC_InitStructure.ADC_SMPduty   = 31;		//ADC 模拟信号采样时间控制, 0~31(注意: SMPDUTY 一定不能设置小于 10)ADC_InitStructure.ADC_CsSetup   = 0;		//ADC 通道选择时间控制 0(默认),1ADC_InitStructure.ADC_CsHold    = 1;		//ADC 通道选择保持时间控制 0,1(默认),2,3ADC_InitStructure.ADC_Speed     = ADC_SPEED_2X1T;		//设置 ADC 工作时钟频率	ADC_SPEED_2X1T~ADC_SPEED_2X16TADC_InitStructure.ADC_AdjResult = ADC_RIGHT_JUSTIFIED;	//ADC结果调整,	ADC_LEFT_JUSTIFIED,ADC_RIGHT_JUSTIFIEDADC_Inilize(&ADC_InitStructure);		//初始化ADC_PowerControl(ENABLE);				//ADC电源开关, ENABLE或DISABLENVIC_ADC_Init(DISABLE,Priority_0);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}void main() {u16 adc;float vol; // 电压float r;  // 电阻double temp; // 温度// R25 = 10kΩ// B-Constant (25-50°C) = 3950// B-Constant (25-85°C) = 3950 // 这个如果没有,和(25-50°C)值一样NtcParameters params = {10000.0,3950.0,3950.0, // 这个如果没有,和(25-50°C)值一样};EA = 1; // 使能中断总开关GPIO_config(); // GPIO配置UART_config(); // 串口配置ADC_config();  // ADC配置while (1){// 读取ADC采样值,是采样值,不是电压值,但和电压有关系// 参数不能乱写,原理图 芯片手册 P04 对应的通道是 12 通道adc = Get_ADCResult(ADC_CH12);// 转换为电压vol = adc * 2.5 / 4095;// 计算出电阻r = vol * 10 / (3.3 - vol);// 通过查表得到温度temp = ntc_to_celsius_segmented(r * 1000.0, &params);printf("r = %.2f, temp = %.1f°\n", r, temp);// 处理的太快delay_ms(250);delay_ms(250);}
}

注意事项

  • 校准ADC参考电压,避免电源波动影响精度。
  • 使用查表法替代复杂公式计算,提升实时性。
  • 添加软件滤波(如滑动平均)减少噪声干扰。
  • NTC的B值需与实际型号匹配,不同型号参数差异较大。
http://www.lryc.cn/news/614077.html

相关文章:

  • 大模型——部署体验gpt-oss-20b
  • 项目一系列-第3章 若依框架入门
  • SEABORN库函数(第十八节课内容总结)
  • 睿抗开发者大赛国赛-24
  • Java基础之匿名内部类与lambda表达式
  • DAY 39 图像数据与显存
  • 缓存投毒进阶 -- justctf 2025 Busy Traffic
  • docker缓存目录转移设置和生效过程
  • 总结运行CRMEB标准版(uniapp)微信小程序的问题
  • 站在Vue的角度,对比鸿蒙开发中的数据渲染二
  • 【ESP32-menuconfig(1) -- Build Type及Bootloader config】
  • 跨平台音乐管理新方案:Melody如何实现一站式音源整合
  • 76 模块编程之高精度定时器
  • 数据仓库知识
  • PBootcms网站模板伪静态配置教程
  • C++信息学奥赛一本通-第一部分-基础一-第2章-第5节
  • linux信号量和日志
  • 户外广告牌识别准确率↑32%:陌讯多模态融合算法实战解析
  • 【JMeter】调试取样器的使用
  • 易美教育荣膺“腾讯年度影响力国际教育品牌”双奖加冕,见证中国国际教育力量的崛起
  • 《论文阅读》传统CoT方法和提出的CoT Prompting的区分
  • 有鹿机器人:如何用±2cm精度重塑行业标准?
  • 综合项目记录:自动化备份全网服务器数据平台
  • excel 导出
  • Linux Shell:Nano 编辑器备忘
  • 影刀 —— 练习 —— 读取Excel的AB两列组成字典
  • flink闲谈
  • 锂电池保护板测试仪:守护电池安全的核心工具|深圳鑫达能
  • 基于Vue.js和Golang构建高效在线客服系统:前端实现与后端交互详解
  • 碰一碰NFC开发写好评php语言源码