使用MLX90640自制红外热像仪(一):MLX90640介绍与API库移植

使用MLX90640自制红外热像仪(一):MLX90640介绍与API库移植平时工作的时候会遇到如下场景 新焊接好的板子 通电后发现电流异常 需要看下板子上哪里发热异常

大家好,欢迎来到IT知识分享网。

  平时工作的时候会遇到如下场景:

  • 新焊接好的板子,通电后发现电流异常,需要看下板子上哪里发热异常。
  • 需要监控某个器件(比如三极管、MOS)的温度,以防过热烧掉。
  • 测量温升。

  因此需要一个红外热像仪,可是网上看了一下都要2000左右了,虽然分辨率很高,可是我并不需要那么好的性能,于是干脆自己做一个。AMG8833的像素点是8×8的,感觉太低了,于是选用了32×24像素点的MLX90640。

MLX90640介绍

特性和优点

  • 小尺寸,低功耗, 32*24 像素红外阵列
  • 方便集成
  • 标准的 TO39 封装
  • 出厂校准
  • 噪声等效温差( NETD)0.1K RMS@1Hz 速率
  • I2C 兼容数字接口
  • 可编程刷新速率 0.5Hz~60Hz
  • 供电电压 3.3V
  • 电流消耗:≤23mA
  • 两种视场角可选: 55° *30° 和 110° *75°
  • 工作温度: -45~85℃
  • 测温范围: -40~300℃
  • 符合 RoHS 标准

应用实例

  • 高精度非接触温度测量
  • 安防、入侵检测
  • 人体检测
  • 智能楼宇环境温度测控
  • 汽车空调控制
  • 微波炉、烤箱温度检测与控制
  • 工业零件温度监测
  • 可视化温度传感器
  • 驱动程序可从下面网页下载:
  • https://github.com/melexis/mlx90640-library

概述

管脚定义

在这里插入图片描述

A 型和 B 型

在这里插入图片描述
MLX90640 有两个型号, A 型和 B 型,型号全称为:MLX90640ESF_BAA/BAB。
他们区别在于:

  • 视场角不同: A 型为 110*75° , B 型为 55*35° ,通俗一点讲就是 A 型是广角,所以镜
    头矮一些,视野更宽,但对远处物体的捕捉能力更低, B 型更适于拍摄稍远的物体。
  • 精度不同: A 型的噪声比 B 型大,所以 B 型的绝对温度和灵敏度都好一些。

一般电气特性

在这里插入图片描述

像素位置对应关系

在这里插入图片描述

通信协议

该设备采用 I2C 协议,支持快速模式( FM+)(最高 1MHz时钟频率),只可作为从机在总线上使用。
SDA 和 SCL 端口 5V 兼容,可以直接连接到 5V 逻辑的 I2C 总线网络。
从地址可编程的,可以有多达 127 个不同的从地址。
使用标准的IIC时序:
在这里插入图片描述



测量模式

  测量完成的红外阵列数据更新到 RAM 区,占用 1536 字节, MLX90640 每次测量一半像素点,分两次完成所有 768 像素的测量,在逻辑上将每次测量完成的一半称为一个子页,故此数据帧有两个子页面(两个子页合并以后才是完整的 768 个像素数据), 每次完成一半像素点的分布模式有两种,可通过控制寄存器 1( 0x800D) 的 bit12 位来设置。

  • ( 1) 棋盘模式(默认),( 每个像素间隔排列-像素交错模式)
  • ( 2)电视交错模式,( 隔行排列-行交错模式)

注 1:标准的 MLX90640 出厂的时候是在棋盘模式下校准的,因此传感器在棋盘模式下具有更好的噪声滤除性能。为了得到最好的结果,建议使用默认的棋盘模式。

在这里插入图片描述
在这里插入图片描述

刷新率和噪声

精度、坏点

原理图

在这里插入图片描述

API库的移植

软件模拟IIC移植(stm32)

