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

相关推荐
blevoice13 小时前
JL杰理AC696N开发板常见问题FAQ-问题6:为什么提示“key 不匹配”?杰理的蓝牙芯片的key是什么?以及该如何添加key? 杰理key文件原理?
单片机·嵌入式硬件·物联网·jl杰理蓝牙音频芯片·ac696n·蓝牙音箱方案开发
三佛科技-1873661339715 小时前
辉芒微FT62FC1x低成本小体积定时器触摸MCU芯片选型深度解析
单片机·嵌入式硬件
独小乐15 小时前
018.使用I2C总线EEPROM|千篇笔记实现嵌入式全栈/裸机篇
linux·笔记·单片机·嵌入式硬件·arm·信息与通信
C^h16 小时前
rtthread控制达妙4310电机
数据库·单片机·嵌入式硬件
三佛科技-1873661339716 小时前
LP3717BSL 12V1A隔离型极简化自供电充电器适配器电源方案测试报告
单片机·嵌入式硬件
一路往蓝-Anbo17 小时前
第二章:STM32 bxCAN 控制器详解:从内存到总线的“中转站”
stm32·单片机·嵌入式硬件·软件工程
Dunkle.T18 小时前
DC-DC PCB设计要点说明——拓扑、走线、选型、铺铜详解
单片机·嵌入式硬件·pcb·dc-dc
charlie11451419118 小时前
嵌入式C++工程实践——第13篇:第一次重构 —— enum class取代宏,类型安全的开始
开发语言·c++·vscode·stm32·安全·重构·现代c++
三品吉他手会点灯19 小时前
STM32F103 学习笔记-21-串口通信(第4节)—串口发送和接收代码讲解(上)
笔记·stm32·单片机·嵌入式硬件·学习
weifengdq20 小时前
SJA1124 SPI转4路LIN STM32 测试笔记
stm32·spi·nxp·lin·sja1124·spi4lin