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

库函数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.xdnf.cn/news/17449.html

相关文章:

  • Seata分布式事务环境搭建
  • linux-LVM 逻辑卷管理
  • Uniworld-V1、X-Omni论文解读
  • 数据结构(二叉树)
  • 【ee类保研面试】其他类---计算机网络
  • 机器学习之支持向量机(原理)
  • [激光原理与应用-185]:光学器件 - BBO、LBO、CLBO晶体的全面比较
  • VSCode 禁用更新检查的方法
  • 实现一个进程池(精讲)
  • 大模型量化上溢及下溢解析
  • 常见数据结构介绍(顺序表,单链表,双链表,单向循环链表,双向循环链表、内核链表、栈、队列、二叉树)
  • LeetCode 刷题【34. 在排序数组中查找元素的第一个和最后一个位置、35. 搜索插入位置】
  • Redis7集群搭建与原理分析
  • 基于Web的交互式坐标系变换矩阵计算工具
  • BGP综合实验练习作业
  • 使用OAK相机实现智能物料检测与ABB机械臂抓取
  • 从零构建TransformerP2-新闻分类Demo
  • Langchain入门:构建一个基于SQL数据的问答系统
  • 後端開發技術教學(三) 表單提交、數據處理
  • 汽车零部件深孔加工质控升级:新启航激光频率梳 3D 测量解决传统光学扫描遮挡
  • 应急响应流程
  • ADB 命令执行模块开发:双模式(普通模式Shell交互模式)实现、线程安全与资源管理优化
  • Nextcloud容器化部署新范式:Docker与Cpolar如何重塑私有云远程访问能力
  • 为什么输入 URL 后会显示页面?HTTP 协议的 “幕后操作”
  • docker缓存目录转移设置和生效过程
  • WPF 双击行为实现详解:DoubleClickBehavior 源码分析与实战指南
  • linux信号量和日志
  • 杂谈 001 · VScode / Copilot 25.08 更新
  • 【系统编程】进程初识
  • 用JOIN替代子查询的查询性能优化