MXL90614红外线测温传感器

news/2024/11/24 7:30:04/

特性和优点:
体积小,成本低
易集成
宽温度范围内的出厂校准设置:
传感器温度范围-40…+125 °C
物体温度范围-70…+380 °C
Ta和To 由0到+50°C 温度范围内,精度可达到0.5°C
(医用) 高精度校准
测量辨析度可达 0.02°C
单个和双重视野版本
兼容SMBus数字接口
客户定制的PWM连续读数输出
3V和 5V 电源电压
电源电压可从 8…16V 调节
节能工作模式
适用于不同应用领域的多种封装方式和测量方式
车用级别标准
应用实例:
高精度无接触测量
用于车用空调控制系统的温度舒适度传感器
用于住宅,商业和工业建筑的空调温度感应元件
挡风玻璃防雾应用
汽车视野死角检测
工业移动元件温度控制
打印机、复印机温度控制
家电温度控制
卫生保健
家畜监控
移动物体探测
多区域温度控制 – 两线通信可支持多达100个传感器
热动继电器 / 警报
体温测量  

MLX90614是一款红外非接触温度计。TO-39金属封装里同时集成了红外感应热电堆探测器芯片和信号处理专用集成芯片。
由于集成了低噪声放大器、17位模数转换器和强大的数字信号处理单元,使得高精度和高分辨度的温度计得以实现。
温度计具备出厂校准化,有数字PWM和SMBus(系统管理总线)输出模式。
作为标准,配置为10位的PWM输出格式用于连续传送温度范围为-20…120 °C的物体温度,其分辨率为0.14 °C。POR默认模式是SMBus输出格式。

     时序

        SCL 引脚的辅助功能 (齐纳二极管) 会给时钟脉冲增加下脉冲信号 (5V 版本) ,如图所示。 (见图 9) 这个脉冲是由片上合成齐纳二极管的瞬态响应造成的,典型时间大约为15μs。SCL线上电抗增加也会加剧该效应。该脉冲不会影响MLX90614识别SCL的上升沿。但可能会妨碍总线上非MLX90614从动器件的正常工作。

 

      PWM/SDA 的数据必须在SCL为低时改变。 (SCL下降沿后间隔至少) 在SCL的上升沿,MD和SD的数据被读出,建议在SCL为低电平的中间时刻改变数据。

     睡眠模式
     MLX90614可通过SMBus接口发送“进入睡眠模式”命令来进入睡眠模式。5V版本没有该功能。为了将电流损耗降为2.5uA (典型值),在模式中SCL保持低电平 。通过将SCL引脚置为高电平,并将PWM/SDA引脚保持低电平不少于tDDq=80ms来使 MLX90614回到POR默认模式 (通过重置 POR)
     如果EEPROM 配置为 PWM模式, (EN_PWM 为高) 在唤醒器件之后,并PWM control[2], PPODB为1,将选择PWM模式,MLX90614会通过推挽式输出PWM脉冲序列。

 退出睡眠模式

       在退出睡眠模式后,间隔0.25s(典型值),才输出数据。第一次测量时片上IIR滤波器被跳过。所有测量结果都会通过由EEPROM设置的嵌入式数字滤波器。嵌入式滤波器的详细介绍请参考www.melexis.com网站上的应用指南“理解MLX90614片上信号滤波器”。
       将SCL 引脚置为低以降低引脚上的漏电流。 (合成齐纳二极管接于该引脚)

       PWM 使能
       下图显示了在PWM使能情况下,切换到SMBus的方式。 (POR后MLX90614为出厂默认输出方式SMBus,,PWM 未使能)。注意SCL引脚需要保持高电平以便使用PWM。

      如果PWM 使能, MLX90614’s 需要SMBus请求状态使PWM不使能并在开始SMBus通信之前重新配置PWM/SDA引脚。一旦PWM未使能,它只能通过切断-打开电源或是退出睡眠模式来使其使能。The MLX90614’s SMBus 请求状态需要将SCL引脚持续多于请求时间 (tREQ) >1,44ms保持为低电平。此情形下SDA线上的数据被忽略。

配置地址

#define ACK     0
#define    NACK 1
#define SA                0x00 //从机地址,单个MLX90614时地址为0x00,多个时地址默认为0x5a
#define RAM_ACCESS        0x00 //RAM access command
#define EEPROM_ACCESS    0x20 //EEPROM access command
#define RAM_TOBJ1        0x07 //To1 address in the eeprom

