红外测温传感器MLX90614

阅读: 评论:0

红外测温传感器MLX90614

红外测温传感器MLX90614

【本文发布于,未经许可不得转载,转载须注明出处】


1、MLX90614使用SMBus进行通讯,很多文章都没能说清楚I2C和SMBus的区别。反正在这里,这两者没什么区别,无需纠结。

2、貌似需要搭配透镜使用才能有更好的精度和更远的测量距离。

3、无地址选择引脚,内部也无唯一ID,要实现一条总线上挂接多个MLX90614,需要单独给每一个传感器的EEPROM写入不同的地址值之后才能挂到总线上.(暂无此需求,未研究)


#ifndef __MLX90614_H__
#define __MLX90614_H__#include "public.h"#define MLX90614_FIXED_BUS_ADDR              0x00    //不可修改的地址
#define MLX90614_EEPROM_BUS_ADDR             0x00    //可修改的地址,保存于eeprom的地址0eh处#define MLX90614_MASK_RAM_ACCESS             0x00    //访问 RAM 或上此值
#define MLX90614_MASK_EEPROM_ACCESS          0x20    //访问 eeprom 或上此值                                            
#define MLX90614_MASK_READ_FLAG              0xf0    //访问 flag 或上此值                                            
#define MLX90614_ENTER_SLEEP_MODE            0xff    //                                          #define MLX90614_EEPROM_ADDR___TO_MAX           (MLX90614_MASK_EEPROM_ACCESS | 0x00)                                            
#define MLX90614_EEPROM_ADDR___TO_MIN           (MLX90614_MASK_EEPROM_ACCESS | 0x01)
#define MLX90614_EEPROM_ADDR___PWM_CTRL         (MLX90614_MASK_EEPROM_ACCESS | 0x02)
#define MLX90614_EEPROM_ADDR___TA_RANGE         (MLX90614_MASK_EEPROM_ACCESS | 0x03)
#define MLX90614_EEPROM_ADDR___EMISSIVITY       (MLX90614_MASK_EEPROM_ACCESS | 0x04)
#define MLX90614_EEPROM_ADDR___CONFIG_REG1      (MLX90614_MASK_EEPROM_ACCESS | 0x05)
#define MLX90614_EEPROM_ADDR___SMBUS_ADDR       (MLX90614_MASK_EEPROM_ACCESS | 0x0E)
#define MLX90614_EEPROM_ADDR___ID_NUMBER1       (MLX90614_MASK_EEPROM_ACCESS | 0x1C)
#define MLX90614_EEPROM_ADDR___ID_NUMBER2       (MLX90614_MASK_EEPROM_ACCESS | 0x1D)
#define MLX90614_EEPROM_ADDR___ID_NUMBER3       (MLX90614_MASK_EEPROM_ACCESS | 0x1E)
#define MLX90614_EEPROM_ADDR___ID_NUMBER4       (MLX90614_MASK_EEPROM_ACCESS | 0x1F)#define MLX90614_RAM_ADDR___RAW_DATA_IR_CH1           (MLX90614_MASK_RAM_ACCESS | 0x04)
#define MLX90614_RAM_ADDR___RAW_DATA_IR_CH2           (MLX90614_MASK_RAM_ACCESS | 0x05)
#define MLX90614_RAM_ADDR___TA                        (MLX90614_MASK_RAM_ACCESS | 0x06)     //环境温度
#define MLX90614_RAM_ADDR___TOBJ1                     (MLX90614_MASK_RAM_ACCESS | 0x07)     //物体温度
#define MLX90614_RAM_ADDR___TOBJ2                     (MLX90614_MASK_RAM_ACCESS | 0x08)#define MLX90614_SCL_PORT               PORT1
#define MLX90614_SCL_PIN                PIN5
#define MLX90614_SCL_PIN_MODE           OPENDRAIN_OUTPUT#define MLX90614_SDA_PORT               PORT1
#define MLX90614_SDA_PIN                PIN4
#define MLX90614_SDA_PIN_MODE_IN()           do {*((volatile uint8_t*)(&PORT->PM0+MLX90614_SDA_PORT)) |= (1 << MLX90614_SDA_PIN);} while (0)
#define MLX90614_SDA_PIN_MODE_OUT()          do {*((volatile uint8_t*)(&PORT->PM0+MLX90614_SDA_PORT)) &= ~(1 << MLX90614_SDA_PIN);} while (0)
#define MLX90614_SDA_PIN_GET()               PORT_GetBit(MLX90614_SDA_PORT, MLX90614_SDA_PIN)typedef enum {MLX90164_WRITE = 0,MLX90164_READ
} mlx90164_cmdtype;    #define MLX90164_NUM        1typedef struct {uint8_t Online[MLX90164_NUM];    //是否在线uint8_t Valid[MLX90164_NUM];     //温度值是否有效int32_t Temperature_Ta[MLX90164_NUM];   //环境温度 2位小数int32_t Temperature_To[MLX90164_NUM];   //物体温度 2位小数
} MLX90164_t;    extern MLX90164_t   MLX90164_data;void MLX90614_Init(void);
void MLX90614_Proc(void);#endif

