0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

CW32模块使用 MLX90614无接触测温传感器

CW32生态社区 来源:CW32生态社区 作者:CW32生态社区 2024-11-14 17:50 次阅读

MLX90614 系列模块是一组通用的红外测温模块。在出厂前该模块已进行校验及线性化,具有非接触、体积小、精度高,成本低等优点。被测目标温度和环境温度能通过单通道输出,并有两种输出接口,适合于汽车空调、室内暖气、家用电器、手持设备以及医疗设备应用等。测温方式可分为接触式和非接触式,接触式测温只能测量被测物体与测温传感器达到热平衡后的温度,所以响应时间长,且极易受环境温度的影响;而红外测温是根据被测物体的红外辐射能量来确定物体的温度,不与被测物体接触,具有影响动被测物体温度分布场,温度分辨率高、响应速度快、测温范围广、不受测温上限的限制、稳定性好等特点,所以我们选择mlx90614来作为红外测温模块。

单片机与mlx90614红外测温模块之间通信的方式是“类IIC”通信,意思就是通信方式跟IIC通信方式很像但又不是IIC,它有另外一个名字叫做SMBus。SMBus (System Management Bus)是 1995 年由 intel 公司提出的一种高效同步串行总线,SMBus 只有两根信号线:双向数据线和时钟信号线,容许 CPU 与各种外围接口器件以串行方式进行通信、交换信息,即可以提高传输速度也可以减小器件的资源占用,另外即使在没有SMBus 接口的单片机上也可利用软件进行模拟

1、模块来源

模块实物展示:

wKgaomc1x9WAD7yOAAATWJHUNuA281.jpg


资料下载链接:
https://pan.baidu.com/s/1AsEBvVCiNAvTKqTeGSA60w
提取码:g06n

2、规格参数

工作电压:4.5~5.5V

工作电流:1.3~2.5mA

以上信息见厂家资料文件

3、移植过程

我们的目标是将例程移植至CW32F030C8T6开发板上【能够测量物体温度和环境温度的功能】。首先要获取资料,查看数据手册应如何实现读取数据,再移植至我们的工程。

3.1查看资料

MLX90614中有两个存储器,分别为EEPROMRAM

MLX90614中共有32个字长为16位的EEPROM存储单元,其地址为000H—01FH。EEPROM中所有的寄存器都是可以通过SMBus进行读取,但只有部分寄存器是可以进行改写的(地址为0x00, 0x01, 0x02, 0x03, 0x04, 0x05*,0x0E, 0x0F, 0x19)。可改写部分如下图所示。因在出厂前模块已进行校验及线性化,所以我们直接使用默认参数,不需要修改。

wKgZomc1x9WAUAqgAABQPNXj6Y0849.jpg

wKgZomc1x9uAd0YwAAB93v_WcoI622.jpg

MLX90614中总共有32个17位的RAM存储单元,用户不能通过RAM来写入数据,只能读取RAM中的部分存储单元读取16位存储数据。其采集的环境温度数据保存在地址06H存储单元中,采集的被测物体温度数据存储在07H存储单元中。因此运用存储在RAM地址中的数据,通过公式的计算,可以得到环境温度Ta及被测物体温度数据To。

wKgaomc1x9uAaSjmAABKEBGcpjY365.jpg

需要注意的是数据的低8位在前面,高8位在后。

wKgZomc1x9yAB3CCAAB_qI9TIAc675.jpg

器件地址(Slave Address)在数据手册中有说明,默认器件地址为0X5A;

wKgaomc1x9yAPE0eAADMBBBZtO8770.jpg

命令(Command)是根据要控制的是RAM还是eeprom来决定一个字节中的BIT7~BIT5。剩余的BIT4~BIT0由要操控的地址决定。

wKgZomc1x92APrCdAABa1tudC4g239.jpg

例如,我要读取RAM的Ta温度数据,则命令组成见下表。其中RAM地址为000x_xxxx,Ta温度数据地址为0x06=0000_0110,只取低5位则为xxx0_0110。