#define SMBUS_PORT        GPIOB
#define SMBUS_SCK        GPIO_Pin_12
#define SMBUS_SDA        GPIO_Pin_13

#define RCC_APB2Periph_SMBUS_PORT        RCC_APB2Periph_GPIOB

#define SMBUS_SCK_H()        SMBUS_PORT->BSRR = SMBUS_SCK
#define SMBUS_SCK_L()        SMBUS_PORT->BRR = SMBUS_SCK
#define SMBUS_SDA_H()        SMBUS_PORT->BSRR = SMBUS_SDA
#define SMBUS_SDA_L()        SMBUS_PORT->BRR = SMBUS_SDA

#define SMBUS_SDA_PIN()        SMBUS_PORT->IDR & SMBUS_SDA //读取引脚电平

配置功能

void SMBus_StartBit(void)
{
    SMBUS_SDA_H();        // Set SDA line
    SMBus_Delay(5);        // Wait a few microseconds
    SMBUS_SCK_H();        // Set SCL line
    SMBus_Delay(5);        // Generate bus free time between Stop
    SMBUS_SDA_L();        // Clear SDA line
    SMBus_Delay(5);        // Hold time after (Repeated) Start
    // Condition. After this period, the first clock is generated.
    //(Thd:sta=4.0us min)
    SMBUS_SCK_L();        // Clear SCL line
    SMBus_Delay(5);        // Wait a few microseconds
}


void SMBus_StopBit(void)
{
    SMBUS_SCK_L();        // Clear SCL line
    SMBus_Delay(5);        // Wait a few microseconds
    SMBUS_SDA_L();        // Clear SDA line
    SMBus_Delay(5);        // Wait a few microseconds
    SMBUS_SCK_H();        // Set SCL line
    SMBus_Delay(5);        // Stop condition setup time(Tsu:sto=4.0us min)
    SMBUS_SDA_H();        // Set SDA line
}


u8 SMBus_SendByte(u8 Tx_buffer)
{
    u8    Bit_counter;
    u8    Ack_bit;
    u8    bit_out;

    for(Bit_counter=8; Bit_counter; Bit_counter--)
    {
        if (Tx_buffer&0x80)
        {
            bit_out=1;   // If the current bit of Tx_buffer is 1 set bit_out
        }
        else
        {
            bit_out=0;  // else clear bit_out
        }
        SMBus_SendBit(bit_out);        // Send the current bit on SDA
        Tx_buffer<<=1;                // Get next bit for checking
    }

    Ack_bit=SMBus_ReceiveBit();        // Get acknowledgment bit
    return    Ack_bit;
}


void SMBus_SendBit(u8 bit_out)
{
    if(bit_out==0)
    {
        SMBUS_SDA_L();
    }
    else
    {
        SMBUS_SDA_H();
    }
    SMBus_Delay(2);                    // Tsu:dat = 250ns minimum
    SMBUS_SCK_H();                    // Set SCL line
    SMBus_Delay(6);                    // High Level of Clock Pulse
    SMBUS_SCK_L();                    // Clear SCL line
    SMBus_Delay(3);                    // Low Level of Clock Pulse
//    SMBUS_SDA_H();                    // Master release SDA line ,
    return;
}


u8 SMBus_ReceiveBit(void)
{
    u8 Ack_bit;

    SMBUS_SDA_H();          //引脚靠外部电阻上拉,当作输入
    SMBus_Delay(2);            // High Level of Clock Pulse
    SMBUS_SCK_H();            // Set SCL line
    SMBus_Delay(5);            // High Level of Clock Pulse
    if (SMBUS_SDA_PIN())
    {
        Ack_bit=1;
    }
    else
    {
        Ack_bit=0;
    }
    SMBUS_SCK_L();            // Clear SCL line
    SMBus_Delay(3);            // Low Level of Clock Pulse

    return    Ack_bit;
}


u8 SMBus_ReceiveByte(u8 ack_nack)
{
    u8     RX_buffer;
    u8    Bit_Counter;

    for(Bit_Counter=8; Bit_Counter; Bit_Counter--)
    {
        if(SMBus_ReceiveBit())            // Get a bit from the SDA line
        {
            RX_buffer <<= 1;            // If the bit is HIGH save 1  in RX_buffer
            RX_buffer |=0x01;
        }
        else
        {
            RX_buffer <<= 1;            // If the bit is LOW save 0 in RX_buffer
            RX_buffer &=0xfe;
        }
    }
    SMBus_SendBit(ack_nack);            // Sends acknowledgment bit
    return RX_buffer;
}


