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

一、系统概述

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

二、系统架构

I2C
数据处理
体温值
控制
控制
设置/校准
供电
额头红外辐射
MLX90614传感器
STM32F103
温度计算算法
LCD1602显示
蜂鸣器报警
LED状态指示
按键
电池

  • 核心组件

  • 传感器:MLX90614(I2C接口,支持环境温度、目标温度双输出);

  • 主控:STM32F103C8T6(72MHz,I2C、ADC、GPIO控制);

  • 显示:LCD1602(16×2字符,显示体温、环境温度);

  • 报警:蜂鸣器(高温报警)、LED(工作状态指示);

  • 电源:3.7V锂电池(带TP4056充电管理)。

三、硬件设计

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)时钟配置
  • 系统时钟树:HSE=8MHz → PLL×9 → 72MHz SYSCLK;

  • APB1/APB2:36MHz/72MHz(I2C1挂载于APB1,时钟36MHz)。

(2)I2C配置(MLX90614)
  • I2C1:标准模式(100kHz),PB6(SCL)、PB7(SDA),开漏输出+4.7kΩ上拉;

  • 从机地址:MLX90614默认地址0x5A(7位地址,写地址0xB4,读地址0xB5)。

(3)GPIO配置
  • 按键:PC0-PC1,输入模式,上拉电阻;

  • 蜂鸣器:PC2,推挽输出;

  • LCD:PB0(RS)、PB2(EN)、PB4-PB7(D4-D7),推挽输出。

(4)生成工程

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

2. 核心代码实现

(1)MLX90614驱动(I2C通信)
c 复制代码
// 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℃):

c 复制代码
// 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显示驱动
c 复制代码
// 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)主程序逻辑
c 复制代码
// 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/contentcss/180192.html

五、关键功能实现

1. 校准方法

  • 两点校准
  1. 0℃校准 :将传感器对准冰水混合物(0℃),记录MLX90614输出值T0_raw,计算偏移量offset = 0 - (T0_raw*0.02 - 273.15)

  2. 37℃校准 :将传感器对准37℃恒温水浴,记录输出值T37_raw,计算比例系数scale = 37 / (T37_raw*0.02 - 273.15 + offset)

  3. 代码中通过CAL_OFFSETCAL_SCALE应用校准参数。

2. 低功耗设计

  • 休眠模式 :无操作时,STM32进入停止模式(HAL_PWR_EnterSTOPMode),通过按键中断唤醒;

  • 传感器休眠 :MLX90614支持睡眠模式(通过I2C发送休眠命令0xFF),测量时唤醒。

3. 抗干扰优化

  • 软件滤波:对连续3次测量结果取中值,减少随机噪声;

  • 环境光抑制:MLX90614内置环境光滤波,避免可见光干扰。

六、测试与验证

1. 测试工具

  • 标准温度计:医用体温计(精度±0.1℃)作为参考;

  • 恒温源:冰水混合物(0℃)、恒温水浴(37℃、40℃);

  • 示波器:观察I2C信号质量。

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显示 直观输出结果,具备快速测量、低功耗、高性价比特点。实际部署时需通过多点校准优化精度,并优化机械结构(如探头弧度)提升用户体验。

相关推荐
DC升降压/LED驱动IC2 小时前
源芯片选型指南之 AP5193 DC-DC 宽电压 LED 降压恒流驱动器
stm32·单片机·嵌入式硬件·物联网·51单片机·proteus
蓝凌y2 小时前
51单片机之花样灯
c语言·单片机·嵌入式硬件·51单片机
爱喝纯牛奶的柠檬2 小时前
STM32驱动HC-SR04超声波测距模块
stm32·单片机·嵌入式硬件
李永奉3 小时前
杰理芯片SDK-更改芯片产品蓝牙名功能
单片机·嵌入式硬件·mcu·物联网·语音识别
坤坤藤椒牛肉面3 小时前
ARM中断设置--定时器中断
单片机·嵌入式硬件
普中科技3 小时前
【普中 51-Ai8051 开发攻略】-- 第 6 章 LED 实验
单片机·嵌入式硬件·开发板·led·普中科技·ai8051u·aicube
爬山算法3 小时前
MongoDB(63)如何配置数据压缩?
数据库·mongodb
蓝凌y3 小时前
51单片机点亮LED
单片机·嵌入式硬件·51单片机
那人如此可好3 小时前
MongoDB从零基础搭建到实战
mongodb·db