一、实物图
二、原理图
编号 | 名称 | 功能 |
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
{
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
}
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
{
MLX90614_SCL = 1;
MLX90614_IIC_Delay(DELAY_TIME);
dat
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;
}
六、流程设计
首先初始化引脚,然后发送起始位,再发送从机设备地址写,接下来发送命令地址,重新发送一次起始位,再发送从机设备地址读,然后先读取低字节数据,再读取高字节数据,最后发送结束位结束本次数据的读取。将读取的高字节数据和低字节数据整合为一个数据,通过公式换算最终得到温度值。