当前位置: 首页 > news >正文

基于TI MSPM0 MCU的MLX90614红外测温传感器SMBus驱动移植与实战

基于TI MSPM0 MCU的MLX90614红外测温传感器SMBus驱动移植与实战

最近在做一个需要非接触测温的小项目,用到了MLX90614这款红外测温传感器。很多刚开始接触嵌入式,特别是用TI MSPM0系列MCU的朋友,可能会觉得驱动这种“类IIC”的传感器有点绕。今天我就以立创开发板为例,手把手带你走一遍从看懂数据手册到代码成功运行的完整流程,把SMBus通信和温度换算这些事儿彻底讲明白。

1. 项目准备:认识你的“武器”

在写代码之前,咱们得先搞清楚要用的“家伙事儿”是什么,以及它们之间怎么“对话”。

1.1 MLX90614传感器简介

MLX90614是一个红外测温模块,它的最大优点就是非接触。你不用碰到物体,隔空就能测出它的温度,非常适合测运动物体、高温物体或者不方便接触的场景(比如测额温)。

它内部已经帮你把复杂的校准和线性化处理好了,你直接读取数据就行,非常方便。模块通过一个叫SMBus的协议和单片机通信。

注意:很多资料说MLX90614用的是I2C,严格来说不准确。它用的是SMBus(System Management Bus),你可以理解为I2C的一个“亲戚”或“增强版”。两者硬件接线(两根线:SCL时钟线和SDA数据线)和基础通信时序很像,所以常被叫做“类IIC”。但在某些细节(如超时、电气特性)上有所不同。好在对于基础读写操作,我们用标准的I2C控制器去模拟SMBus的主时序,通常都能正常工作。

模块关键参数(基于原文资料)

  • 工作电压:4.5V ~ 5.5V (注意是5V电平,如果MCU是3.3V,可能需要电平转换)
  • 工作电流:1.3mA ~ 2.5mA
  • 默认器件地址:0x5A(7位地址)
  • 温度数据存储位置
    • 物体温度(To):存储在RAM的0x07地址单元。
    • 环境温度(Ta):存储在RAM的0x06地址单元。

1.2 理解MLX90614的数据存储与命令

要读取温度,你得知道怎么跟传感器“要数据”。MLX90614内部有两块存储区:

  1. EEPROM:存储了出厂校准参数,我们一般不需要改动。
  2. RAM:存储了实时采集的数据,我们读取温度就是从这里读

读取数据的核心是构造一个正确的“命令字节”。这个命令字节告诉传感器:“我要读RAM,并且地址是0x06(或0x07)”。

怎么构造呢?根据数据手册:

  • 命令字节的高3位(BIT7~BIT5)表示操作类型。读RAM就是000
  • 命令字节的低5位(BIT4~BIT0)就是RAM地址的低5位。

所以:

  • 读环境温度(地址0x06 =0000 0110),取低5位00110,加上高3位000,命令字节就是0000 0110,即0x06
  • 读物体温度(地址0x07 =0000 0111),取低5位00111,命令字节就是0000 0111,即0x07

看,其实很简单,读温度就是发送命令0x060x07

1.3 温度数据换算

传感器读回来的不是直接的温度值,而是一个16位的原始数据。需要用一个固定公式换算:

实际温度 = (原始数据 × 0.02) - 273.15

这个公式对物体温度(To)和环境温度(Ta)都适用。公式里的273.15是开尔文温度到摄氏度的转换常数。

举个例子,如果你读到的原始数据是0x3AF7(十进制15095),那么计算过程就是: 15095 × 0.02 = 301.9 301.9 - 273.15 = 28.75℃

2. 硬件连接与工程配置

2.1 引脚连接

MLX90614模块通常有4个引脚:VCC, GND, SCL, SDA。

  • VCC-> 开发板5V引脚(注意电平匹配)
  • GND-> 开发板GND
  • SCL-> 开发板上用于I2C功能的时钟引脚(例如 PA8)
  • SDA-> 开发板上用于I2C功能的数据引脚(例如 PA9)

具体连接到你开发板的哪两个脚,取决于你接下来在SysConfig工具里的配置。

