手把手教你用STM32 HAL库驱动TMP117温度传感器(附完整代码)
2026/6/11 22:33:53 网站建设 项目流程

STM32 HAL库驱动TMP117高精度温度传感器实战指南

在工业控制、医疗设备和消费电子等领域,温度测量往往是系统设计中最基础却最关键的环节之一。德州仪器(TI)推出的TMP117数字温度传感器以其±0.1°C的测量精度和-40°C至+125°C的宽工作范围,成为替代传统热敏电阻和热电偶的理想选择。本文将基于STM32CubeMX和HAL库,从零开始构建完整的TMP117驱动方案,帮助开发者快速实现高精度温度监测系统。

1. 硬件准备与CubeMX配置

TMP117采用标准I2C接口通信,最高支持1MHz的快速模式Plus(Fm+)。在开始编码前,需要完成以下硬件连接:

  • 引脚连接
    • TMP117的SDA接STM32的PB7(I2C1_SDA)
    • TMP117的SCL接STM32的PB6(I2C1_SCL)
    • ADD0引脚接地(默认I2C地址0x48)

打开STM32CubeMX,按步骤配置I2C外设:

  1. 在"Pinout & Configuration"标签页启用I2C1
  2. 将PB6和PB7自动配置为I2C1_SCL和I2C1_SDA
  3. 在"I2C Mode and Configuration"中设置参数:
    Timing = 0x00707CBB // 100kHz标准模式 No Stretch Mode = Disable

提示:对于长距离布线或干扰环境,建议降低I2C时钟频率至50kHz以下,并启用时钟延展(Clock Stretching)。

生成代码前,务必在"Project Manager"标签页勾选"Generate peripheral initialization as a pair of .c/.h files",这将方便后续的驱动代码管理。

2. HAL库驱动实现

2.1 基础通信函数封装

创建tmp117.h头文件定义常用寄存器地址:

#define TMP117_I2C_ADDR 0x48 << 1 // HAL库要求左移1位 #define TMP117_REG_TEMP 0x00 #define TMP117_REG_CONFIG 0x01 #define TMP117_REG_HIGH_LIMIT 0x02 #define TMP117_REG_LOW_LIMIT 0x03

实现温度读取函数时,需要注意TMP117的数据格式转换:

float TMP117_ReadTemperature(I2C_HandleTypeDef *hi2c) { uint8_t buf[2]; int16_t rawTemp; // 读取温度寄存器 HAL_I2C_Mem_Read(hi2c, TMP117_I2C_ADDR, TMP117_REG_TEMP, I2C_MEMADD_SIZE_8BIT, buf, 2, HAL_MAX_DELAY); // 组合两个字节并转换为温度值 rawTemp = (buf[0] << 8) | buf[1]; return rawTemp * 0.0078125f; // LSB = 7.8125m°C }

2.2 高级配置功能

TMP117提供了丰富的配置选项,通过配置寄存器(0x01)可以设置:

位域参数可选值说明
[15:13]转换周期000-111从15.5ms到8s共8档
[10:9]平均模式00-11关闭/8次/32次/64次平均
[8]数据就绪中断0/1启用温度转换完成中断
[7:5]警报模式000-111设置高低限触发条件

配置示例代码:

void TMP117_Config(I2C_HandleTypeDef *hi2c, uint16_t settings) { uint8_t buf[2]; buf[0] = settings >> 8; // 高字节 buf[1] = settings & 0xFF;// 低字节 HAL_I2C_Mem_Write(hi2c, TMP117_I2C_ADDR, TMP117_REG_CONFIG, I2C_MEMADD_SIZE_8BIT, buf, 2, HAL_MAX_DELAY); }

典型配置调用(设置1Hz采样+64次平均):

TMP117_Config(&hi2c1, 0x0220);

3. 抗干扰设计与性能优化

3.1 I2C通信可靠性增强

工业环境中I2C总线易受干扰,可通过以下措施提升稳定性:

  • 硬件层面

    • 在SCL和SDA线上串联100Ω电阻
    • 添加4.7kΩ上拉电阻至3.3V
    • 使用双绞线或屏蔽线缆
  • 软件层面

    HAL_StatusTypeDef Safe_I2C_Read(I2C_HandleTypeDef *hi2c, uint16_t devAddr, uint16_t memAddr, uint8_t *pData, uint16_t size) { HAL_StatusTypeDef status; uint8_t retry = 3; do { status = HAL_I2C_Mem_Read(hi2c, devAddr, memAddr, I2C_MEMADD_SIZE_8BIT, pData, size, 100); if(status == HAL_OK) break; HAL_Delay(1); } while(--retry); return status; }

3.2 温度数据滤波处理

对于需要高稳定读数的应用,可采用滑动窗口滤波:

#define FILTER_WINDOW_SIZE 8 typedef struct { float buffer[FILTER_WINDOW_SIZE]; uint8_t index; float sum; } TempFilter; float FilterTemperature(TempFilter *filter, float newTemp) { filter->sum -= filter->buffer[filter->index]; filter->buffer[filter->index] = newTemp; filter->sum += newTemp; filter->index = (filter->index + 1) % FILTER_WINDOW_SIZE; return filter->sum / FILTER_WINDOW_SIZE; }

初始化滤波器并使用的示例:

TempFilter tempFilter = {0}; float currentTemp = FilterTemperature(&tempFilter, TMP117_ReadTemperature(&hi2c1));

4. 实战案例:恒温控制系统

结合PID算法实现一个简单的恒温控制演示:

4.1 PID控制器实现

typedef struct { float Kp, Ki, Kd; float integral; float prevError; } PIDController; float PID_Update(PIDController *pid, float setpoint, float input, float dt) { float error = setpoint - input; pid->integral += error * dt; float derivative = (error - pid->prevError) / dt; pid->prevError = error; return pid->Kp * error + pid->Ki * pid->integral + pid->Kd * derivative; }

4.2 系统集成

主控制循环代码框架:

void TemperatureControlLoop(void) { PIDController pid = { .Kp = 2.0f, .Ki = 0.5f, .Kd = 1.0f }; TempFilter filter = {0}; float setpoint = 37.0f; // 目标温度37°C while(1) { float rawTemp = TMP117_ReadTemperature(&hi2c1); float filtered = FilterTemperature(&filter, rawTemp); float output = PID_Update(&pid, setpoint, filtered, 0.1f); // 输出控制加热器(PWM占空比0-100%) uint8_t duty = (uint8_t)constrain(output, 0, 100); SetHeaterDuty(duty); HAL_Delay(100); // 100ms控制周期 } }

在实际项目中,我们还需要添加温度超限报警、安全保护等机制。TMP117自带的高低温度限制寄存器可以硬件触发警报,减轻MCU的轮询负担:

// 设置温度上限报警(40°C) void SetTempAlarms(I2C_HandleTypeDef *hi2c) { uint8_t highLimit[2]; int16_t tempHigh = (int16_t)(40.0f / 0.0078125f); highLimit[0] = tempHigh >> 8; highLimit[1] = tempHigh & 0xFF; HAL_I2C_Mem_Write(hi2c, TMP117_I2C_ADDR, TMP117_REG_HIGH_LIMIT, I2C_MEMADD_SIZE_8BIT, highLimit, 2, HAL_MAX_DELAY); }

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询