/********************************************************************************* @copyright* @file      .c* @author* @version* @date      2023/1* @brief     红外测温传感器******************************************************************************* @attention*******************************************************************************/#include "MLX90614.h"MLX90164_t   MLX90164_data;
uint8_t calc[32];
uint8_t *calc_p = calc;#define DELAY_xUS       2   //uint8_t Calc_PEC_CRC8(uint8_t *dat, uint8_t len)
{uint8_t i;uint8_t 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;
}
/*** @brief  起始信号* @note   SCL高电平期间,SDA跳变为低。需要保证start前sda和scl均为高* @param* @retval* @author PWH* @date   2022/7*/
void MLX90614_Start(void)
{MLX90614_SDA_PIN_MODE_OUT();PORT_SetBit(MLX90614_SDA_PORT, MLX90614_SDA_PIN);PORT_SetBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);DELAY_US(DELAY_xUS);//PORT_ClrBit(MLX90614_SDA_PORT, MLX90614_SDA_PIN);DELAY_US(DELAY_xUS);//PORT_ClrBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);DELAY_US(DELAY_xUS);//
}
/*** @brief  结束信号* @note   SCL高电平期间,SDA跳变为高* @param* @retval* @author PWH* @date   2022/7*/
void MLX90614_Stop(void)
{MLX90614_SDA_PIN_MODE_OUT();PORT_ClrBit(MLX90614_SDA_PORT, MLX90614_SDA_PIN);PORT_SetBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);DELAY_US(DELAY_xUS);//PORT_SetBit(MLX90614_SDA_PORT, MLX90614_SDA_PIN);
}
/*** @brief  主机发出应答* @note   发送完8bit后,第9bit发送前的SCL低电平期间,SDA拉低* @param* @retval* @author PWH* @date   2022/7*/
void MLX90614_ACK(void)
{MLX90614_SDA_PIN_MODE_OUT();PORT_ClrBit(MLX90614_SDA_PORT, MLX90614_SDA_PIN);PORT_SetBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);DELAY_US(DELAY_xUS);//PORT_ClrBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);DELAY_US(DELAY_xUS);//
}
/*** @brief  主机发出非应答* @note   发送完8bit后,第9bit发送前的SCL低电平期间,SDA拉高* @param* @retval* @author PWH* @date   2022/7*/
void MLX90614_NACK(void)
{MLX90614_SDA_PIN_MODE_OUT();PORT_SetBit(MLX90614_SDA_PORT, MLX90614_SDA_PIN);PORT_SetBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);DELAY_US(DELAY_xUS);//PORT_ClrBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);DELAY_US(DELAY_xUS);//
}
/*** @brief  等待从机应答* @note   每发送一个字节后,再产生一个scl低电平让从机把应答信号放到sda上* @param* @retval* @author PWH* @date   2022/7*/
uint8_t MLX90614_WaitACK(void)
{uint8_t ack;MLX90614_SDA_PIN_MODE_IN();PORT_SetBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);ack = MLX90614_SDA_PIN_GET() ? 0 : 1;   //从机拉低sda应答DELAY_US(DELAY_xUS);//PORT_ClrBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);DELAY_US(DELAY_xUS);//return ack;
}
/*** @brief* @note* @param* @retval* @author PWH* @date   2022/7*/
void MLX90614_SendByte(uint8_t _1byte)
{uint8_t i;MLX90614_SDA_PIN_MODE_OUT();for (i = 0; i < 8; i++){if (_1byte & 0x80)PORT_SetBit(MLX90614_SDA_PORT, MLX90614_SDA_PIN);elsePORT_ClrBit(MLX90614_SDA_PORT, MLX90614_SDA_PIN);PORT_SetBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);DELAY_US(DELAY_xUS);//_1byte <<= 1;PORT_ClrBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);   //时钟低电平期间才允许数据变化DELAY_US(DELAY_xUS);//}
}
/*** @brief* @note* @param* @retval* @author PWH* @date   2022/7*/
void MLX90614_ReadByte(uint8_t *_1byte)
{uint8_t i;*_1byte = 0;MLX90614_SDA_PIN_MODE_IN();for (i = 0; i < 8; i++){PORT_SetBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);DELAY_US(DELAY_xUS);//*_1byte <<= 1;if (MLX90614_SDA_PIN_GET())*_1byte |= 0x01;PORT_ClrBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);DELAY_US(DELAY_xUS);//}
}
/*** @brief* @note* @param* @retval* @author PWH* @date   2022/7*/
void MLX90614_ReadWrite(uint8_t mlx_addr, mlx90164_cmdtype cmd, uint8_t reg_addr, uint8_t *bytes, uint8_t bytes_num)
{uint8_t i;calc_p = calc;  //缓存一帧用作校验计算*calc_p++ = (mlx_addr <<= 1) & 0xfe;   //器件地址MLX90614_Start();MLX90614_SendByte(mlx_addr & 0xfe); MLX90614_WaitACK();MLX90614_SendByte(reg_addr);    //寄存器地址*calc_p++ = reg_addr;MLX90614_WaitACK();if (cmd == MLX90164_WRITE){for (i = 0; i < bytes_num; i++) //发送数据{*calc_p++ = *bytes;MLX90614_SendByte(*bytes++);MLX90614_WaitACK();}MLX90614_SendByte(Calc_PEC_CRC8(calc, calc_p - calc));  //发送校验}else{MLX90614_Start();MLX90614_SendByte(mlx_addr | 0x01); //器件地址 读*calc_p++ = mlx_addr | 0x01;MLX90614_WaitACK();for (i = 0; i < bytes_num; i++){MLX90614_ReadByte(bytes);if (i == bytes_num - 1) {MLX90614_NACK();}else {MLX90614_ACK();}*calc_p++ = *bytes++;}}MLX90614_Stop();
}/*** @brief  初始化* @note* @param* @retval* @author PWH* @date   2022/7*/
void MLX90614_Init(void)
{uint32_t delay;PORT_Init(MLX90614_SCL_PORT, MLX90614_SCL_PIN, MLX90614_SCL_PIN_MODE);PORT_ClrBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);   //拉低scl超过1.44ms,传感器将由pwm转为i2c工作模式UserTimer_Reset(&delay);while (UserTimer_Read(&delay) < 3);PORT_SetBit(MLX90614_SCL_PORT, MLX90614_SCL_PIN);PORT_Init(MLX90614_SDA_PORT, MLX90614_SDA_PIN, OPENDRAIN_OUTPUT);MLX90614_SDA_PIN_MODE_OUT();PORT_SetBit(MLX90614_SDA_PORT, MLX90614_SDA_PIN);memset(MLX90164_data.Online, 0, sizeof(MLX90164_data));
}#define MLX_TEST    0
/*** @brief* @note   main while中调用* @param* @retval* @author PWH* @date   2023/2*/
void MLX90614_Proc(void)
{static uint32_t timer = 0;uint8_t temp[3];uint16_t temperature;#if (MLX_TEST == 1)uint8_t i;#endifif (UserTimer_Read(&timer) > TIMEOUT_1S)	//1s{UserTimer_Reset(&timer);MLX90164_data.Online[0] = 0;MLX90164_data.Valid[0] = 0;MLX90614_ReadWrite(MLX90614_FIXED_BUS_ADDR, MLX90164_READ, MLX90614_RAM_ADDR___TA, temp, 3);#if (MLX_TEST == 1)for (i = 0; i < calc_p - calc; i++){printf("calc[%d] = %#xrn", i, calc[i]);}printf("temp0=%#x,temp1=%#x,temp2=%#xrn", temp[0], temp[1], temp[2]);#endifif (Calc_PEC_CRC8(calc, calc_p - calc - 1) == temp[2]){MLX90164_data.Temperature_Ta[0] = (int32_t)(*((uint16_t *)temp) * 2) - (int32_t)27315;#if (MLX_TEST == 1)printf("ta成功temp0=%#x,temp1=%#x,temp2=%#xrn", temp[0], temp[1], temp[2]);#endif
//            MLX90164_data.Online[0] = 1;
//            MLX90164_data.Valid[0] = 1;}#if (MLX_TEST == 1)else{printf("ta失败-%#xrn", Calc_PEC_CRC8(calc, calc_p - calc - 1));}#endifMLX90614_ReadWrite(MLX90614_FIXED_BUS_ADDR, MLX90164_READ, MLX90614_RAM_ADDR___TOBJ1, temp, 3);#if (MLX_TEST == 1)for (i = 0; i < calc_p - calc; i++){printf("calc[%d] = %#xrn", i, calc[i]);}printf("temp0=%#x,temp1=%#x,temp2=%#xrn", temp[0], temp[1], temp[2]);#endifif (Calc_PEC_CRC8(calc, calc_p - calc - 1) == temp[2]){//温度换算公式:寄存器值 * 0.02, 结果单位为开尔文MLX90164_data.Temperature_To[0] = (int32_t)(*((uint16_t *)temp) * 2) - (int32_t)27315;#if (MLX_TEST == 1)printf("to成功temp0=%#x,temp1=%#x,temp2=%#xrn", temp[0], temp[1], temp[2]);#endifMLX90164_data.Online[0] = 1;MLX90164_data.Valid[0] = 1;}#if (MLX_TEST == 1)else{printf("to失败-%#xrn", Calc_PEC_CRC8(calc, calc_p - calc - 1));}printf("环境温度%f℃,物体温度%f℃rnrn", (float)MLX90164_data.Temperature_Ta[0] / 100, (float)MLX90164_data.Temperature_To[0] / 100);#endif}
}

本文发布于:2024-02-04 11:31:11,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170706184255176.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:网卡:mlx5
下一篇:matlab基础入门
标签:测温   传感器
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23