
1. 从一颗测温芯片说起为什么选MLX90614和OpenHarmony第一次拿到MLX90614这颗红外测温芯片的时候我其实没太当回事——不就是个I2C接口的温度传感器嘛能有多复杂结果真正把它挂到OpenHarmony系统上跑通前后折腾了将近一周。踩的坑包括但不限于设备树节点写错导致I2C总线根本扫不到器件、SMBus协议和标准I2C的时序差异让读出来的温度永远是0xFFFF、还有HDI层接口对接时数据上报格式对不上的问题。所以这篇内容我打算把整个流程从头到尾捋一遍把那些文档里不会写的细节都摊开讲。MLX90614是Melexis出品的一款红外非接触式测温芯片TO-39金属封装内部集成了红外热电堆传感器、低噪声放大器、17位ADC和一个DSP处理单元出厂时已经做了校准通过I2C接口可以直接读出经过线性化和温度补偿的环境温度与目标温度。它的测温范围覆盖-70°C到380°C医疗级版本精度可以做到±0.1°C工业级大概±0.5°C。相比自己搭热电堆运放ADC的方案这颗芯片省了太多事——校准、线性化、冷端补偿全在片内搞定MCU端只需要通过I2C读两个寄存器就行。那为什么要在OpenHarmony上做这个驱动因为现在大量智能硬件设备——比如智能门禁的体温筛查模块、工业设备的非接触温度监控节点、智能家居里的环境感知终端——都在往OpenHarmony生态上迁移。OpenHarmony的驱动框架和传统Linux驱动有相似之处但也有自己的一套HDIHardware Driver Interface规范特别是从3.2版本之后外设驱动推荐走HDFHardware Driver Foundation框架来写。这意味着你不能简单照搬Linux的i2c_client驱动那套写法得按照OpenHarmony的规则来组织代码、配置设备树、注册驱动入口。这篇文章适合谁看如果你已经有基本的C语言基础和嵌入式开发经验了解I2C通信的基本原理但还没在OpenHarmony上完整走过一遍外设驱动开发流程那这篇内容就是写给你的。我会从硬件连接开始经过设备树配置、驱动框架搭建、I2C通信实现、数据解析一直到HDI接口对接和实际测试验证每一步都给出可复现的操作和参数说明。代码基于OpenHarmony 3.2 Release版本硬件平台以瑞芯微RK3568为例其他平台可以根据实际情况调整。2. 动手之前硬件连接与I2C地址确认2.1 MLX90614的引脚定义与接线方式MLX90614常见的是TO-39四脚封装四个引脚分别是VDD、GND、SCL、SDA。这里有个容易搞错的地方它的VDD供电范围是3.0V到3.6V典型值3.3V不能直接接5V否则芯片会烧。我之前有个朋友图省事直接怼了5V上去芯片当场冒烟几十块钱就这么没了。接线方式很直接MLX90614引脚开发板对应引脚备注VDD3.3V必须3.3V不可接5VGNDGND共地SCLI2Cx_SCL需要上拉电阻SDAI2Cx_SDA需要上拉电阻关于上拉电阻MLX90614的I2C接口是开漏输出SCL和SDA线都需要接上拉电阻到VDD。阻值一般选4.7kΩ或者10kΩ。如果你用的开发板上I2C总线已经有上拉电阻了很多RK3568开发板会自带4.7kΩ上拉那就不需要额外加。但如果你是通过杜邦线飞线连接到面包板上的最好确认一下总线上有没有上拉没有的话自己补两个4.7kΩ的电阻上去。我遇到过好几次读数据不稳定、偶尔NACK的情况最后查出来都是上拉电阻缺失或者阻值太大导致上升沿太缓。2.2 I2C从机地址的确认方法MLX90614的7位I2C从机地址是0x5A。注意这里说的是7位地址如果你在代码里用的是8位地址格式那写地址是0xB4读地址是0xB5。这个换算关系一定要搞清楚不然你会发现在i2cdetect工具里能看到0x5A这个地址但代码里怎么都通信不上。在Linux或者OpenHarmony的shell里可以用i2cdetect工具来扫描总线上的设备i2cdetect -y 1这里的“1”是I2C总线编号具体取决于你的硬件连接。如果一切正常你应该能看到类似这样的输出0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 5a 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --看到0x5a就说明芯片已经正常上电并且I2C通信链路是通的。如果什么都没扫到先检查供电和接线再确认上拉电阻最后检查设备树里I2C控制器有没有使能。注意MLX90614支持SMBus协议它的读写时序和标准I2C有细微差别。SMBus要求数据传输之间有更严格的超时限制而且读操作需要先写寄存器地址再发起读中间要发一个Repeat Start而不是Stop。如果你的I2C控制器驱动不支持Repeat Start读出来的数据会全是0xFF。3. OpenHarmony设备树配置让系统认识这颗芯片3.1 设备树的基本结构与I2C节点添加OpenHarmony在RK3568平台上使用的是设备树来描述硬件资源。设备树文件通常位于内核源码的arch/arm64/boot/dts/rockchip/目录下具体到RK3568你可能会用到rk3568-evb.dts或者你自己板子对应的dts文件。首先需要确认I2C控制器节点是使能状态。以I2C1为例在设备树里找到对应的节点i2c1 { status okay; clock-frequency 100000; pinctrl-names default; pinctrl-0 i2c1_xfer; };这里clock-frequency设置的是I2C总线时钟频率标准模式是100kHz快速模式是400kHz。MLX90614支持到400kHz但如果你飞线比较长或者上拉电阻偏大建议先用100kHz跑通再提速。pinctrl-0引用的引脚配置节点决定了哪两个物理引脚被复用为I2C功能这个一定要和你的实际接线对应上否则总线根本不通。然后在i2c1节点下面添加MLX90614的子节点mlx90614: mlx906145a { compatible melexis,mlx90614; reg 0x5a; status okay; };compatible属性是驱动匹配的关键驱动代码里的of_match_table必须包含这个字符串否则驱动加载后不会和这个设备节点绑定。reg属性就是I2C从机地址0x5A。3.2 设备树配置中容易踩的坑第一个坑是I2C控制器被其他功能占用了。RK3568的引脚复用非常灵活同一个物理引脚可能被多个外设共用。如果你发现设备树改好了但i2cdetect还是扫不到设备去检查一下pinctrl有没有冲突。可以用cat /sys/kernel/debug/pinctrl/pinctrl-rockchip-pinmux来查看当前引脚的复用状态。第二个坑是设备树编译后没有更新到板子上。修改dts文件后需要重新编译dtb然后把新的dtb烧录到开发板的boot分区。很多人改了dts但忘了重新编译和烧录然后一直在那里查代码问题白白浪费时间。编译命令一般是./build.sh --product-name rk3568 --build-target kernel编译产物在out/rk3568/packages/phone/images/目录下找到对应的dtb文件烧录即可。第三个坑是I2C地址冲突。0x5A这个地址在有些开发板上可能已经被其他芯片占用了比如某些EEPROM或者PMIC。先用i2cdetect扫一遍确认0x5A没有被其他设备占用再添加节点。4. HDF驱动框架搭建从零写一个MLX90614驱动4.1 OpenHarmony驱动框架的核心概念OpenHarmony的HDF驱动框架和Linux驱动模型有相似之处但组织方式不同。核心概念包括HdfDriverEntry驱动入口结构体包含Bind、Init、Release三个回调函数。Bind负责将驱动和设备节点关联Init负责初始化硬件和注册服务Release负责释放资源。HdfDeviceObject设备对象驱动通过它获取设备树中配置的属性信息。HdfDeviceNode设备节点对应设备树中的一个具体设备。Dispatch服务分发方法用于处理用户态通过HDI接口发过来的请求。整个驱动的加载流程是系统启动时HDF框架解析设备树找到匹配的驱动调用Bind进行绑定然后调用Init进行初始化。用户态通过HDI接口调用驱动服务时请求会通过Dispatch方法分发到对应的处理函数。4.2 驱动代码的目录结构与编译配置在OpenHarmony源码中外设驱动一般放在drivers/peripheral/目录下。我们需要创建一个新的目录比如drivers/peripheral/mlx90614/目录结构如下drivers/peripheral/mlx90614/ ├── BUILD.gn ├── driver/ │ ├── BUILD.gn │ ├── include/ │ │ └── mlx90614.h │ └── src/ │ └── mlx90614.c └── hdi/ └── ...BUILD.gn是OpenHarmony的编译配置文件基于GN和Ninja构建系统。驱动模块的BUILD.gn大概长这样import(//build/ohos.gni) ohos_shared_library(mlx90614_driver) { sources [ driver/src/mlx90614.c, ] include_dirs [ driver/include, //drivers/framework/include/core, //drivers/framework/include/utils, //drivers/framework/include/osal, //drivers/framework/include/platform, //drivers/framework/include/config, ] deps [ //drivers/framework/core:hdf_core, //drivers/framework/utils:hdf_utils, //drivers/framework/osal:hdf_osal, //drivers/framework/support/platform:hdf_platform, ] part_name mlx90614_driver install_enable true }这里的关键是deps里要链接HDF框架的核心库否则编译时会报找不到HdfDriverEntry等符号。part_name要和产品配置文件里的部件名称对应否则驱动不会被编译进系统镜像。4.3 驱动入口与I2C通信初始化驱动的核心代码从HdfDriverEntry开始#include hdf_device_desc.h #include hdf_log.h #include osal_io.h #include osal_mem.h #include platform_if.h #define HDF_LOG_TAG mlx90614_driver static int32_t Mlx90614Bind(struct HdfDeviceObject *device) { if (device NULL) { HDF_LOGE(device is null); return HDF_ERR_INVALID_PARAM; } HDF_LOGI(mlx90614 bind success); return HDF_SUCCESS; } static int32_t Mlx90614Init(struct HdfDeviceObject *device) { if (device NULL || device-property NULL) { HDF_LOGE(device or property is null); return HDF_ERR_INVALID_PARAM; } HDF_LOGI(mlx90614 init start); // 初始化I2C设备 // 注册HDI服务 return HDF_SUCCESS; } static void Mlx90614Release(struct HdfDeviceObject *device) { HDF_LOGI(mlx90614 release); } struct HdfDriverEntry g_mlx90614DriverEntry { .moduleVersion 1, .moduleName mlx90614_driver, .Bind Mlx90614Bind, .Init Mlx90614Init, .Release Mlx90614Release, }; HDF_INIT(g_mlx90614DriverEntry);HDF_INIT宏负责将驱动入口注册到HDF框架。moduleName必须和驱动配置文件中写的模块名一致否则框架找不到这个驱动。I2C通信的初始化在Init函数中完成。OpenHarmony提供了平台抽象层接口来操作I2C#include i2c_if.h static DevHandle g_i2cHandle NULL; static int32_t Mlx90614I2cInit(struct HdfDeviceObject *device) { int32_t ret; struct HdfDeviceNode *node (struct HdfDeviceNode *)device; g_i2cHandle I2cOpen(node-devId); if (g_i2cHandle NULL) { HDF_LOGE(open i2c failed); return HDF_FAILURE; } // 设置I2C从机地址 ret I2cSetAddr(g_i2cHandle, MLX90614_I2C_ADDR); if (ret ! HDF_SUCCESS) { HDF_LOGE(set i2c addr failed, ret %d, ret); I2cClose(g_i2cHandle); g_i2cHandle NULL; return ret; } HDF_LOGI(mlx90614 i2c init success); return HDF_SUCCESS; }I2cOpen的参数是设备节点ID这个ID来自设备树中I2C控制器的编号。I2cSetAddr设置从机地址0x5A。这两个接口是OpenHarmony平台层提供的底层会调用具体的I2C控制器驱动来完成实际的硬件操作。5. MLX90614寄存器操作与温度数据解析5.1 关键寄存器说明与读写时序MLX90614内部有多个寄存器我们主要用到两个寄存器地址名称说明0x06TOBJ1目标温度116位数据0x07TOBJ2目标温度216位数据0x08TA环境温度16位数据0x3ATAR1目标温度1原始数据0x3BTAR2目标温度2原始数据读温度数据的流程是先发送要读的寄存器地址写操作然后发起读操作读取两个字节的数据。注意MLX90614的数据格式是低字节在前、高字节在后小端模式而且数据是17位的最高位在第二个字节的bit7。温度换算公式是温度(°C) 原始数据 × 0.02 - 273.15比如读到的原始数据是0x3B4C十进制15180那么温度 15180 × 0.02 - 273.15 303.6 - 273.15 30.45°C。5.2 I2C读写函数的实现在OpenHarmony的HDF框架下I2C读写通过I2cTransfer接口完成static int32_t Mlx90614ReadReg(uint8_t regAddr, uint8_t *data, uint16_t len) { int32_t ret; struct I2cMsg msgs[2]; // 第一个消息写寄存器地址 msgs[0].addr MLX90614_I2C_ADDR; msgs[0].flags 0; msgs[0].len 1; msgs[0].buf regAddr; // 第二个消息读数据 msgs[1].addr MLX90614_I2C_ADDR; msgs[1].flags I2C_FLAG_READ; msgs[1].len len; msgs[1].buf data; ret I2cTransfer(g_i2cHandle, msgs, 2); if (ret ! 2) { HDF_LOGE(i2c transfer failed, ret %d, ret); return HDF_FAILURE; } return HDF_SUCCESS; }这里的关键是I2cTransfer的第二个参数是一个消息数组第一个消息是写操作发送寄存器地址第二个消息是读操作。两个消息之间会自动插入Repeat Start这正是SMBus读操作要求的时序。如果你分成两次独立的I2cTransfer调用中间会插入Stop信号MLX90614可能不会正确响应。5.3 温度数据的解析与校验读到的原始数据需要做解析和校验static int32_t Mlx90614ReadTemp(float *temp) { uint8_t buf[3] {0}; uint16_t rawData; int32_t ret; ret Mlx90614ReadReg(MLX90614_TOBJ1, buf, 3); if (ret ! HDF_SUCCESS) { HDF_LOGE(read tobj1 failed); return ret; } // 校验PEC可选 // buf[0]是低字节buf[1]是高字节buf[2]是PEC rawData (uint16_t)(buf[1] 8) | buf[0]; // 检查数据有效性 if (rawData 0xFFFF || rawData 0x0000) { HDF_LOGE(invalid raw data: 0x%04X, rawData); return HDF_FAILURE; } *temp (float)rawData * 0.02f - 273.15f; HDF_LOGI(raw 0x%04X, temp %.2f C, rawData, *temp); return HDF_SUCCESS; }这里我加了数据有效性检查因为如果I2C通信有问题读出来的数据经常是0xFFFF或者0x0000。这两个值对应的温度分别是1037.55°C和-273.15°C明显不合理可以直接判定为无效数据。实操心得MLX90614读到的原始数据是17位的但实际有效精度取决于芯片型号。医疗级MLX90614ESF-DCI精度可以到0.1°C工业级MLX90614ESF-BAA大概0.5°C。换算出来的温度值建议保留两位小数再多的小数位没有实际意义。6. HDI接口对接与用户态服务注册6.1 HDI接口定义与实现HDIHardware Driver Interface是OpenHarmony驱动框架中用户态和内核态之间的接口层。对于温度传感器这类外设通常需要定义一个HDI接口让上层应用可以通过标准接口获取温度数据。首先在drivers/peripheral/mlx90614/hdi/目录下定义接口文件mlx90614_hdi.h#ifndef MLX90614_HDI_H #define MLX90614_HDI_H #include stdint.h #define MLX90614_HDI_SUCCESS 0 #define MLX90614_HDI_FAILURE (-1) int32_t Mlx90614HdiInit(void); int32_t Mlx90614HdiGetTemperature(float *temp); int32_t Mlx90614HdiGetAmbientTemperature(float *temp); int32_t Mlx90614HdiDeinit(void); #endif然后在驱动代码中实现这些接口并通过Dispatch方法注册到HDF框架static int32_t Mlx90614Dispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) { int32_t ret HDF_SUCCESS; float temp 0.0f; switch (cmdId) { case MLX90614_CMD_GET_OBJECT_TEMP: ret Mlx90614ReadTemp(temp); if (ret HDF_SUCCESS) { HdfSbufWriteFloat(reply, temp); } break; case MLX90614_CMD_GET_AMBIENT_TEMP: ret Mlx90614ReadAmbientTemp(temp); if (ret HDF_SUCCESS) { HdfSbufWriteFloat(reply, temp); } break; default: HDF_LOGE(unknown cmdId: %d, cmdId); ret HDF_ERR_NOT_SUPPORT; break; } return ret; }HdfDeviceIoClient代表用户态的客户端连接cmdId是命令字data是输入参数reply是输出结果。用户态通过HdfIoServiceBind和HdfIoServiceDispatch来调用这些接口。6.2 用户态测试程序编写写一个简单的用户态测试程序来验证驱动是否工作正常#include stdio.h #include stdlib.h #include hdf_io_service_if.h #include mlx90614_hdi.h int main(int argc, char **argv) { struct HdfIoService *service NULL; struct HdfSBuf *data NULL; struct HdfSBuf *reply NULL; float temp 0.0f; int32_t ret; service HdfIoServiceBind(mlx90614_service); if (service NULL) { printf(bind service failed\n); return -1; } data HdfSbufObtainDefaultSize(); reply HdfSbufObtainDefaultSize(); if (data NULL || reply NULL) { printf(obtain sbuf failed\n); goto cleanup; } ret service-dispatcher-Dispatch(service-object, MLX90614_CMD_GET_OBJECT_TEMP, data, reply); if (ret ! HDF_SUCCESS) { printf(dispatch failed, ret %d\n, ret); goto cleanup; } if (!HdfSbufReadFloat(reply, temp)) { printf(read temp from reply failed\n); goto cleanup; } printf(object temperature: %.2f C\n, temp); cleanup: if (data ! NULL) HdfSbufRecycle(data); if (reply ! NULL) HdfSbufRecycle(reply); if (service ! NULL) HdfIoServiceRecycle(service); return 0; }编译这个测试程序需要链接HDF的客户端库在BUILD.gn里加上对应的依赖ohos_executable(mlx90614_test) { sources [ mlx90614_test.c ] deps [ //drivers/framework/core:hdfframework, //drivers/framework/osal:hdf_osal, ] external_deps [ hdf_core:libhdf_utils ] }7. 调试与问题排查实录7.1 常见问题速查表现象可能原因排查方法解决方案i2cdetect扫不到0x5A供电异常万用表测VDD引脚电压确认3.3V供电正常i2cdetect扫不到0x5A上拉电阻缺失测SCL/SDA空闲时电压补4.7kΩ上拉电阻i2cdetect扫不到0x5A设备树未使能I2C查看/sys/bus/i2c/devices修改dts使能I2C控制器读数据全0xFF时序不匹配示波器抓I2C波形确认使用Repeat Start读数据全0x00从机地址错误确认7位/8位地址格式7位地址0x5A8位写0xB4温度值跳变严重电源噪声示波器测VDD纹波加100nF去耦电容驱动加载失败模块名不匹配查看hilog日志确认moduleName一致HDI调用返回失败服务未注册查看服务列表确认Init中注册了服务7.2 几个我实际踩过的坑第一个坑是设备树里I2C控制器的clock-frequency设成了400kHz但飞线太长导致信号质量差读出来的数据偶尔出错。后来降到100kHz就稳定了。所以如果你也是用杜邦线连接的建议先用100kHz跑通等PCB打板了再考虑提速。第二个坑是MLX90614的PEC校验。MLX90614支持SMBus的PECPacket Error Checking功能每次读数据会多返回一个字节的CRC校验值。如果你在设备树或者驱动里没有正确处理这个额外的字节读到的数据就会错位。我一开始读3个字节以为第三个字节是无效数据直接丢了后来才发现那是PEC。不过PEC校验是可选的如果你不使能PEC读2个字节就够了。第三个坑是HDI服务注册的时机。我一开始在Bind函数里就注册了服务结果用户态调用时经常返回失败。后来改到Init函数里注册并且确保在注册之前完成了所有硬件初始化问题就解决了。Bind只是建立驱动和设备节点的关联此时硬件还没有初始化完成不适合注册服务。第四个坑是hilog日志级别。OpenHarmony默认的日志级别可能不输出INFO级别的日志导致我以为驱动没加载。后来用hilog -b D把日志级别调到DEBUG才看到完整的加载过程。调试阶段建议把日志级别调低方便观察驱动状态。7.3 性能优化建议MLX90614的转换速率不算快默认配置下每秒大概能读10次左右。如果你需要更高的采样率可以通过配置寄存器调整。但要注意提高采样率会牺牲一定的精度。另外如果你在同一个I2C总线上挂了多个MLX90614可以通过修改芯片内部的EEPROM来改变从机地址。不过这个操作有风险改错了芯片就废了建议先用一个芯片把驱动跑通再说。在驱动层面可以考虑加一个缓存机制把最近一次读到的温度值缓存起来上层应用读取时如果缓存未过期就直接返回缓存值减少I2C通信次数。缓存有效期可以根据实际需求设置比如100ms。8. 从驱动到应用完整数据链路验证8.1 系统集成与编译烧录驱动代码写完之后需要把驱动模块集成到系统镜像中。在产品的配置文件里添加驱动部件{ subsystem: mlx90614, components: [ { component: mlx90614_driver, features: [] } ] }然后在drivers/peripheral/mlx90614/driver/BUILD.gn中确保install_enable true这样编译时会把驱动库安装到系统镜像的/vendor/lib/modules/目录下。编译整个系统./build.sh --product-name rk3568 --ccache编译完成后镜像文件在out/rk3568/packages/phone/images/目录下。烧录到开发板后系统启动时会自动加载驱动。可以通过以下命令确认驱动是否加载成功hilog | grep mlx90614如果看到“mlx90614 bind success”和“mlx90614 i2c init success”的日志说明驱动已经正常加载。8.2 实际测温验证与精度对比用一个标准温度源比如恒温水浴或者黑体炉来验证测温精度。我手头没有专业设备就用了一个医用电子体温计做对比。把MLX90614对准一个装了温水的杯子同时用体温计测水温等读数稳定后对比测量次数MLX90614读数(°C)体温计读数(°C)偏差(°C)136.836.50.3237.136.80.3336.936.60.3437.036.70.3536.736.40.3可以看到MLX90614的读数比体温计高0.3°C左右这个偏差是固定的说明芯片的线性度很好只是存在一个系统性的偏移。这个偏移可以通过在驱动里加一个补偿值来修正或者在上层应用做校准。需要注意的是红外测温的准确性受环境影响很大。环境温度、测量距离、目标物体的发射率都会影响读数。MLX90614出厂时默认的目标发射率是0.95适合测量大多数非金属表面。如果测量金属表面需要根据实际发射率做修正。8.3 长时间运行稳定性测试让驱动连续运行24小时每隔10秒读一次温度记录数据。测试下来发现几个问题第一连续运行几个小时后偶尔会出现一次读数为0xFFFF的情况。排查后发现是I2C总线在长时间运行后出现了偶发的时序偏移。在驱动里加了重试机制一次读取失败后自动重试最多3次问题基本解决。第二环境温度变化对读数的影响比预期大。当环境温度从25°C升到35°C时目标温度的读数会漂移大约0.5°C。这是红外测温的固有问题可以通过读取环境温度寄存器TA来做补偿。第三长时间运行后驱动占用的内存没有明显增长说明没有内存泄漏。但要注意在Release函数中正确释放所有分配的资源包括I2C句柄、SBuf等。9. 一些实操层面的经验总结整个流程走下来我觉得最容易出问题的环节是设备树配置和I2C时序。设备树的问题在于它不报错配置错了就是设备找不到你得一层一层排查。I2C时序的问题在于它有时候能工作有时候不能稳定性很差需要用示波器才能定位。如果你刚开始做OpenHarmony驱动开发我的建议是先用一个最简单的GPIO驱动练手把HDF框架的加载流程、设备树匹配、HDI接口注册这些基础环节跑通然后再上I2C这种有通信协议的复杂外设。直接上I2C驱动的话一旦出问题你很难判断是框架的问题还是通信的问题。另外OpenHarmony的驱动开发文档目前还不够完善很多细节需要看源码才能搞清楚。建议把drivers/framework/目录下的核心代码过一遍特别是core/和support/platform/这两个目录理解了框架的设计思路之后写驱动会顺畅很多。关于MLX90614这颗芯片本身它的性价比在红外测温领域算是很高的。如果你需要更远的测量距离或者更高的精度可以考虑MLX90614的DCI版本或者Melexis的其他型号。但如果只是做近距离的非接触测温比如体温筛查或者设备温度监控这颗芯片完全够用。最后说一个实际项目中遇到的问题MLX90614的视场角FOV对测量结果影响很大。标准版本的FOV是90度意味着在10cm距离上测量区域直径大约20cm。如果你要测很小的目标比如电子元件的表面温度就需要选窄视场角的版本比如FOV为35度或者10度的型号。这个在选型的时候就要确定好不然后面发现测不准再换芯片就麻烦了。