4. 体温连续监测与异常报警
任务目标
在可穿戴设备上通过皮肤温度传感器(如Maxim MAX30205或TI TMP117)连续读取体温数据,当温度超过设定阈值(如38.0℃)时触发报警(LED点亮+蜂鸣器鸣响),并在串口输出报警信息。本案例使用STM32F103微控制器与I2C接口的TMP117传感器实现完整闭环。
硬件与依赖
- 主控:STM32F103C8T6(Blue Pill),I2C1:PB6(SCL)、PB7(SDA)
- 传感器:TMP117(I2C地址0x48),VCC接3.3V,GND接地
- 报警输出:PA1接LED(串联220Ω电阻),PA2接蜂鸣器(NPN三极管驱动)
- 软件:STM32CubeIDE或Keil MDK,使用标准外设库或HAL库均可
核心实现
以下代码实现完整的温度读取与报警逻辑。TMP117的寄存器0x00为温度结果寄存器,数据格式为16位有符号数,分辨率0.0078125℃/LSB。代码每500ms读取一次温度,连续3次超过阈值则触发报警并保持,直到温度回落至阈值以下0.5℃才解除。
// main.c 核心逻辑(使用HAL库)
#include "stm32f1xx_hal.h"
#define TMP117_ADDR 0x48 << 1
#define TMP117_TEMP_REG 0x00
#define ALARM_THRESHOLD 38.0f
#define HYSTERESIS 0.5f
#define SAMPLE_INTERVAL 500 // ms
I2C_HandleTypeDef hi2c1;
float current_temp = 0.0f;
uint8_t alarm_active = 0;
uint8_t over_count = 0;
// 读取TMP117温度(单位:℃)
float read_tmp117_temperature(void) {
uint8_t reg = TMP117_TEMP_REG;
uint8_t data[2] = {0};
int16_t raw;
float temp;
HAL_I2C_Master_Transmit(&hi2c1, TMP117_ADDR, ®, 1, 100);
HAL_I2C_Master_Receive(&hi2c1, TMP117_ADDR, data, 2, 100);
raw = (int16_t)((data[0] << 8) | data[1]);
temp = raw * 0.0078125f;
return temp;
}
// 报警控制
void set_alarm(uint8_t state) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, state ? GPIO_PIN_SET : GPIO_PIN_RESET); // LED
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, state ? GPIO_PIN_SET : GPIO_PIN_RESET); // 蜂鸣器
}
// 主循环中的温度监测与报警逻辑
void temperature_monitor_task(void) {
current_temp = read_tmp117_temperature();
if (!alarm_active) {
if (current_temp >= ALARM_THRESHOLD) {
over_count++;
if (over_count >= 3) { // 连续3次超阈值才报警,防抖动
alarm_active = 1;
set_alarm(1);
printf("ALARM: Temp=%.2f°C exceeded %.1f°C\r\n", current_temp, ALARM_THRESHOLD);
}
} else {
over_count = 0;
}
} else {
// 报警状态下,温度回落至阈值-迟滞值以下才解除
if (current_temp < (ALARM_THRESHOLD - HYSTERESIS)) {
alarm_active = 0;
over_count = 0;
set_alarm(0);
printf("ALARM CLEARED: Temp=%.2f°C\r\n", current_temp);
}
}
}
// 定时器回调(500ms周期)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM3) {
temperature_monitor_task();
}
}
int main(void) {
HAL_Init();
// ... 系统时钟配置(72MHz)、GPIO、I2C、TIM3初始化代码由CubeMX生成 ...
// 启动500ms定时器
HAL_TIM_Base_Start_IT(&htim3);
while (1) {
// 主循环可处理其他任务
}
}
运行与验证
- 使用STM32CubeMX配置I2C1(100kHz)、PA1/PA2为推挽输出、TIM3定时500ms中断,生成初始化代码后,将上述逻辑加入工程。
- 编译烧录后,打开串口助手(115200-8-N-1),观察温度输出。
- 验证步骤:
- 正常状态:用手触摸传感器使其升温至38℃以上并保持,观察LED与蜂鸣器应在约1.5秒(3次采样)内激活,串口打印
ALARM信息。 - 恢复状态:移开热源,待温度降至37.5℃以下,报警应自动解除,LED熄灭、蜂鸣器停止,串口打印
ALARM CLEARED。 - 判定通过条件:报警触发阈值与解除迟滞行为与代码设定一致,串口输出温度值与实际体温计误差不超过±0.3℃。
关键说明
- 若使用MAX30205替代TMP117,需注意其I2C地址为0x90(8位),且温度寄存器为0x00,数据格式同为16位有符号,但分辨率不同(0.00390625℃/LSB),需相应调整转换系数。
- 连续3次采样确认是为了避免瞬时干扰导致误报;迟滞回差防止报警在阈值附近频繁切换。
- 实际穿戴场景中,皮肤温度通常低于核心体温,如需报警对应发热状态,阈值应根据佩戴位置校准(如腋下比体表高约0.5℃)。