2.2 使用SysConfig配置I2C外设

TI的MSPM0系列推荐使用图形化工具SysConfig来配置引脚和外设,它会自动生成初始化代码,非常省事。

  1. 在CCS或你的工程中找到并双击empty.syscfg文件,打开SysConfig配置界面。
  2. 在左侧的“Components”窗口中,点击ADD按钮。
  3. 搜索并添加I2C相关的配置组件(例如I2CCONNECTION下的I2C)。
  4. 在图形界面中,将I2C模块拖放到你的MCU芯片图标上。
  5. 在右侧属性栏,配置I2C的工作模式(Controller模式,即主模式)、时钟速度(比如100kbps)等参数。
  6. 最关键的一步:配置引脚。在引脚映射图中,或者在一个叫“PinMux”的配置项里,为这个I2C实例选择具体的SCL和SDA引脚(例如PA8和PA9)。软件会检查引脚冲突,非常直观。
  7. 点击保存按钮。

重要提示:保存后,SysConfig可能会弹出对话框询问是否更新工程中的源文件,一定要选择Yes to All

  1. 保存后,点击编译按钮(或让工程自动构建)。SysConfig会自动在后台生成一个ti_msp_dl_config.h文件,里面包含了所有你配置的引脚和外围设备定义。这个文件通常会被主头文件board.h所包含,所以我们只需要在代码里#include "board.h"就行了。

3. 驱动代码移植与编写

配置好硬件,接下来就是写软件驱动了。我们需要创建两个文件:bsp_mlx90614.cbsp_mlx90614.h

3.1 头文件 (bsp_mlx90614.h)

头文件很简单,主要是声明我们即将要用的函数。

#ifndef _BSP_MLX90614_H_ #define _BSP_MLX90614_H_ #include "board.h" // 包含所有硬件配置 // 温度读取函数声明 // SlaveAddr: 传感器地址,默认为0x5A // RegAddr: 要读取的寄存器地址,物体温度用0x07,环境温度用0x06 float MLX90614_Read(unsigned char SlaveAddr, unsigned char RegAddr); #endif

3.2 源文件 (bsp_mlx90614.c)

这里是核心,包含了实际的通信和计算逻辑。代码基于原文提供的示例,我加了更详细的注释。

#include "bsp_mlx90614.h" #include <stdio.h> /** * @brief 计算PEC校验值(循环冗余校验) * @param dat: 指向要校验的数据数组的指针 * @param len: 数据的长度(字节数) * @retval 计算出的8位PEC校验值 * @note MLX90614的SMBus通信可选PEC校验,用于提高通信可靠性。 * 本例程的读取函数未使用PEC,但此函数保留供需要时使用。 */ static unsigned char PEC_Calculation(unsigned char *dat, unsigned char len) { unsigned char i; unsigned char crc = 0; while (len--) { crc ^= *dat++; // 与数据异或 for (i = 0; i < 8; i++) // 处理每个bit { if (crc & 0x80) // 如果最高位是1 { crc = (crc << 1) ^ 0x07; // 左移并与多项式0x07异或 } else { crc = (crc << 1); // 否则只左移 } } } return crc; } /** * @brief 读取MLX90614的温度值 * @param SlaveAddr: 传感器的7位I2C地址,默认为0x5A * @param RegAddr: 要读取的命令/寄存器地址(0x06为环境温度,0x07为物体温度) * @retval 计算得到的实际温度值(摄氏度,float类型) */ float MLX90614_Read(unsigned char SlaveAddr, unsigned char RegAddr) { uint8_t dat_buff[3] = {0}; // 存储读取到的数据:低字节、高字节、PEC(本例未使用PEC) uint8_t cmd = RegAddr; // 要发送的命令字节,就是寄存器地址 // 步骤1: 将命令字节写入I2C控制器的发送FIFO DL_I2C_fillControllerTXFIFO(I2C_0_INST, &cmd, 1); // 等待I2C控制器空闲 while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)) {} // 步骤2: 启动一次写传输,发送传感器地址(左移1位)和命令字节 // (SlaveAddr<<1) 将7位地址左移,最低位表示读写(0写,1读),这里是写操作 DL_I2C_startControllerTransfer(I2C_0_INST, (SlaveAddr << 1), DL_I2C_CONTROLLER_DIRECTION_TX, 1); // 等待总线繁忙(表示传输开始) while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS)) {} // 等待本次传输完成,控制器再次空闲 while (!(DL_I2C_getControllerStatus(I2C_0_INST) & DL_I2C_CONTROLLER_STATUS_IDLE)) {} // 短暂延时,确保传感器准备好数据。这个延时有时很关键,根据传感器手册调整。 delay_ms(2); // 步骤3: 启动一次读传输,读取3个字节(温度低字节、高字节、PEC) // 注意:传感器地址最低位此时为1,表示读操作 DL_I2C_startControllerTransfer(I2C_0_INST, (SlaveAddr << 1) | 0x01, DL_I2C_CONTROLLER_DIRECTION_RX, 3); // 从I2C接收FIFO中依次读出3个字节 for (int i = 0; i < 3; i++) { dat_buff[i] = DL_I2C_receiveControllerData(I2C_0_INST); } // 步骤4: 组合温度原始数据(注意:低字节在前!) uint16_t tempRaw = (dat_buff[1] << 8) | dat_buff[0]; // dat_buff[1]是高字节,dat_buff[0]是低字节 // 步骤5: 将原始数据转换为实际温度(摄氏度) float temperature = (tempRaw * 0.02) - 273.15; return temperature; }

