在嵌入式系统设计中,温度监测是保障设备稳定运行、延长硬件寿命的关键功能。HC32F460 系列微控制器内置的温度传感器(OTS)模块,凭借无需外部硬件、集成度高、功耗低等优势,广泛应用于电机控制、工业监测、消费电子等场景。本文将从 OTS 模块的工作原理、硬件特性、驱动开发到实际应用,全面解析其技术细节与工程实践方法。
一、OTS 模块核心特性与工作原理
1.1 核心特性(基于 HC32F460 参考手册)
HC32F460 的 OTS 模块是一款基于半导体热敏效应的内置温度传感器,主要特性如下:
测量范围:典型覆盖 -40℃ ~ 125℃,满足工业级宽温需求;
时钟灵活性:支持 HRC(内部高速时钟)或 XTAL(外部晶振)作为工作时钟,适配不同系统时钟方案;
低功耗设计:支持采样完成后自动关闭(Auto-Off),降低待机功耗;
校准机制:通过斜率(K)和偏移(M)参数校准,可实现 ±1℃ 级测量精度;
硬件触发:支持通过 AOS(自动运行系统)模块实现外设联动触发采样,减少 CPU 干预。
1.2 工作原理
OTS 模块的核心是利用半导体器件的 温度 - 频率特性 实现温度测量,其原理框图如下(参考手册图 17-1):
时钟源选择:从 HRC 或 XTAL 中选择稳定时钟,为采样提供基准;
双路采样电路:通过 DR1(数据寄存器 1)和 DR2(数据寄存器 2)采集不同温度敏感元件的信号,抵消环境干扰;
误差补偿:ECR(误差补偿寄存器)存储出厂校准的误差系数,修正采样偏差;
温度计算:通过公式 T = K × [(1/DR1) - (1/DR2)] × ECR + M 计算实际温度,其中 K(斜率)和 M(偏移)需通过校准实验获取。
二、OTS 硬件配置与寄存器解析
2.1 外设时钟与地址映射
根据 HC32F460 参考手册 “存储器映射” 章节:
OTS 模块挂载于 APB4 总线,基地址为 0x4004_A400;
需通过 PWC_FCG3 寄存器(功能时钟控制 3)的 OTS 位使能时钟:PWC_FCG3 |= PWC_FCG3_OTSEN(位 12 置 1)。
2.2 关键寄存器说明
OTS 模块的配置与控制依赖 4 个核心寄存器,需结合参考手册 17.3 节理解其功能:
关键位配置示例:
选择 HRC 时钟:OTS_CTL |= OTS_CTL_OTSCK;
使能自动关闭:OTS_CTL |= OTS_CTL_TSSTP(采样完成后自动停止 OTS);
启动采样:OTS_CTL |= OTS_CTL_OTSST。
三、OTS 驱动开发实战(基于 LL 库)
HC32F460 提供 LL(底层库)驱动,开发者可基于 hc32_ll_ots.h/hc32_ll_ots.c 封装实用接口。以下为完整驱动实现,包含初始化、校准、温度读取功能。
3.1 驱动头文件(iots.h)
#ifndef __IOTS_H__
#define __IOTS_H__
#include "hc32_ll.h"
#include "hc32f460.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief OTS 初始化函数
* @param None
* @retval int32_t: 初始化结果
* - LL_OK: 初始化成功
* - LL_ERR_INVD_PARAM: 参数错误(内部断言触发,正常不会返回)
*/
int32_t BSP_OTS_Init(void);
/**
* @brief OTS 轮询读取温度(阻塞式)
* @param [out] pf32Temp: 温度存储地址(单位:℃)
* @param [in] u32Timeout: 超时时间(单位:循环次数,建议≥1000)
* @retval int32_t: 读取结果
* - LL_OK: 读取成功
* - LL_ERR_TIMEOUT: 超时失败
* - LL_ERR_INVD_PARAM: 输入指针为空
*/
int32_t BSP_OTS_ReadTempPolling(float32_t *pf32Temp, uint32_t u32Timeout);
/**
* @brief OTS 校准实验(获取K/M参数,需在已知温度环境下执行)
* @param [in] u8TempCond: 校准温度条件(参考 OTS_Param_Temp_Cond)
* - OTS_PARAM_TEMP_COND_TN40: -40℃
* - OTS_PARAM_TEMP_COND_T25: 25℃(常温推荐)
* - OTS_PARAM_TEMP_COND_T125: 125℃
* @param [out] pf32SlopeK: 校准后的斜率K(输出参数,用于初始化)
* @param [out] pf32OffsetM: 校准后的偏移M(输出参数,用于初始化)
* @param [in] u32Timeout: 超时时间(单位:循环次数,建议≥1000)
* @retval int32_t: 校准结果
* - LL_OK: 校准成功
* - LL_ERR_TIMEOUT: 超时失败
* - LL_ERR_INVD_PARAM: 输入指针为空或温度条件非法
*/
int32_t BSP_OTS_Calibrate(uint8_t u8TempCond, float32_t *pf32SlopeK, float32_t *pf32OffsetM, uint32_t u32Timeout);
#ifdef __cplusplus
}
#endif
#endif /* __IOTS_H__ */
3.2 驱动源文件(iots.c)
#include "iots.h"
/**
* @brief OTS 硬件依赖初始化(时钟使能)
* @NOTE HC32F460 的 OTS 挂载在 CM_OTS 外设,需先使能其时钟
* @param None
* @retval None
*/
static void BSP_OTS_HwInit(void)
{
/* 1. 使能 OTS 外设时钟(CM_OTS 时钟由 PCLK0 提供,需先确保 PCLK0 使能) */
FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_OTS, ENABLE);
/* 2. (可选)若使用 XTAL 作为 OTS 时钟,需先初始化 XTAL 并确保其稳定 */
// 示例:若选择 OTS_CLK_XTAL,需先初始化 XTAL(根据实际硬件配置,如 8MHz)
// stc_clk_xtal_init_t stcXtalInit = {0};
// stcXtalInit.u8XtalState = CLK_XTAL_ON;
// stcXtalInit.u8XtalMode = CLK_XTAL_MODE_OSC;
// stcXtalInit.u8XtalDrv = CLK_XTAL_DRV_LOW;
// CLK_XtalInit(&stcXtalInit);
// while (CLK_GetXtalSta() != CLK_XTAL_STA_STB) { /* 等待 XTAL 稳定 */ }
}
/**
* @brief OTS 初始化(调用 LL 库接口,配置时钟、自动关闭、校准参数)
* @param None
* @retval int32_t: 初始化结果
*/
int32_t BSP_OTS_Init(void)
{
int32_t i32Ret = LL_ERR_INVD_PARAM;
stc_ots_init_t stcOTSInit = {0};
/* 1. 硬件初始化(时钟使能) */
BSP_OTS_HwInit();
/* 2. 初始化 OTS 配置结构体(默认参数,可根据需求修改) */
i32Ret = OTS_StructInit(&stcOTSInit);
if (i32Ret != LL_OK)
{
return i32Ret;
}
/* 3. 自定义 OTS 配置(根据实际需求调整) */
stcOTSInit.u16ClockSrc = OTS_CLK_HRC; // 选择 HRC 作为 OTS 时钟(推荐,无需额外初始化)
// stcOTSInit.u16ClockSrc = OTS_CLK_XTAL; // 若选择 XTAL,需先完成 XTAL 初始化(见 BSP_OTS_HwInit 注释)
stcOTSInit.u16AutoOffEn = OTS_AUTO_OFF_ENABLE; // 采样完成后自动关闭 OTS(降低功耗)
/* 4. 校准参数配置 */
// 使用校准后的 K/M 参数(精度高,需先执行 BSP_OTS_Calibrate 获得)
stcOTSInit.f32SlopeK = 3005.26F; // 斜率(根据芯片特性微调)
stcOTSInit.f32OffsetM = 27.93F; // 偏移(修正量)
/* 5. 调用 LL 库初始化 OTS */
i32Ret = OTS_Init(&stcOTSInit);
return i32Ret;
}
/**
* @brief 轮询读取温度(阻塞式,基于 LL_OTS_Polling 封装)
* @param [out] pf32Temp: 温度存储地址
* @param [in] u32Timeout: 超时时间 建议不小于10000
* @retval int32_t: 读取结果
*/
int32_t BSP_OTS_ReadTempPolling(float32_t *pf32Temp, uint32_t u32Timeout)
{
int32_t i32Ret = LL_ERR_INVD_PARAM;
/* 1. 参数合法性检查 */
if (pf32Temp == NULL)
{
return LL_ERR_INVD_PARAM;
}
/* 2. 调用 LL 库轮询读取温度 */
i32Ret = OTS_Polling(pf32Temp, u32Timeout);
if (i32Ret == LL_OK)
{
/* 可选:温度范围过滤(HC32F460 OTS 典型量程:-40℃ ~ 125℃) */
if (*pf32Temp < -50.0F || *pf32Temp > 135.0F)
{
i32Ret = LL_ERR_INVD_MD; // 超出合理范围,返回数据非法
}
}
return i32Ret;
}
/**
* @brief OTS 校准实验(获取 K/M 参数,需在已知温度环境下执行)
* @note 原理:在 2 个已知温度点(如 25℃ 和 125℃)执行校准,计算斜率 K 和偏移 M
* @param [in] u8TempCond: 校准温度条件
* @param [out] pf32SlopeK: 斜率 K
* @param [out] pf32OffsetM: 偏移 M
* @param [in] u32Timeout: 超时时间
* @retval int32_t: 校准结果
*/
int32_t BSP_OTS_Calibrate(uint8_t u8TempCond, float32_t *pf32SlopeK, float32_t *pf32OffsetM, uint32_t u32Timeout)
{
int32_t i32Ret = LL_ERR_INVD_PARAM;
static float32_t s_f32A1 = 0.0F, s_f32A2 = 0.0F; // 存储两个温度点的 A 参数
static uint8_t s_u8CalibCnt = 0; // 校准计数(0:未校准,1:第一个点,2:完成)
uint16_t u16Dr1 = 0, u16Dr2 = 0, u16Ecr = 0;
/* 1. 参数合法性检查 */
if ((pf32SlopeK == NULL) || (pf32OffsetM == NULL))
{
return LL_ERR_INVD_PARAM;
}
if ((u8TempCond != OTS_PARAM_TEMP_COND_TN40) &&
(u8TempCond != OTS_PARAM_TEMP_COND_T25) &&
(u8TempCond != OTS_PARAM_TEMP_COND_T125))
{
return LL_ERR_INVD_PARAM;
}
/* 2. 执行校准实验(获取当前温度点的 A 参数) */
i32Ret = OTS_ScalingExperiment(&u16Dr1, &u16Dr2, &u16Ecr, (s_u8CalibCnt == 0) ? &s_f32A1 : &s_f32A2, u32Timeout);
if (i32Ret != LL_OK)
{
return i32Ret;
}
/* 3. 累计校准计数,若完成 2 个点则计算 K/M */
s_u8CalibCnt++;
if (s_u8CalibCnt >= 2)
{
// 示例:假设两个校准点为 25℃(A1)和 125℃(A2),计算 K = (T2-T1)/(A2-A1),M = T1 - K*A1
float32_t f32T1 = 25.0F, f32T2 = 125.0F; // 需与实际校准温度对应
if (s_f32A2 != s_f32A1)
{ // 避免除以零
*pf32SlopeK = (f32T2 - f32T1) / (s_f32A2 - s_f32A1);
*pf32OffsetM = f32T1 - (*pf32SlopeK) * s_f32A1;
}
else
{
i32Ret = LL_ERR_INVD_MD; // 校准数据异常
}
s_u8CalibCnt = 0; // 重置校准计数,支持下次校准
}
else
{
i32Ret = LL_OK; // 第一个点校准完成,等待第二个点
}
return i32Ret;
}
四、总结
HC32F460 的 OTS 模块为嵌入式系统提供了低成本、高集成度的温度监测方案。通过理解其半导体热敏原理、寄存器配置逻辑,结合 LL 库封装驱动,可快速实现温度采集功能。在实际应用中,需根据精度需求执行校准、优化采样策略,并关注低功耗设计,以充分发挥 OTS 模块的性能优势。如需进一步深入,可参考 HC32F460 参考手册第 17 章 “温度传感器(OTS)”,获取更详细的硬件时序与寄存器细节。
————————————————
版权声明:本文为CSDN博主「时光呀时光慢慢走」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/XdaDC/article/details/150773165
|
|