wKgaomc1x92AB0A5AAAkLHuI5Y0186.jpg

PEC是一个多项式为X8+X2+X1+1的CRC-8校验数据。

在数据手册中举了两个例子。其中0xB4为器件地址左移一位后的值。

wKgaomc1x-OAEwYQAACdgLSntN8230.jpg

得到温度的原始数据后,根据数据手册的说明进行换算即可得到温度。

wKgZomc1x-OAICLdAABV6ovySeo755.jpg

以上是手册中举了一个例子,如果读取到的温度数据是0X3AF7,其10进制为15095,将10进制数 除以50或者乘以0.02得到301.9,再减去273.15即可得到实际温度。

温度 = 温度原始数据 * 0.02 - 273.15

该温度换算公式对To和Ta都适用。

3.2引脚选择

wKgaomc1x-SAaWaKAAFuGlZ6O0o874.jpg

模块接线图

3.3移植至工程

工程模板参考入门手册的工程模板

移植步骤中的导入.c和.h文件与【CW32模块使用】DHT11温湿度传感器相同,只是将.c和.h文件更改为bsp_mlx90614.c与bsp_mlx90614.h。这里不再过多讲述,移植完成后面修改相关代码。

在文件bsp_mlx90614.c中,编写如下代码。

/*
 * Change Logs:
 * Date           Author       Notes
 * 2024-06-20     LCKFB-ALP    first version
 */

#include "bsp_mlx90614.h"
#include "stdio.h"


/******************************************************************
 * 函 数 名 称:MLX90614_GPIO_Init
 * 函 数 说 明:MLX90614的引脚初始化
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:MLX90614是5V,而且开发板开发板的引脚输出是3.3V,
 *             故设置引脚模式时,必须设置为开漏模式
******************************************************************/
void MLX90614_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct; // GPIO初始化结构体

    RCC_MLX90614_ENABLE();        // 使能GPIO时钟

    GPIO_InitStruct.Pins = GPIO_SCL|GPIO_SDA;             // GPIO引脚
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;           // 开漏输出
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;              // 输出速度高
    GPIO_Init(PORT_MLX90614, &GPIO_InitStruct);              // 初始化
}


/******************************************************************
 * 函 数 名 称:IIC_Start
 * 函 数 说 明:IIC起始时序
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void IIC_Start(void)
{
        SDA_OUT();

        SDA(1);
        delay_us(5);
        SCL(1);
        delay_us(5);

        SDA(0);
        delay_us(5);
        SCL(0);
        delay_us(5);

}
/******************************************************************
 * 函 数 名 称:IIC_Stop
 * 函 数 说 明:IIC停止信号
 * 函 数 形 参:无
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void IIC_Stop(void)
{
        SDA_OUT();
        SCL(0);
        SDA(0);

        SCL(1);
        delay_us(5);
        SDA(1);
        delay_us(5);

}

/******************************************************************
 * 函 数 名 称:IIC_Send_Ack
 * 函 数 说 明:主机发送应答或者非应答信号
 * 函 数 形 参:0发送应答  1发送非应答
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void IIC_Send_Ack(unsigned char ack)
{
        SDA_OUT();
        SCL(0);
        SDA(0);
        delay_us(5);
        if(!ack) SDA(0);
        else     SDA(1);
        SCL(1);
        delay_us(5);
        SCL(0);
        SDA(1);
}


/******************************************************************
 * 函 数 名 称:I2C_WaitAck
 * 函 数 说 明:等待从机应答
 * 函 数 形 参:无
 * 函 数 返 回:0有应答  1超时无应答
 * 作       者:LC
 * 备       注:无
******************************************************************/
unsigned char I2C_WaitAck(void)
{
        char ack = 0;
        unsigned char ack_flag = 10;
        SCL(0);
        SDA(1);
        SDA_IN();
        delay_us(5);
        SCL(1);
        delay_us(5);

        while( (SDA_GET()==1) && ( ack_flag ) )
        {
                        ack_flag--;
                        delay_us(5);
        }

        if( ack_flag <= 0 )
        {
                        IIC_Stop();
                        return 1;
        }
        else
        {
                        SCL(0);
                        SDA_OUT();
        }
        return ack;
}