代码关键点解析

  1. 通信流程:这是一个典型的I2C读传感器流程:启动 -> 发送器件地址(写) -> 发送命令字节 -> 重启 -> 发送器件地址(读) -> 读取数据 -> 停止。代码中通过两次DL_I2C_startControllerTransfer实现了“重启”效果。
  2. 数据顺序dat_buff[0]是温度数据的低8位,dat_buff[1]是高8位。这是MLX90614规定的,不要弄反。
  3. PEC字节:我们读回了3个字节,第三个字节dat_buff[2]是PEC校验码。本例为了简化,没有进行校验计算。在实际要求高的场合,可以用前面的PEC_Calculation函数验证数据正确性。
  4. 延时:在写命令和读数据之间加了一个小延时 (delay_ms(2)),这是为了给传感器一点时间准备数据。如果通信不稳定,可以尝试调整这个值。

4. 主程序验证与测试

驱动写好了,最后就是在主函数里调用它,并打印出结果。

#include "board.h" #include <stdio.h> #include "bsp_mlx90614.h" int main(void) { // 开发板初始化(时钟、GPIO、UART等,由SysConfig生成的代码完成) board_init(); // 初始化串口,用于打印(假设board_init已包含) printf("MLX90614 Test Start!\r\n"); while (1) { // 读取物体温度(传感器地址0x5A, 寄存器地址0x07) float object_temp = MLX90614_Read(0x5A, 0x07); // 读取环境温度(传感器地址0x5A, 寄存器地址0x06) float ambient_temp = MLX90614_Read(0x5A, 0x06); // 打印结果,格式化为整数和小数部分,便于在串口助手上观察 printf("Object: %d.%02d C, Ambient: %d.%02d C\r\n", (int)object_temp, ((uint32_t)(object_temp * 100)) % 100, (int)ambient_temp, ((uint32_t)(ambient_temp * 100)) % 100); // 每秒读取一次 delay_ms(1000); } }

编译、下载、观察

  1. 将整个工程编译无误后,下载到你的立创开发板(或其他TI MSPM0开发板)。
  2. 用USB线连接开发板到电脑,打开串口调试助手(如Putty、SecureCRT等)。
  3. 设置正确的串口号和波特率(通常是115200)。
  4. 复位开发板,你应该能看到串口每隔一秒打印出两行温度数据。
  5. 用手靠近MLX90614的传感器窗口(那个黑色的小透镜),物体温度应该会明显上升。环境温度则相对稳定。