void SMBus_Delay(u16 time)
{
    u16 i, j;
    for (i=0; i<4; i++)
    {
        for (j=0; j<time; j++);
    }
}


void SMBus_Init()
{
    GPIO_InitTypeDef    GPIO_InitStructure;

    /* Enable SMBUS_PORT clocks */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SMBUS_PORT, ENABLE);

    /*配置SMBUS_SCK、SMBUS_SDA为集电极开漏输出*/
    GPIO_InitStructure.GPIO_Pin = SMBUS_SCK | SMBUS_SDA;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SMBUS_PORT, &GPIO_InitStructure);

    SMBUS_SCK_H();
    SMBUS_SDA_H();
}


u16 SMBus_ReadMemory(u8 slaveAddress, u8 command)
{
    u16 data;            // Data storage (DataH:DataL)
    u8 Pec;                // PEC byte storage
    u8 DataL=0;            // Low data byte storage
    u8 DataH=0;            // High data byte storage
    u8 arr[6];            // Buffer for the sent bytes
    u8 PecReg;            // Calculated PEC byte storage
    u8 ErrorCounter;    // Defines the number of the attempts for communication with MLX90614

    ErrorCounter=0x00;                // Initialising of ErrorCounter
    slaveAddress <<= 1;    //2-7位表示从机地址
    
    do
    {
repeat:
        SMBus_StopBit();                //If slave send NACK stop comunication
        --ErrorCounter;                    //Pre-decrement ErrorCounter
        if(!ErrorCounter)                 //ErrorCounter=0?
        {
            break;                        //Yes,go out from do-while{}
        }

        SMBus_StartBit();                //Start condition
        if(SMBus_SendByte(slaveAddress))//Send SlaveAddress 最低位Wr=0表示接下来写命令
        {
            goto    repeat;                //Repeat comunication again
        }
        if(SMBus_SendByte(command))        //Send command
        {
            goto    repeat;                //Repeat comunication again
        }

        SMBus_StartBit();                    //Repeated Start condition
        if(SMBus_SendByte(slaveAddress+1))    //Send SlaveAddress 最低位Rd=1表示接下来读数据
        {
            goto    repeat;                 //Repeat comunication again
        }

        DataL = SMBus_ReceiveByte(ACK);    //Read low data,master must send ACK
        DataH = SMBus_ReceiveByte(ACK); //Read high data,master must send ACK
        Pec = SMBus_ReceiveByte(NACK);    //Read PEC byte, master must send NACK
        SMBus_StopBit();                //Stop condition

        arr[5] = slaveAddress;        //
        arr[4] = command;            //
        arr[3] = slaveAddress+1;    //Load array arr
        arr[2] = DataL;                //
        arr[1] = DataH;                //
        arr[0] = 0;                    //
        PecReg=PEC_Calculation(arr);//Calculate CRC
    }
    while(PecReg != Pec);        //If received and calculated CRC are equal go out from do-while{}

    data = (DataH<<8) | DataL;    //data=DataH:DataL
    return data;
}


u8 PEC_Calculation(u8 pec[])
{
    u8     crc[6];
    u8    BitPosition=47;
    u8    shift;
    u8    i;
    u8    j;
    u8    temp;

    do
    {
        /*Load pattern value 0x000000000107*/
        crc[5]=0;
        crc[4]=0;
        crc[3]=0;
        crc[2]=0;
        crc[1]=0x01;
        crc[0]=0x07;

        /*Set maximum bit position at 47 ( six bytes byte5...byte0,MSbit=47)*/
        BitPosition=47;

        /*Set shift position at 0*/
        shift=0;

        /*Find first "1" in the transmited message beginning from the MSByte byte5*/
        i=5;
        j=0;
        while((pec[i]&(0x80>>j))==0 && i>0)
        {
            BitPosition--;
            if(j<7)
            {
                j++;
            }
            else
            {
                j=0x00;
                i--;
            }
        }/*End of while */

        /*Get shift value for pattern value*/
        shift=BitPosition-8;

        /*Shift pattern value */
        while(shift)
        {
            for(i=5; i<0xFF; i--)
            {
                if((crc[i-1]&0x80) && (i>0))
                {
                    temp=1;
                }
                else
                {
                    temp=0;
                }
                crc[i]<<=1;
                crc[i]+=temp;
            }/*End of for*/
            shift--;
        }/*End of while*/

        /*Exclusive OR between pec and crc*/
        for(i=0; i<=5; i++)
        {
            pec[i] ^=crc[i];
        }/*End of for*/
    }
    while(BitPosition>8); /*End of do-while*/

    return pec[0];
}