/******************************************************************
 * 函 数 名 称:Send_Byte
 * 函 数 说 明:写入一个字节
 * 函 数 形 参:dat要写人的数据
 * 函 数 返 回:无
 * 作       者:LC
 * 备       注:无
******************************************************************/
void Send_Byte(uint8_t dat)
{
        int i = 0;
        SDA_OUT();
        SCL(0);//拉低时钟开始数据传输

        for( i = 0; i < 8; i++ )
        {
                SDA( (dat & 0x80) >> 7 );
                delay_us(1);
                SCL(1);
                delay_us(5);
                SCL(0);
                delay_us(5);
                dat< <=1;
        }
}

/******************************************************************
 * 函 数 名 称:Read_Byte
 * 函 数 说 明:IIC读时序
 * 函 数 形 参:无
 * 函 数 返 回:读到的数据
 * 作       者:LC
 * 备       注:无
******************************************************************/
unsigned char Read_Byte(void)
{
        unsigned char i,receive=0;
        SDA_IN();//SDA设置为输入
        for(i=0;i< 8;i++ )
        {
                SCL(0);
                delay_us(5);
                SCL(1);
                delay_us(5);
                receive< <=1;
                if( SDA_GET() )
                {
                        receive|=1;
                }
                delay_us(5);
        }
        SCL(0);
        return receive;
}


///******************************************************************
// * 函 数 名 称:PEC_Calculation
// * 函 数 说 明:PEC校验
// * 函 数 形 参:pec要校验的数据地址   len校验的长度
// * 函 数 返 回:校验后的值
// * 作       者:LC
// * 备       注:无
//******************************************************************/
//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++ )
//        {
//            if( crc&0x80 )
//            {
//                crc = (crc< <1)^0x07;
//            }
//            else
//            {
//                crc = (crc< <1);
//            }
//        }
//    }
//    return crc;
//}

/************************************************************
 * 函数名称:MLX90615_Read
 * 函数说明:读取MLX90615的温度
 * 型    参:SlaveAddr = 器件地址  RegAddr = 要操作的寄存器地址
 * 返 回 值:温度值
 * 备    注:   SlaveAddr = 0X5A默认器件地址
 *              RegAddr   = 0X07读取被测量物体温度
 *              RegAddr   = 0X06读取环境温度
*************************************************************/
float MLX90614_Read(unsigned char SlaveAddr, unsigned char RegAddr)
{
    IIC_Start();
    Send_Byte((SlaveAddr < < 1) | 0); // 写命令
    if(I2C_WaitAck()) {
        IIC_Stop();
        return 0.0;
    }

    Send_Byte(RegAddr); // 寄存器地址
    if(I2C_WaitAck()) {
        IIC_Stop();
        return 0.0;
    }

//        delay_ms(1);

    IIC_Start();
    Send_Byte((SlaveAddr < < 1) | 1); // 读命令
    if(I2C_WaitAck()) {
        IIC_Stop();
        return 0.0;
    }

    uint8_t lowByte = Read_Byte(); // 低8位
    IIC_Send_Ack(0);
    uint8_t highByte = Read_Byte(); // 高8位
    IIC_Send_Ack(1);
    IIC_Stop();

    uint16_t tempRaw = (highByte < < 8) | lowByte;
    float temperature = (tempRaw * 0.02) - 273.15;

    return temperature;
}

在文件bsp_mlx90614.h中,编写如下代码。

/*
 * Change Logs:
 * Date           Author       Notes
 * 2024-06-20     LCKFB-ALP    first version
 */

#ifndef _BSP_MLX90614_H_
#define _BSP_MLX90614_H_

#include "board.h"

