【mcuclub】红外测温-MLX90614

发布于:2022-11-09 ⋅ 阅读:(10) ⋅ 点赞:(0) ⋅ 评论:(0)

一、实物图

二、原理图

编号 名称 功能
1 VCC 电源正
2 GND 电源地
3 SCL 串行时钟输入
4 SDA 串行地址和数据输入/输出

三、简介

MLX90614是一种红外温度计,用于非接触式温度测量。红外测温是根据被测物体的红外辐射能量来确定物体的温度,不与被测物体接触,具有不影响被测物体温度分布场,温度分辨率高、响应速度快、测温范围广、不受测温上限的限制、稳定性好等特点。适合于汽车空调、室内暖气、家用电器、手持设备以及医疗设备应用等。

MLX90614的出厂校准温度范围很广:环境温度为-40°C——125°C,目标温度为-70°C——380°C。测量值是传感器视场中所有物体的平均温度。在室温下,MLX90614的标准精确度为±0.5°C。

四、工作原理

MLX90614由MLX81101红外热电堆传感器和包括含有稳压电路、低噪声放大器、A/D转换器、DSP单元、脉宽调制电路及逻辑控制电路的MLX90302信号处理芯片构成。

其工作原理为:红外热电堆传感器输出的温度信号经过内部低噪声、低失调的运算放大器(OPA)放大后经过A/D转换器(ADC)转换为17位数字信号通过可编程FIR及IIR低通数字滤波器(即DSP)处理后输出,输出结果存储在其内部RAM存储单元中。

五、通信协议(SMBus通信)

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

1、时序结构

起始信号:SCL高电平期间,SDA从高电平切换到低电平

停止信号:SCL高电平期间,SDA从低电平切换到高电平

代码如下:

/****

*******I2C总线启动信号

*****/

void MLX90614_IIC_Start(void)

{

   MLX90614_SDA = 1;

   MLX90614_SCL = 1;

   MLX90614_IIC_Delay(DELAY_TIME);

   MLX90614_SDA = 0;

   MLX90614_IIC_Delay(DELAY_TIME);

   MLX90614_SCL = 0;

}

/****

*******I2C总线停止信号

*****/

void MLX90614_IIC_Stop(void)

{

   MLX90614_SDA = 0;

   MLX90614_SCL = 1;

   MLX90614_IIC_Delay(DELAY_TIME);

   MLX90614_SDA = 1;

   MLX90614_IIC_Delay(DELAY_TIME);

}

发送应答:在接收完一个字节之后,主机在下一个时钟发送一位数据,数据0表示应答,数据1表示非应答。

接收应答:在发送完一个字节之后,主机在下一个时钟接收一位数据,判断从机是否应答,数据0表示应答,数据1表示非应答(主机在接收之前,需要释放SDA)。

代码如下:

/****

*******发送应答或非应答信号

*****/

void MLX90614_IIC_SendAck(bit ackbit)

{

   MLX90614_SCL = 0;

   MLX90614_SDA = ackbit;

   MLX90614_IIC_Delay(DELAY_TIME);

   MLX90614_SCL = 1;

   MLX90614_IIC_Delay(DELAY_TIME);

   MLX90614_SCL = 0;

   MLX90614_SDA = 1;

   MLX90614_IIC_Delay(DELAY_TIME);

}

/****

*******等待应答信号

*****/

bit MLX90614_IIC_WaitAck(void)

{

   bit ackbit;

   MLX90614_SDA = 1;

   MLX90614_SCL = 1;

   MLX90614_IIC_Delay(DELAY_TIME);

   ackbit = MLX90614_SDA;

   MLX90614_SCL = 0;

   MLX90614_IIC_Delay(DELAY_TIME);

   return ackbit;

}

发送一个字节:SCL低电平期间,主机将数据位依次放到SDA线上(高位在前),然后拉高SCL,主机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可发送一个字节。

代码如下:

/****

*******I2C总线发送一个字节数据

*****/

void MLX90614_IIC_SendByte(uchar byte)

{

   uchar i;

   MLX90614_SCL = 0;

   for(i=0; i<8; i++)

   {

      if(byte & 0x80)

         MLX90614_SDA = 1;

      else

         MLX90614_SDA = 0;

      MLX90614_IIC_Delay(DELAY_TIME);

      MLX90614_SCL = 1;

      MLX90614_IIC_Delay(DELAY_TIME);

      MLX90614_SCL = 0;

      MLX90614_IIC_Delay(DELAY_TIME);

      byte <<= 1;

   }

   MLX90614_IIC_WaitAck();

}

接收一个字节:SCL低电平期间,从机将数据位依次放到SDA总线上(高位在前),然后拉高SCL,从机将在SCL高电平期间读取数据位,所以SCL高电平期间SDA不允许有数据变化,依次循环上述过程8次,即可接收一个字节(主机在接收之前,需要释放SDA)。

代码如下:

/****

*******I2C总线接收一个字节数据

*****/

uchar MLX90614_IIC_RecByte(bit ackbit)

{

   uchar i, dat;

   MLX90614_SDA = 1;

   for(i=0; i<8; i++)

   {

      MLX90614_SCL = 1;

      MLX90614_IIC_Delay(DELAY_TIME);

      dat <<= 1;

      if(MLX90614_SDA)

         dat |= 1;

      MLX90614_SCL = 0;

      MLX90614_IIC_Delay(DELAY_TIME);

   }

   MLX90614_IIC_SendAck(ackbit);

   return dat;

}

2、MLX90614读取数据

Slave Address是MLX90614的识别地址,当一个系统中只有一个mlx90614时,该地址默认为00h。

Command是命令,共有四种模式分别为访问RAM、访问EEPROM、读取标示符、进入SLEEP模式。这里我用的是访问RAM即存储温度数据的存储器。访问RAM的命令为000x xxxx,xxxxx代表要读取/写入的内存地址的低五位。

RAM中不能写入数据,只能进行读取,并且只有有限数目是客户感兴趣的。

注:TA是环境温度,TOBJ1是物体温度。

代码如下:

/****

*******MLX90614读温度数据函数

*******返回值:扩大10倍的温度值,最后一位代表小数位

*****/

uint Mlx90614_Read_Temp(void)

{

   uchar Data_H,Data_L;

   uint T,Temp;

   EA = 0;

   MLX90614_IIC_Start();

   MLX90614_IIC_SendByte(MLX90614_SlaveAddress);

   MLX90614_IIC_SendByte(0x07);

   MLX90614_IIC_Start();

   MLX90614_IIC_SendByte(MLX90614_SlaveAddress + 1);

   Data_L = MLX90614_IIC_RecByte(MLX90614_ACK);

   Data_H = MLX90614_IIC_RecByte(MLX90614_ACK);

   MLX90614_IIC_Stop();

   EA = 1;

   /****温度换算****/

   T = Data_H*256 + Data_L;

   if(T*2 >= 27315)

      Temp = (T*2-27315) / 10;

   else

      Temp = (27315-T*2) / 10;

   Temp = Temp * 1.04;           //体表温度与实际体温换算

   return Temp;

}

六、流程设计

首先初始化引脚,然后发送起始位,再发送从机设备地址写,接下来发送命令地址,重新发送一次起始位,再发送从机设备地址读,然后先读取低字节数据,再读取高字节数据,最后发送结束位结束本次数据的读取。将读取的高字节数据和低字节数据整合为一个数据,通过公式换算最终得到温度值。