/ * @copyright (C) 2017 Melexis N.V. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ / * As the timings depend heavily on the MCU in use, it is recommended * to make sure that the proper timings are achieved. For that purpose * an oscilloscope might be needed to strobe the SCL and SDA signals. * The Wait(int) function could be modified in order to better * trim the frequency. For coarse setting of the frequency or * dynamic frequency change using the default function implementation, * ‘freqCnt’ argument should be changed – lower value results in * higher frequency. */ #include "MLX90640_I2C_Driver.h" #define Wait(freqCnt) freqCnt++ int I2CSendByte(int8_t); void I2CReadBytes(int, char *); void I2CStart(void); void I2CStop(void); void I2CRepeatedStart(void); void I2CSendACK(void); void I2CSendNack(void); int I2CReceiveAck(void); //void Wait(int); int freqCnt = 1; void MLX90640_I2CInit() { 
    GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE ); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); IIC_SDA_HIGH(); IIC_SCL_HIGH(); } int MLX90640_I2CRead(uint8_t slaveAddr, uint16_t startAddress,uint16_t nMemAddressRead, uint16_t *data) { 
    uint8_t sa; int ack = 0; int cnt = 0; int i = 0; char cmd[2] = { 
   0,0}; char i2cData[1664] = { 
   0}; uint16_t *p; p = data; sa = (slaveAddr << 1); cmd[0] = startAddress >> 8; cmd[1] = startAddress & 0x00FF; I2CStop(); Wait(freqCnt); I2CStart(); Wait(freqCnt); ack = I2CSendByte(sa)!=0; if(ack != 0) { 
    return -1; } ack = I2CSendByte(cmd[0])!=0; if(ack != 0) { 
    return -1; } ack = I2CSendByte(cmd[1])!=0; if(ack != 0) { 
    return -1; } I2CRepeatedStart(); sa = sa | 0x01; ack = I2CSendByte(sa); if(ack != 0) { 
    return -1; } I2CReadBytes((nMemAddressRead << 1), i2cData); I2CStop(); for(cnt=0; cnt < nMemAddressRead; cnt++) { 
    i = cnt << 1; *p++ = (int)i2cData[i]*256 + (int)i2cData[i+1]; } return 0; } void MLX90640_I2CFreqSet(int freq) { 
    freqCnt = freq>>1; } int MLX90640_I2CWrite(uint8_t slaveAddr, uint16_t writeAddress, uint16_t data) { 
    uint8_t sa; int ack = 0; char cmd[4] = { 
   0,0,0,0}; static uint16_t dataCheck; sa = (slaveAddr << 1); cmd[0] = writeAddress >> 8; cmd[1] = writeAddress & 0x00FF; cmd[2] = data >> 8; cmd[3] = data & 0x00FF; I2CStop(); Wait(freqCnt); I2CStart(); ack = I2CSendByte(sa); if (ack != 0x00) { 
    return 1; } for(int i = 0; i<4; i++) { 
    ack = I2CSendByte(cmd[i]); if (ack != 0x00) { 
    return -1; } } I2CStop(); MLX90640_I2CRead(slaveAddr,writeAddress,1, &dataCheck); if ( dataCheck != data) { 
    return -2; } return 0; } int I2CSendByte(int8_t data) { 
    int ack = 1; int8_t byte = data; for(int i=0;i<8;i++) { 
    Wait(freqCnt); if(byte & 0x80) { 
    IIC_SDA_HIGH(); } else { 
    IIC_SDA_LOW(); } Wait(freqCnt); IIC_SCL_HIGH(); Wait(freqCnt); Wait(freqCnt); IIC_SCL_LOW(); byte = byte<<1; } Wait(freqCnt); ack = I2CReceiveAck(); return ack; } void I2CReadBytes(int nBytes, char *dataP) { 
    char data; for(int j=0;j<nBytes;j++) { 
    Wait(freqCnt); IIC_SDA_HIGH(); data = 0; for(int i=0;i<8;i++){ 
    Wait(freqCnt); IIC_SCL_HIGH(); Wait(freqCnt); data = data<<1; if(IIC_SDA_READ()){ 
    data = data+1; } Wait(freqCnt); IIC_SCL_LOW(); Wait(freqCnt); } if(j == (nBytes-1)) { 
    I2CSendNack(); } else { 
    I2CSendACK(); } *(dataP+j) = data; } } //void Wait(int freqCnt) //{ 
     int i;  i=0;  for(i = 0;i<freqCnt;i++);  { 
     cnt = cnt++;   }   while(freqCnt--);  for(cnt=20;cnt>0;cnt--);  //}  void I2CStart(void) { 
    IIC_SDA_HIGH(); IIC_SCL_HIGH(); Wait(freqCnt); Wait(freqCnt); IIC_SDA_LOW(); Wait(freqCnt); IIC_SCL_LOW(); Wait(freqCnt); } void I2CStop(void) { 
    IIC_SCL_LOW(); IIC_SDA_LOW(); Wait(freqCnt); IIC_SCL_HIGH(); Wait(freqCnt); IIC_SDA_HIGH(); Wait(freqCnt); } void I2CRepeatedStart(void) { 
    IIC_SCL_LOW(); Wait(freqCnt); IIC_SDA_HIGH(); Wait(freqCnt); IIC_SCL_HIGH(); Wait(freqCnt); IIC_SDA_LOW(); Wait(freqCnt); IIC_SCL_LOW(); } void I2CSendACK(void) { 
    IIC_SDA_LOW(); Wait(freqCnt); IIC_SCL_HIGH(); Wait(freqCnt); Wait(freqCnt); IIC_SCL_LOW(); Wait(freqCnt); IIC_SDA_HIGH(); } void I2CSendNack(void) { 
    IIC_SDA_HIGH(); Wait(freqCnt); IIC_SCL_HIGH(); Wait(freqCnt); Wait(freqCnt); IIC_SCL_LOW(); Wait(freqCnt); IIC_SDA_HIGH(); } int I2CReceiveAck(void) { 
    int ack; IIC_SDA_HIGH(); Wait(freqCnt); IIC_SCL_HIGH(); Wait(freqCnt); if(IIC_SDA_READ() == 0) { 
    ack = 0; } else { 
    ack = 1; } Wait(freqCnt); IIC_SCL_LOW(); IIC_SDA_LOW(); return ack; } 

