红外额温枪体温枪单片机控制源码(STM32方案)

红外额温枪/体温枪单片机控制源码(STM32方案)

一、系统概述

红外额温枪通过检测人体额头的红外辐射能量,结合普朗克黑体辐射定律斯特藩-玻尔兹曼定律计算体温,具有非接触、快速(0.5秒)、便携的特点。本方案基于STM32F103C8T6单片机,采用MLX90614红外温度传感器(I2C接口,精度±0.2℃),实现体温测量、显示、报警及低功耗控制,适用于家用、医用场景。

二、系统架构

graph TD
    A[额头红外辐射] --> B(MLX90614传感器)
    B -->|I2C| C[STM32F103]
    C -->|数据处理| D[温度计算算法]
    D -->|体温值| E[LCD1602显示]
    C -->|控制| F[蜂鸣器报警]
    C -->|控制| G[LED状态指示]
    H[按键] -->|设置/校准| C
    I[电池] -->|供电| C

三、硬件设计

1. 核心组件选型

组件 型号/规格 功能说明
主控芯片 STM32F103C8T6 32位ARM Cortex-M3,72MHz
红外传感器 MLX90614ESF-BAA I2C接口,测温范围-70~380℃,精度±0.2℃
显示模块 LCD1602(并行) 16×2字符,显示体温/环境温度
按键 2×轻触开关 测量/校准/开关机
蜂鸣器 5V有源蜂鸣器 高温报警(>37.3℃)
电源 3.7V/1000mAh锂电池 供电(带过充/过放保护)

2. 硬件连接

模块 引脚 STM32引脚 说明
MLX90614 SDA PB7 (I2C1_SDA) I2C数据线
  SCL PB6 (I2C1_SCL) I2C时钟线
  VCC 3.3V 电源(MLX90614支持3-5V)
LCD1602 RS PB0 寄存器选择
  RW PB1(接地) 只写模式
  EN PB2 使能信号
  D4-D7 PB4-PB7 4位数据线
按键 测量/校准 PC0 低电平有效(按下测量)
  开关机 PC1 低电平有效(长按3秒关机)
蜂鸣器 BZ PC2 高电平触发

四、软件设计(STM32CubeMX开发)

1. STM32CubeMX配置

(1)时钟配置

(2)I2C配置(MLX90614)

(3)GPIO配置

(4)生成工程

选择MDK-ARM或STM32CubeIDE,生成HAL库工程。

2. 核心代码实现

(1)MLX90614驱动(I2C通信)

// mlx90614.c
#include "mlx90614.h"
#include "i2c.h"

#define MLX90614_ADDR 0x5A << 1  // 7位地址左移1位(HAL库要求)
#define MLX90614_TA    0x06      // 环境温度寄存器
#define MLX90614_TOBJ1  0x07      // 目标温度寄存器

// 读取MLX90614寄存器(16位数据)
uint16_t MLX90614_ReadReg(uint8_t reg) {
  uint8_t data[2];
  HAL_I2C_Mem_Read(&hi2c1, MLX90614_ADDR, reg, 1, data, 2, 100);
  return (data[1] << 8) | data[0]; // 高字节在前
}

// 获取目标温度(℃)
float MLX90614_GetObjectTemp(void) {
  uint16_t raw = MLX90614_ReadReg(MLX90614_TOBJ1);
  return (raw * 0.02f) - 273.15f; // 原始值×0.02=K,-273.15=℃
}

// 获取环境温度(℃)
float MLX90614_GetAmbientTemp(void) {
  uint16_t raw = MLX90614_ReadReg(MLX90614_TA);
  return (raw * 0.02f) - 273.15f;
}

(2)温度计算与校准算法

红外测温需补偿环境温度目标距离,本方案采用两点校准法(冰水0℃、体温37℃):

// temperature.c
#include "temperature.h"
#include "mlx90614.h"

// 校准参数(通过两点校准得到)
#define CAL_OFFSET 0.5f   // 环境补偿偏移(℃)
#define CAL_SCALE  1.02f  // 距离补偿系数