最后计算出温度值

float SMBus_ReadTemp(void)
{   
    return SMBus_ReadMemory(SA, RAM_ACCESS|RAM_TOBJ1)*0.02-273.15+2;
}

H文件

#ifndef __BSP_MLX90614_H
#define __BSP_MLX90614_H

#include "stm32f10x.h"

void SMBus_StartBit(void);
void SMBus_StopBit(void);
void SMBus_SendBit(u8);
u8 SMBus_SendByte(u8);
u8 SMBus_ReceiveBit(void);
u8 SMBus_ReceiveByte(u8);
void SMBus_Delay(u16);
void SMBus_Init(void);
u16 SMBus_ReadMemory(u8, u8);
u8 PEC_Calculation(u8*);
float SMBus_ReadTemp(void);    //获取温度值 
#endif

主函数(这里使用的窜口打印)

#include "bsp-led.h"
#include "bsp-usart.h"
#include "bsp-mlx90614.h"

void delay(uint32_t i)
{
  for(;i!=0;i--);
}


int main(void)
{
        float Temperature;
        USART_Config();
        SMBus_Init();
        while(1)
         {
            Temperature=SMBus_ReadTemp();
          printf("The Temperature is:%f\n",Temperature);
            delay(0xffffff);

          }

    }


http://www.ppmy.cn/news/520250.html

相关文章

开发框架前后端分离的好处是什么

关于将前端和后端保持在一起或分开&#xff0c;存在广泛的意见分歧。唯一重要的是&#xff0c;这两个组件对于开发成熟的应用程序都是必需的。 考虑&#xff1a;紧密耦合的前端和后端 许多人认为后端和前端的分离是一个坏主意&#xff0c;这两个角色之间没有太大区别。 以下…

重新理解微服务之终究绕不过这4个坎之(一)

写在前头 大家曾经有没有遇过日常技术交流的时候&#xff0c;会讨论某某技术之间的关系是什么&#xff0c;某些技术是否应该用到微服务。我相信热爱技术交流的您&#xff0c;就算不是在微服务这里领域&#xff0c;或多或少都会跟其他同行会做一些争议话题的探讨&#xff0c;而…

为啥海康摄像头网页无法预览

最近在做IPC相关的业务&#xff0c;用谷歌、火狐都无法预览摄像头画面&#xff0c;即使装了插件也不行&#xff0c;后面发现了&#xff0c;要用IE打开&#xff0c;才能预览。。。。。 转载于:https://www.cnblogs.com/132818Creator/p/10980880.html

海康威视定时截图保存本地

import cv2 import time import os.path import datetime url "rtsp://admin:a123456789192.168.1.22/Streaming/Channels/1" #rtsp://用户名:密码ip地址/Streaming/Channels/1最后面的1是因为我选择1会显示出我要的内容&#xff0c;有的是1或者3或者4 cap cv2.Vid…

iVMS-4200 Mac 版监控客户端切换中文语言的方法

安装好最新版本之后&#xff0c;直接跳转到&#xff08;或者在应用程序中的 iVMS-4200 图标上鼠标右键&#xff0c;显示包内容&#xff09;/Applications/iVMS-4200.app/Contents/MacOS/&#xff0c;之后用文本编辑器修改 Setup.xml&#xff1a; <?xml version1.0 encodin…

EasyNVR通过Onvif方式接入的设备云台控制无反应是什么原因?

EasyNVR平台可以通过Onvif协议与摄像头进行网络连接&#xff0c;并实现摄像头的PTZ云台控制&#xff0c;PTZ控制包含转动、变焦等&#xff08;需要摄像头带云台功能&#xff09;。与EasyGBS平台不同&#xff0c;EasyGBS是通过国标GB28181协议接入实现云台的控制功能。对EasyNVR…

海康威视SDK登录失败,错误码为8

耗时几天&#xff0c;终于找到真因 问题背景&#xff1a;调试正常&#xff0c;突然之间啥都没改&#xff0c;一直报8错误。 一试 官网上再次下载最新版本SDK https://open.hikvision.com/download/5cda567cf47ae80dd41a54b3?type10 HCNetSDK.java版本较多&#xff0c;适合…