打开MLX90640_I2C_Driver.h文件,把SDA和SCL拉高拉低的宏定义实现:

/ * @copyright (C) 2017 Melexis N.V. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef _MLX90640_I2C_Driver_H_ #define _MLX90640_I2C_Driver_H_ //#ifdef __cplusplus // extern "C" { 
    //#endif #include <stdint.h> #include "stm32f10x.h" //IO方向设置 #define SDA_IN() { 
     GPIOA->CRH&=0X0FFFFFFF;GPIOA->CRH|=8<<28;} #define SDA_OUT() { 
     GPIOA->CRH&=0X0FFFFFFF;GPIOA->CRH|=3<<28;} #define GPIO_PORT_I2C GPIOA  #define RCC_I2C_PORT RCC_APB2Periph_GPIOA  #define I2C_SCL_PIN GPIO_Pin_9 /* 连接到SCL时钟线的GPIO */ #define I2C_SDA_PIN GPIO_Pin_15 /* 连接到SDA数据线的GPIO */ #define IIC_SCL_HIGH() GPIO_PORT_I2C->BSRR = I2C_SCL_PIN /* SCL = 1 */ #define IIC_SCL_LOW() GPIO_PORT_I2C->BRR = I2C_SCL_PIN /* SCL = 0 */ #define IIC_SDA_HIGH() GPIO_PORT_I2C->BSRR = I2C_SDA_PIN /* SDA = 1 */ #define IIC_SDA_LOW() GPIO_PORT_I2C->BRR = I2C_SDA_PIN /* SDA = 0 */ #define IIC_SDA_READ() ((GPIO_PORT_I2C->IDR & I2C_SDA_PIN) != 0) /* 读SDA口线状态 */ void MLX90640_I2CInit(void); int MLX90640_I2CRead(uint8_t slaveAddr,uint16_t startAddress, uint16_t nMemAddressRead, uint16_t *data); int MLX90640_I2CWrite(uint8_t slaveAddr,uint16_t writeAddress, uint16_t data); void MLX90640_I2CFreqSet(int freq); //#ifdef __cplusplus //} //#endif #endif 

硬件IIC移植

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/124612.html

(0)
上一篇 2025-10-05 21:13
下一篇 2025-10-05 21:15

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信