常见问题与排查

  • 打印乱码或没数据:首先检查串口波特率设置是否正确。然后确认board_init()里是否正确初始化了用于打印的UART。
  • 温度读出来是0或异常值(如-273)
    • 检查硬件连接:VCC、GND、SCL、SDA四根线是否接牢?SCL和SDA是否接反?传感器是否供电正常(5V)?
    • 检查I2C引脚配置:确认SysConfig里配置的I2C引脚和你实际接线的引脚一致。
    • 检查上拉电阻:I2C总线需要上拉电阻(通常4.7kΩ~10kΩ)。开发板上的I2C接口可能已经内置了上拉,如果用的是通用GPIO口模拟,或者模块本身没有上拉,就需要自己在SCL和SDA线上各加一个上拉电阻到VCC。
    • 用逻辑分析仪抓波形:这是最直接的调试方法。看看单片机是否发出了正确的起始信号、地址、命令,以及传感器是否有应答和数据返回。
  • 通信不稳定,偶尔能读到:尝试增加delay_ms(2)的延时时间,或者检查电源是否稳定。

好了,整个过程就是这样。其实驱动MLX90614并不复杂,核心就是理解SMBus的读写序列和温度换算公式。一旦打通,这个传感器用起来还是非常方便的。在实际项目里,你可以把读到的温度用于显示、报警或者与其他系统联动。希望这篇教程能帮你顺利搞定这个红外测温模块。

http://www.jsqmd.com/news/469337/

相关文章:

  • Cellranger实战指南:从数据比对到表达矩阵生成
  • 国内知名IC制造展会哪家比较好,影响力深度解析 - 品牌2026
  • 立创EDA四轴智能小车F4项目:硬件电路设计优化与功能模块集成详解
  • Python flask +uniapp微信小程序的校园食堂订餐点餐配送系统微信小程序设计与实现
  • 博奥龙biodragon | 棕榈酰化修饰在疾病治疗中的前沿探索
  • 绝地求生罗技鼠标宏系统构建指南:从技术原理到战术落地
  • 2026年湖北庭院流水景墙优质供应商推荐与采购指南 - 2026年企业推荐榜
  • 数字孪生10大核心技术解析:从入门到实践
  • 基于FPGA的立创便携多通道函数发生器开源项目全解析
  • 微信小程序Python flask 基于Android的高校校车订座系统的设计与实现
  • genshin-fps-unlock技术解密:突破《原神》帧率限制的实战指南
  • 热门店铺磁吸门帘优质品牌推荐榜:陕西磁吸门帘/餐饮磁吸门帘/医院棉门帘/商场棉门帘/商场磁吸门帘/商店磁吸门帘/选择指南 - 优质品牌商家
  • 5个关键点:用VLC实现RTSP视频推流的实战指南
  • 3种高效方法:使用ncmdump工具实现NCM文件转MP3完全指南
  • 个人数据管理新方案:3步实现QQ空间历史记录完整备份
  • 电动玩具声光协同升级:四态硬件触发语音系统设计
  • 立创开源:基于STM32F405与FreeRTOS的NB-IoT无人水质监测船全栈开发指南
  • 瑞芯微 RK3588 核心模块性能监控与调优实战指南
  • 金融PHP支付接口安全“静默崩溃”现象全解析,从cURL SSL证书固定失效到JWT密钥硬编码的连锁崩塌链
  • FLUX.1-dev旗舰版部署全攻略:针对24G显存优化,一键启动无压力
  • 多平台直播效率提升指南:obs-multi-rtmp开源工具应用实践
  • 实测对比:Qwen3-ForcedAligner与传统字幕制作工具谁更快?
  • 如何用Alas解决碧蓝航线的三大痛点:自动化脚本实战指南
  • Xenos:Windows DLL注入工具的技术架构与安全实践指南
  • 国际知名IC制造展会有哪些,全球半导体领域重磅展会一览 - 品牌2026
  • 微带线与带状线:PCB设计中的阻抗控制与信号完整性解析
  • 四大.NET ORM框架深度对比:EF Core、SqlSugar、FreeSql与Dapper的性能、功能与适用场景
  • 【Jmatpro 10.0】从材料成分到应力-应变曲线的完整流程解析
  • opencode + oh-my-opencode配置全流程记录
  • Page Assist 开源工具本地部署与使用问题全解析