//端口移植
#define RCC_MLX90614_ENABLE()   __RCC_GPIOA_CLK_ENABLE()
#define PORT_MLX90614               CW_GPIOA


#define GPIO_SDA                    GPIO_PIN_1
#define GPIO_SCL                    GPIO_PIN_0

//设置SDA输出模式
#define SDA_OUT()   {        
                        GPIO_InitTypeDef GPIO_InitStruct;                
                        GPIO_InitStruct.Pins = GPIO_SDA;                 
                        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;      
                        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;         
                        GPIO_Init(PORT_MLX90614, &GPIO_InitStruct);         
                     }
//设置SDA输入模式
#define SDA_IN()    {        
                        GPIO_InitTypeDef GPIO_InitStruct;                
                        GPIO_InitStruct.Pins = GPIO_SDA;                 
                        GPIO_InitStruct.Mode = GPIO_MODE_INPUT_PULLUP;   
                        GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;         
                        GPIO_Init(PORT_MLX90614, &GPIO_InitStruct);         
                    }
//获取SDA引脚的电平变化
#define SDA_GET()       GPIO_ReadPin(PORT_MLX90614, GPIO_SDA)
//SDA与SCL输出
#define SDA(x)          GPIO_WritePin(PORT_MLX90614, GPIO_SDA, (x?GPIO_Pin_SET:GPIO_Pin_RESET) )
#define SCL(x)          GPIO_WritePin(PORT_MLX90614, GPIO_SCL, (x?GPIO_Pin_SET:GPIO_Pin_RESET) )



void MLX90614_GPIO_Init(void);
float MLX90614_Read(unsigned char SlaveAddr, unsigned char RegAddr);

void IIC_Stop(void);
#endif

4、移植验证

在自己工程中的main主函数中,编写如下。

/*
 * Change Logs:
 * Date           Author       Notes
 * 2024-06-20     LCKFB-ALP    first version
 */
#include "board.h"
#include "stdio.h"
#include "bsp_uart.h"
#include "bsp_mlx90614.h"

int32_t main(void)
{
    board_init();        // 开发板初始化

    uart1_init(115200);        // 串口1波特率115200

    MLX90614_GPIO_Init();
    printf("Startrn");
    while(1)
    {
        float t = MLX90614_Read(0X5A, 0X07);
        if( t != 0)
        {
            printf("temperature = %.2frn", t);
        }
        delay_ms(1000);
    }
}

移植现象:测量手心温度为36℃左右。

wKgZomc1x-SAP8VhAAC7wnooxI0678.jpg

模块移植成功案例代码:

链接:https://pan.baidu.com/s/1Ts1A7Eqng7yCa2YabmI6_A?pwd=LCKF

提取码:LCKF

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 传感器
    +关注

    关注

    2548

    文章

    50635

    浏览量

    751669
  • CW32
    +关注

    关注

    1

    文章

    183

    浏览量

    575