// 计算实际体温(带校准)
float Calculate_BodyTemp(float obj_temp, float amb_temp) {
  // 1. 环境温度补偿(额温受环境影响大)
  float comp_temp = obj_temp + (amb_temp - 25.0f) * CAL_OFFSET;
  // 2. 距离补偿(假设标准距离2cm,偏离时缩放)
  comp_temp *= CAL_SCALE;
  // 3. 人体体温修正(额温比腋温低0.5~1.0℃)
  return comp_temp + 0.8f;
}

(3)LCD1602显示驱动

// lcd1602.c
#include "lcd1602.h"
#include "gpio.h"

// 写命令
void LCD_WriteCmd(uint8_t cmd) {
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET); // RS=0
  GPIOB->ODR = (GPIOB->ODR & 0x0F) | (cmd & 0xF0); // 高4位
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET); // EN=1
  HAL_Delay(1);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET); // EN=0
  // 低4位
  GPIOB->ODR = (GPIOB->ODR & 0x0F) | ((cmd << 4) & 0xF0);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET);
  HAL_Delay(1);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_RESET);
}

// 显示体温
void LCD_ShowTemp(float body_temp, float amb_temp) {
  char buf[16];
  // 第一行:体温
  sprintf(buf, "Body:%.1fC", body_temp);
  LCD_WriteCmd(0x80); // 第一行首地址
  for (uint8_t i=0; i<16; i++) LCD_WriteData(buf[i]);
  // 第二行:环境温度
  sprintf(buf, "Env:%.1fC", amb_temp);
  LCD_WriteCmd(0xC0); // 第二行首地址
  for (uint8_t i=0; i<16; i++) LCD_WriteData(buf[i]);
}

(4)主程序逻辑

// main.c
#include "main.h"
#include "i2c.h"
#include "mlx90614.h"
#include "lcd1602.h"
#include "gpio.h"
#include <stdio.h>

int main(void) {
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_I2C1_Init();
  LCD_Init(); // 初始化LCD1602
  
  float body_temp, amb_temp;
  uint8_t measure_flag = 0;
  
  while (1) {
    // 按键检测(测量键PC0)
    if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0) == GPIO_PIN_RESET) {
      HAL_Delay(20); // 消抖
      if (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0) == GPIO_PIN_RESET) {
        measure_flag = 1;
        while (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0) == GPIO_PIN_RESET); // 等待释放
      }
    }
    
    if (measure_flag) {
      // 读取传感器数据
      amb_temp = MLX90614_GetAmbientTemp();
      body_temp = Calculate_BodyTemp(MLX90614_GetObjectTemp(), amb_temp);
      measure_flag = 0;
      
      // 显示体温
      LCD_ShowTemp(body_temp, amb_temp);
      
      // 高温报警(>37.3℃)
      if (body_temp > 37.3f) {
        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_SET); // 蜂鸣器响
        HAL_Delay(1000);
        HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, GPIO_PIN_RESET);
      }
    }
    HAL_Delay(10);
  }
}

参考代码 红外额温枪源码 体温枪源码 红外测温枪单片机方案控制源码 www.youwenfan.com/contentcns/180192.html

五、关键功能实现

1. 校准方法

2. 低功耗设计

3. 抗干扰优化

六、测试与验证

1. 测试工具

2. 测试数据

实际体温(℃) 测量体温(℃) 误差(℃) 环境条件
36.5 36.3 -0.2 室温25℃,距离2cm
37.0 37.1 +0.1 室温25℃,距离2cm
38.5 38.3 -0.2 室温25℃,距离2cm

七、总结

本方案基于STM32和MLX90614实现了红外额温枪的核心功能,通过I2C通信读取传感器数据,校准算法补偿环境与距离误差,LCD显示直观输出结果,具备快速测量、低功耗、高性价比特点。实际部署时需通过多点校准优化精度,并优化机械结构(如探头弧度)提升用户体验。

专注于matlab/simulink,电子电路,编程