当前位置: 首页 > 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.dtcms.com/a/322003.html

相关文章:

  • react的form.resetFields()
  • cuda编程之内核执行配置参数
  • 智慧交通场景下 mAP↑28%:陌讯多模态融合算法实战解析
  • Linux入门到精通,第二周自我总结
  • 书生浦语第五期-L1G3-LMDeploy 课程
  • 配电线路故障定位在线监测装置的技术解析与应用价值
  • C语言编译流程讲解
  • 第七篇:动画基础:requestAnimationFrame循环
  • 解决多线程安全性问题的方法
  • 可编辑51页PPT | 某鞋服品牌集团数字化转型项目建议书
  • 相机Camera日志实例分析之十:相机Camx【萌拍调节AE/AF拍照】单帧流程日志详解
  • 基于MATLAB实现的毫米波大规模MIMO系统中继混合预编码设计
  • [windows]torchsig 1.1.0 gr-spectrumdetect模块安装
  • LeetCode 刷题【34. 在排序数组中查找元素的第一个和最后一个位置、35. 搜索插入位置】
  • 哈希法(Java)
  • 【数据结构】排序(sort) -- 计数排序
  • wstool和git submodule优劣势对比
  • select ... for update阻塞
  • 【感知机】感知机(perceptron)学习算法例题及详解
  • 任务管理器如何查看详细的命令行和路径?
  • 安科瑞能源管理系统在某新材料公司光储充一体化项目上的应用
  • 【C++空指针革命】nullptr:告别NULL的终极解决方案与底层实现剖析
  • 在超算中心,除了立式机柜(rack-mounted)还有哪些形式?
  • 官方Windows系统部署下载工具实践指南
  • 遥测自跟踪天线系统组成、特点、功能、工作流程
  • 【普通地质学】地质年代与地层系统
  • 无人机SN模块运行与功能详解
  • Vibe coding现在能用于生产吗?
  • 什么是0.8米分辨率卫星影像数据?
  • C++ WonderTrader源码分析之自旋锁实现