收藏 人收藏

    评论

    相关推荐

    MLX90614红外温度传感器的驱动设计与实现

    红外温度传感器一般用于非接触式的温度检测。在我们的系统中经常会有这样的需求。所以我们将其设计为通用的驱动库以备复用。这一篇我们将讲述MLX90614红外温度传感器驱动的设计与实现。
    发表于 12-12 14:53 7350次阅读
    <b class='flag-5'>MLX90614</b>红外温度<b class='flag-5'>传感器</b>的驱动设计与实现

    基于MLX90614的非接触式体温测量系统设计

    根据辐射测温原理设计制作温度测量系统。采用Melexis公司的MLX90614接触测量的红外温度传感器,通过SMBus协议与AT89S51单片机通讯,并通过单片机系统驱动液晶显示
    发表于 03-08 14:37

    红外测温传感器MLX90614测温的响应时间是多少??????

    红外测温传感器MLX90614测温的响应时间是多少??????
    发表于 05-16 20:59

    怎样去设计一种基于MLX90614和OpenMV-H7的温度传感器

    MLX90614系列模块是什么?OpenMV-H7又是什么?怎样去设计一种基于MLX90614和OpenMV-H7的温度传感器呢?
    发表于 11-10 07:49

    为什么无法使用MSP430进行调试MLX90614红外测温传感器

    在用MSP430G2553调试MLX90614红外测温传感器时,输出的值始终为-273.1,我认为应该是读取寄存内容为0所致,我的程序使用STM32程序修改后进行调试的,原32程序输
    发表于 11-29 06:08

    MLX90614简介

    1.MLX90614简介MLX90614是一款价格昂贵的非接触式红外温度传感器,尤其在疫情的影响下,其价格更是高不可攀,该传感器主要用于不能
    发表于 12-08 06:51

    mlx90614进行红外测温的方法

    做项目使用了NRF51822,要用mlx90614进行红外测温,分享一下相关的使用。mlx90614是一款红外非接触温度计,有多个型号,BAA、DCI等,不同封装的
    发表于 01-10 08:17

    MLX90614医用级红外温度传感器的驱动程序编写

    咚咚咚————【封装驱动】MLX90614医用级红外温度传感器,自己编写封装的驱动程序。/********************************************主控芯片:STM32
    发表于 01-25 07:09

    MLX90614系列传感器搭配DM小板完成精准测温

    。小板搭载我迈莱芯MLX90614全系列传感器及我司定制的DM801DH传感器,使用方便。模组通信方式为串口TTL通信,并且人体温度数据 我司已转换为十进制,也可以通过串口调试工具在电脑上安装调试助手查看
    发表于 11-22 13:37

    如何使用 MLX90614 红外测温仪实现 SMBus 通信

    本文档介绍了 PIC 微控制中的 MLX90614 红外温度计 SMBus 通信。本文档还介绍了红外测温仪的应用,以及典型电路示例和所用开发工具的汇编程序和 C 示例。 范围 本应用笔记介绍了如
    的头像 发表于 06-21 17:47 8103次阅读
    如何使用 <b class='flag-5'>MLX90614</b> 红外<b class='flag-5'>测温</b>仪实现 SMBus 通信

    使用STM8S和MLX90614手持非接触红外测温枪设计的工程文件和程序

    基于STM8S手持非接触红外测温MLX90614 额温枪设计,包含原理图、PCB、源程序等
    发表于 02-04 08:00 0次下载
    使用STM8S和<b class='flag-5'>MLX90614</b>手持非<b class='flag-5'>接触</b>红外<b class='flag-5'>测温</b>枪设计的工程文件和程序

    温度传感器MLX90614的STM32驱动实现

    1.MLX90614简介MLX90614是一款价格昂贵的非接触式红外温度传感器,尤其在疫情的影响下,其价格更是高不可攀,该传感器主要用于不能
    发表于 11-25 20:06 67次下载
    温度<b class='flag-5'>传感器</b><b class='flag-5'>MLX90614</b>的STM32驱动实现

    基于STM32的MLX90614人体红外测温

      今天分享一个项目是做一个红外测温的。这个东西网上都有现成的资料和代码,做起来不难。关于红外测温用的芯片是mlx90614。...
    发表于 01-26 19:06 85次下载
    基于STM32的<b class='flag-5'>MLX90614</b>人体红外<b class='flag-5'>测温</b>枪

    使用mlx90614 ir进行非接触式温度测量

    电子发烧友网站提供《使用mlx90614 ir进行非接触式温度测量.zip》资料免费下载
    发表于 10-31 11:19 1次下载
    使用<b class='flag-5'>mlx90614</b> ir进行非<b class='flag-5'>接触</b>式温度测量

    使用MLX90614红外非接触式温度传感器

    电子发烧友网站提供《使用MLX90614红外非接触式温度传感器.zip》资料免费下载
    发表于 11-11 15:21 8次下载
    使用<b class='flag-5'>MLX90614</b>红外非<b class='flag-5'>接触</b>式温度<b class='flag-5'>传感器</b>