STM32F103单片机通过IIC控制MLX90614红外温度传感器

**MLX90614(gy906-BAA)**非接触红外温度传感器是一款性能和精度都较高的温度测量产品,在医疗,工业等领域应用较多;有四个引脚,使用SMBus协议,通过控制SDA、SCL引脚进行数据读取。工作电压为3.3V。
*

完整工程下载

产品配图

stm32cubemax 配置

串口温度测试:

电路连接说明:
SDA引脚连接STM32F103c8t6单片机PB7,SCL引脚连接PB6引脚。 VCC连接3.3V引脚,GND连接单片机的3.3V对应的GND引脚。因为IIC使用的是软模拟实现的引脚功能,所以用到了网上下载的标准库MLX90614.c与MLX90614.h文件

移植到stm32cubemax生成的工程里去,节省大家时间。

main.c 文件展示:

#include "main.h"
#include "usart.h"
#include "gpio.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "mlx90614.h"
#include "stdio.h"
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */printf("START");mlx90614_init();HAL_Delay(1000);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){HAL_Delay(1000);printf("%f",mlx90614_read_temp());/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

MLX90614.h 文件展示:

#ifndef __MLX90614_H
#define __MLX90614_H//#include "sys.h"
#include "main.h"//==============================================MLX90614硬件接口==================================================
#define     MLX90614_IIC_CLK            RCC_APB2Periph_GPIOB
#define     MLX90614_IIC_PORT           GPIOB
#define     MLX90614_IIC_PIN_SCL        GPIO_PIN_6
#define     MLX90614_IIC_PIN_SDA        GPIO_PIN_7#define   MLX90614_IIC_SCL        PBout(6)
#define     MLX90614_IIC_SDA        PBout(7)
#define     MLX90614_READ_SDA       PBin(7)  //输入SDA //==============================================MLX90614函数接口==================================================
void mlx90614_init(void);
float mlx90614_read_temp(void);
void delay_usssss(int n);
//==============================================MLX90614寄存器==================================================
#define     RAM             0x00
#define     EEPROM          0x20
#define     MODE            0x60
#define     EXITMODE        0x61
#define     READFLAG        0xf0
#define     SLEEP           0xff
#define     RD              0x01
#define     WR              0x00 #define    AMBITEMPADDR    0x03
#define     IR1ADDR         0x04
#define     IR2ADDR         0x05
#define     ENVITEMPADDR    0x06
#define     OBJ1TEMPADDR    0x07
#define     OBJ2TEMPADDR    0x08 #define    TOBJMAXADDR     0x00
#define     TOBJMINADDR     0x01
#define     PWMCTRLADDR     0x02
#define     TARANGEADDR     0x03
#define     KEADDR          0x04
#define     CONFIGADDR      0x05
#define     SMBUSADDR       0x0e
#define     RES1ADDR        0x0f
#define     RES2ADDR        0x19
#define     ID1ADDR         0x1c
#define     ID2ADDR         0x1d
#define     ID3ADDR         0x1e #define    ID4ADDR         0x1f #define    ACK_SUCCESS     0x01
#define     ACK_FAIL        0x00
#define     N               5#endif

/---------------------
MLX90614.c 文件展示:

/*================================================================================================
//  文件功能:MlX90614的驱动文件
//  文件说明:
//  文件类型:
//------------------------------------------------------------------------------------------------
//  硬件平台:STM32F103C8T6 -cubemax
//  软件平台:KEIL5 MDK
//------------------------------------------------------------------------------------------------
//  开发组织:
//  开发作者:heyque
//  官方商城:
//------------------------------------------------------------------------------------------------//------------------------------------------------------------------------------------------------
//  更新时间:2021-05-12
//-----------------------------------------------------------------------------------------------
//  待完善内容:
================================================================================================*/
#include "mlx90614.h"/*================================================================================================
//  @函数名称:
//  @函数功能:SDA输出配置
//  @函数说明:
//------------------------------------------------------------------------------------------------
//  @参数值:   无
//  @返回值:   无
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-07-11    heyque  新建
//==============================================================================================*/
/*================================================================================================
//  @函数名称:
//  @函数功能:产生通讯开始信号
//  @函数说明:MLX90614在SCK=1时,检测到SDA由1到0表示通信开始
//------------------------------------------------------------------------------------------------
//  @参数值:   无
//  @返回值:   无
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
void mlx90614_iic_start(void)
{MLX90614_SDA_OUT();HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA, GPIO_PIN_SET);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_SET);delay_weimiao(5);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA, GPIO_PIN_RESET);delay_weimiao(5);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET);delay_weimiao(5);
}
/*================================================================================================
//  @函数名称:
//  @函数功能:产生通讯停止信号
//  @函数说明:MLX90614在SCK=1时,检测到SDA由0到1表示通信结束
//------------------------------------------------------------------------------------------------
//  @参数值:   无
//  @返回值:   无
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
void mlx90614_iic_stop(void)
{MLX90614_SDA_OUT();HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA, GPIO_PIN_RESET);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET);delay_weimiao(5);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_SET);delay_weimiao(5);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA, GPIO_PIN_SET);delay_weimiao(5);
}
/*================================================================================================
//  @函数名称:
//  @函数功能:产生ACK应答
//  @函数说明:
//------------------------------------------------------------------------------------------------
//  @参数值:   无
//  @返回值:   无
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
void mlx90614_iic_ack(void)
{HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET);MLX90614_SDA_OUT();HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA, GPIO_PIN_RESET);delay_weimiao(2);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_SET);delay_weimiao(5);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET);
}
/*================================================================================================
//  @函数名称:
//  @函数功能:产生NACK非应答
//  @函数说明:
//------------------------------------------------------------------------------------------------
//  @参数值:   无
//  @返回值:   无
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
void mlx90614_iic_no_ack(void)
{HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET);MLX90614_SDA_OUT();HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA, GPIO_PIN_SET);delay_weimiao(2);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_SET);delay_weimiao(5);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET);
}
/*================================================================================================
//  @函数名称:
//  @函数功能:等待应答信号到来
//  @函数说明:
//------------------------------------------------------------------------------------------------
//  @参数值:   无
//  @返回值:   1,接收应答失败 0,接收应答成功
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
uint8_t mlx90614_iic_wait_ack(void)
{uint8_t tempTime=0;MLX90614_SDA_IN();      //SDA设置为输入  HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA, GPIO_PIN_SET);delay_weimiao(1);    HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_SET);delay_weimiao(1);    while(HAL_GPIO_ReadPin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA)==1){tempTime++;if(tempTime>250){mlx90614_iic_stop();return 1;}}HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET);//时钟输出0      return 0;
}
/*================================================================================================
//  @函数名称:
//  @函数功能:从RAM/EEPROM中读取一个字节数据
//  @函数说明:从MLX90614中的指定地址读取一个字节数据,高位在前,低位在后
//------------------------------------------------------------------------------------------------
//  @参数值:   ack_nack:主机应答信号
//  @返回值:   dat: 读取的数据
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
uint8_t mlx90614_iic_read_byte(uint8_t ack)
{uint8_t i,receive=0;MLX90614_SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET); delay_weimiao(2);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_SET);receive<<=1;if(HAL_GPIO_ReadPin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA)==1)receive++;   delay_weimiao(1); }                  if (!ack)mlx90614_iic_no_ack();//发送nACKelsemlx90614_iic_ack(); //发送ACK   return receive;
}
/*================================================================================================
//  @函数名称:
//  @函数功能:向EEPROM写一个字节数据
//  @函数说明:在写完一个字节后检测MLX6014是否发送了应答信号
//------------------------------------------------------------------------------------------------
//  @参数值:   dat:需要发送的字节
//  @返回值:   s_ack:应答信号状态
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
uint8_t mlx90614_iic_write_byte(uint8_t dat)
{uint8_t t;   uint8_t s_ack=0;MLX90614_SDA_OUT();      HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET);//拉低时钟开始数据传输for(t=0;t<8;t++){              if((dat&0x80)>0) //0x80  1000 0000HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA, GPIO_PIN_SET);elseHAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA, GPIO_PIN_RESET);dat<<=1;      delay_weimiao(2);   //对TEA5767这三个延时都是必须的HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_SET);delay_weimiao(2); HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET);    delay_weimiao(2);}   if(mlx90614_iic_wait_ack()) //高电平表示正确接收数据  (高?低??这个应该是低电平){s_ack = ACK_FAIL;}else{s_ack = ACK_SUCCESS;}return s_ack;
}
/*================================================================================================
//  @函数名称:
//  @函数功能:mlx90614初始化
//  @函数说明:
//------------------------------------------------------------------------------------------------
//  @参数值:   无
//  @返回值:   无
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
void mlx90614_init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};__HAL_RCC_GPIOB_CLK_ENABLE();/*Configure GPIO pin : PB7 */GPIO_InitStruct.Pin = MLX90614_IIC_PIN_SCL|MLX90614_IIC_PIN_SCL;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA|MLX90614_IIC_PIN_SCL, GPIO_PIN_SET);HAL_GPIO_Init(MLX90614_IIC_PORT, &GPIO_InitStruct);
}
/*================================================================================================
//  @函数名称:
//  @函数功能:计算PEC包裹校验码,根据接收的字节计算PEC码
//  @函数说明:计算传入数据的PEC码
//------------------------------------------------------------------------------------------------
//  @参数值:   pec[]:传入的数据
//              n:传入数据个数
//  @返回值:   pec[0]:计算得到的PEC值
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
static uint8_t pec_cal(uint8_t pec[],uint16_t n)
{unsigned char crc[6];unsigned char Bitposition=47;unsigned char shift;unsigned char i;unsigned char j;unsigned char temp;do{crc[5]=0; //载入 CRC数值 0x000000000107crc[4]=0;crc[3]=0;crc[2]=0;crc[1]=0x01;crc[0]=0x07;Bitposition=47; //设置Bitposition的最大值为47shift=0;//在传送的字节中找出第一个“1”i=5; //设置最高标志位 (包裹字节标志)j=0; //字节位标志,从最低位开始while((pec[i]&(0x80>>j))==0 && (i>0)){Bitposition--;if(j<7){j++;}else{j=0x00;i--;}}//while语句结束,并找出Bitposition中为“1”的最高位位置shift=Bitposition-8;//得到CRC数值将要左移/右移的数值“shift”//对CRC数据左移“shift”位while(shift){for(i=5;i<0xFF;i--){if((crc[i-1]&0x80) && (i>0))//核对字节的最高位的下一位是否为"1"{ //是 - 当前字节 + 1temp=1; //否 - 当前字节 + 0} //实现字节之间移动“1”else{temp=0;}crc[i]<<=1;crc[i]+=temp;}shift--;}//pec和crc之间进行异或计算for(i=0;i<=5;i++){pec[i]^=crc[i];}}while(Bitposition>8);return pec[0]; //返回计算所得的crc数值
}
/*================================================================================================
//  @函数名称:
//  @函数功能:将MLX90614的工作模式从PWM模式切换到SMBus模式
//  @函数说明:从PWM模式切换到SMBus的方法是将SCL保持至少1.44ms以上的低电平,
//              如果PWM没有使能就不需要发送请求命令。
//------------------------------------------------------------------------------------------------
//  @参数值:无
//  @返回值:无
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
void pwm_to_smbus(void)
{HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET);delay_weimiao(1500); //大于1.44msHAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_SET);
}
/*================================================================================================
//  @函数名称:
//  @函数功能:退出睡眠模式
//  @函数说明:保持SCK高电平后,SDA持续至少33ms低电平,
//              在退出睡眠模式后需要间隔250ms(典型值)才输出数据。
//------------------------------------------------------------------------------------------------
//  @参数值:无
//  @返回值:无
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
void eixt_sleep(void)
{HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_SET);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA, GPIO_PIN_SET);delay_weimiao(5);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA, GPIO_PIN_RESET);HAL_Delay(35); //大于33ms退出睡眠模式HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SDA, GPIO_PIN_SET);HAL_Delay(260); //大于250ms开始输出数据
}
/*================================================================================================
//  @函数名称:
//  @函数功能:清除EEPROM指定单元的数据
//  @函数说明:在向EEPROM中写入数据之前必须先清除内存单元中的数据,也就是全部写入0
//------------------------------------------------------------------------------------------------
//  @参数值:   saddr:从机地址
//              cmd:发送命令
//  @返回值:   无
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
void mlx90614_clear_eeprom(uint8_t saddr,uint8_t cmd)
{uint8_t retry = 10; //失败重复次数uint8_t s_ack = 0;HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET);    while(retry--){mlx90614_iic_start(); //发送起始位s_ack = mlx90614_iic_write_byte((saddr<<1)|WR); //发送从机地址和Wr位if(s_ack == ACK_SUCCESS){s_ack = 0;s_ack = mlx90614_iic_write_byte(EEPROM|cmd);//发送命令,8位 EPROM表示对RAM操作,cmd表示操作EEPROM的地址$MLX90614.Cif(s_ack == ACK_SUCCESS){s_ack = 0;s_ack = mlx90614_iic_write_byte(0x00); //发送低字节if(s_ack == ACK_SUCCESS){s_ack = 0;s_ack = mlx90614_iic_write_byte(0x00); //发送高字节if(s_ack == ACK_SUCCESS){s_ack = 0;s_ack = mlx90614_iic_write_byte(0x6f); //发送PEC字节if(s_ack == ACK_SUCCESS){mlx90614_iic_stop(); //发送停止位break; //退出循环}else goto stop_ce;}else goto stop_ce;}else goto stop_ce;}else goto stop_ce;}else goto stop_ce;stop_ce:mlx90614_iic_stop(); //发送停止位,芯片接收失败}HAL_Delay(5); //擦除完成至少等待5ms
}
/*================================================================================================
//  @函数名称:
//  @函数功能:读EEPROM指定单元的数据
//  @函数说明:从指定从机读取指定EEPROM地址的数据
//------------------------------------------------------------------------------------------------
//  @参数值:   saddr:从机地址
//              cmd:读取EEPROM地址
//  @返回值:   Data:读取数据
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
uint16_t mlx90614_read_eeprom(uint8_t saddr,uint8_t cmd)
{uint8_t retry = 10;uint8_t s_ack;uint16_t Data;uint8_t DataL; //接收数据低字节uint8_t DataH; //接收数据高字节uint8_t PEC; //接收的PEC值uint8_t Pecreg; //计算的PEC值uint8_t buf[6]; //存储已接收数据的缓存while(retry--){mlx90614_iic_start(); //发送起始位s_ack = mlx90614_iic_write_byte((saddr<<1)|WR); //发送从机地址和Wr位if(s_ack == ACK_SUCCESS){s_ack = 0;s_ack = mlx90614_iic_write_byte(EEPROM|cmd); //发送命令if(s_ack == ACK_SUCCESS){s_ack = 0;mlx90614_iic_start(); //重新发送起始位s_ack = mlx90614_iic_write_byte((saddr<<1)|RD); //发送从机地址和Rd位if(s_ack == ACK_SUCCESS){s_ack = 0;DataL = mlx90614_iic_read_byte(1); //读数据低字节DataH = mlx90614_iic_read_byte(1); //读数据高字节PEC = mlx90614_iic_read_byte(1); //读数据PEC字节mlx90614_iic_stop(); //发送停止位buf[5]=(saddr<<1);buf[4]=EEPROM|cmd;buf[3]=(saddr<<1)|RD;buf[2]=DataL;buf[1]=DataH;buf[0]=0;Pecreg=pec_cal(buf,6); //调用计算 PEC 的函数if(Pecreg == PEC){break;}}else goto stop_re;}else goto stop_re;}else goto stop_re;stop_re:mlx90614_iic_stop();}Data = (DataH<<8) + DataL;return Data;
}
/*================================================================================================
//  @函数名称:
//  @函数功能:写EEPROM指定单元的数据
//  @函数说明:在向EEPROM中写入数据之前必须先清除内存单元中的数据,也就是全部写入0
//------------------------------------------------------------------------------------------------
//  @参数值:   saddr:要清除数据的内存单元
//  @返回值:   无
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
void mlx90614_write_eeprom(uint8_t saddr,uint8_t cmd,uint8_t DataL,uint8_t DataH)
{uint8_t retry = 10; //失败重复次数uint8_t s_ack = 0;uint8_t Pecreg; //存储计算所得PEC结果$MLX90614.Cuint8_t buf[6]; //存储将要发送字节的缓冲器buf[5]=0;buf[4]=saddr<<1;buf[3]=cmd;buf[2]=DataL;buf[1]=DataH;buf[0]=0;Pecreg=pec_cal(buf,6);HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET);    while(retry--){mlx90614_iic_start(); //发送起始位s_ack = mlx90614_iic_write_byte((saddr<<1)|WR); //发送从机地址和Wr位if(s_ack == ACK_SUCCESS){s_ack = 0;s_ack = mlx90614_iic_write_byte(EEPROM|cmd); //发送命令if(s_ack == ACK_SUCCESS){s_ack = 0;s_ack = mlx90614_iic_write_byte(DataL); //发送低字节if(s_ack == ACK_SUCCESS){s_ack = 0;s_ack = mlx90614_iic_write_byte(DataH); //发送高字节if(s_ack == ACK_SUCCESS){s_ack = 0;s_ack = mlx90614_iic_write_byte(Pecreg); //发送PEC码if(s_ack == ACK_SUCCESS){mlx90614_iic_stop(); //发送停止位break; //退出循环}else goto stop_we;}else goto stop_we;}else goto stop_we;}else goto stop_we;}else goto stop_we;stop_we:mlx90614_iic_stop();}HAL_Delay(5); //写入之后等待5ms
}/*================================================================================================
//  @函数名称:
//  @函数功能:设定MLX90614器件地址
//  @函数说明:器件从地址可以通过向EEPROM的SMBus地址0x0E中写入来进行设定。为了给从器件设定地址,必
//              须先以0x00+Wr当作从地址开始,当主机发送此命令,MLX90614总是会反馈并忽略掉内部芯片
//              编码信息。向EEPROM写入数据前需要清除原来的数据,就是向修改单元写入0x0000,擦除之后
//              需要等待5ms才可以重新写入数据,修改地址时写入的地址高字节MLX90614会忽略.修改之后需
//              要重新将MLX90614的电源断开重启。
//------------------------------------------------------------------------------------------------
//  @参数值:   soaddr:从机旧地址
//              snaddr:从机新地址
//  @返回值:   无
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    heyque  新建
//==============================================================================================*/
void mlx90614_set_addr(uint8_t soaddr,uint8_t snaddr)
{// uint8_t cmd = EEPROM|SMBUSADDR;
// uint8_t DataL = snaddr;
// uint8_t DataH = 0x00;
// EEPROM_WRITE(snaddr,cmd,0x00,0x00);
// EEPROM_WRITE(snaddr,cmd,DataL,DataH);
}/*================================================================================================
//  @函数名称:
//  @函数功能:读MLX90614的RAM中内容
//  @函数说明:主要读取三个,环境温度,物体温度1,物体温度2
//              器件从地址可以通过向EEPROM的SMBus地址0x0E中写入来进行设定。
//------------------------------------------------------------------------------------------------
//  @参数值:   saddr:从机地址,7位地址,任何MLX90614都会对0x00地址作出反应
//              cmd:存放温度的寄存器地址
//  @返回值:   Data:读取出来的数值。SA(write) - Command - SA(read) - LSByte - MSByte - PEC
//------------------------------------------------------------------------------------------------
//  @修改日志:2021-05-12    冯奇  新建
//==============================================================================================*/
static uint16_t mlx90614_read_ram(uint8_t saddr,uint8_t cmd)
{uint16_t Data;uint8_t DataL; //接收数据低字节uint8_t DataH; //接收数据高字节uint8_t PEC;uint8_t retry = 10; //失败重复次数uint8_t s_ack = 0;uint8_t Pecreg; //计算的PEC值uint8_t buf[6]; //存储已接收数据的缓存HAL_GPIO_WritePin(MLX90614_IIC_PORT, MLX90614_IIC_PIN_SCL, GPIO_PIN_RESET); while(retry--){mlx90614_iic_start(); //发送起始位s_ack = mlx90614_iic_write_byte((saddr<<1)|WR); //发送从机地址和Wr位if(s_ack == ACK_SUCCESS){s_ack = 0;s_ack = mlx90614_iic_write_byte(RAM|cmd);//发送命令,8位,RAM表示对RAM操作,cmd表示操作RAM的地址if(s_ack == ACK_SUCCESS){s_ack = 0;mlx90614_iic_start(); //重新发送起始位s_ack = mlx90614_iic_write_byte((saddr<<1)+1); //发送从机地址和Rd位if(s_ack == ACK_SUCCESS){s_ack = 0;DataL = mlx90614_iic_read_byte(1); //读数据低字节DataH = mlx90614_iic_read_byte(1); //读数据高字节PEC = mlx90614_iic_read_byte(1); //读数据PEC字节// DataL=RX_byte(0); //// DataH=RX_byte(0); //// PEC=RX_byte(1);mlx90614_iic_stop(); //发送停止位buf[5]=(saddr<<1);buf[4]=EEPROM|cmd;buf[3]=(saddr<<1)|RD;buf[2]=DataL;buf[1]=DataH;buf[0]=0;Pecreg=pec_cal(buf,6); //调用计算 PEC 的函数if(Pecreg == PEC){break; //退出循环}}else goto stop_rr;}else goto stop_rr;}else goto stop_rr;stop_rr:mlx90614_iic_stop(); //发送停止位,芯片接收失败}PEC = PEC+1;Data = (DataH<<8) + DataL;return Data;
}

STM32CubeMX配置读取MLX90614(GY-906)非接触红外测温传感器相关推荐

  1. 【单片机毕业设计】【mcuclub-jk-003】基于单片机的非接触红外测温的设计

    最近设计了一个项目基于单片机的非接触红外测温系统,与大家分享一下: 一.基本介绍 项目名:非接触红外测温 项目编号:mcuclub-jk-003 单片机类型:STC89C52.STM32F103C8T ...

  2. 4Gwifi无线远程非接触红外测温传感器mqtt/http推送数据

    1产品概述 DAQ-GP-IRT4G无线红外测温传感器终端是上海数采物联网科技有限公司推出的一款无线非接触红外测温产品.本产品红外探测器(热敏探测器和光电探测器)将红外辐射能量测出并转变成电信号,再根 ...

  3. 第二十七篇、基于Arduino uno,获取mlx90614非接触式红外测温传感器的温度值——结果导向

    0.结果 说明:先来看看串口调试助手显示的结果,第一个值是空气的温度,第二个值是被测量的物体温度,如果是你想要的,可以接着往下看. 1.外观 说明:虽然mlx90614非接触式红外测温传感器形态各异, ...

  4. GY906 MLX90614 非接触式 红外测温传感器 LabVIEW i2c总线数据读取

    GY906使用的红外测温芯片为MLX90614. 使用LabVIEW读取i2c总线数据时,需要知道传感器的地址,出厂默认为0x5A.传感器地址支持自己修改,存放在芯片EEPROM的0x0E位置,可以通 ...

  5. Arduino使用MLX90614 非接触式红外测温传感器

    相关资料链接 链接:https://pan.baidu.com/s/1eE0rkaSJsKJMU_RUorS5OA 提取码:3ujh 1.1 介绍: MLX90614是一款由迈来芯公司提供的低成本,无 ...

  6. ESP32启明云端又有新玩法|基于ESP32+热像仪传感的物联网非接触智能测温终端为高考护航了

    今天是高考第一天,想想N年前的自己,高考前抱着破罐子破摔的心态,书丢一边,好吃好喝迎高考!所以结局惨淡无比! 不提伤心事了,今天祝所有的高考考生都能取得自己满意的成绩! 今天提到的ESP32的新玩法跟 ...

  7. 基于stm32的非接触式红外测温系统

    一.硬件材料清单: 1.STM32核心板 2.OLED显示屏 3.mlx90614 红外测温传感器 4.蜂鸣器 5.按键 二.实现的功能 1.mlx90614红外温度数据的实时检测 2.本地OLED数 ...

  8. STM32和MLx90614非接触红外温度传感器

    MLx90614介绍: MLx90614非接触红外温度传感器是一款性能和精度都较高的温度测量产品,在医疗,工业等领域应用较多:有四个引脚,使用SMBus协议,通过控制SCL引脚进行数据读取.现在给出一 ...

  9. 26、基于51单片机mlx90614(GY-906)非接触式红外测温上下限声光报警系统设计

    摘要 门式红外人体测温安检仪与传统的安检系统比较,增加了人体测温功能,在流行病多发季节可以适当的提醒人们减少外出,必要时可采取强制措施禁止出行以减少疾病的传播:并且测温为非接触式,与传统的接触式测温相 ...

  10. 010 红外非接触测温传感器

    010 红外非接触测温传感器 01 功能作用   非接触测量物体温度,包括人的额头,手臂都,所以可以测量人的体温. 02 如何使用 02_0 通用模块尺寸及固定方式   模块尺寸大小与乐高长方形框架结 ...

最新文章

  1. 学习动力之“学习金字塔 (爱德加•戴尔)”理论
  2. C++/C++11中std::queue的使用
  3. python 执行vba脚本_用python批量执行VBA代码
  4. hdoj1423 最长上升公共子序列
  5. 马斯克活猪脑机接口试验成功!多芯片植入,硬币大小,实时读取脑电波,已被批准人脑实验...
  6. python怎么安装pandas模块-windows下如何安装Python、pandas
  7. 影响软件测试未来的5件事 (译)
  8. http反向代理之haproxy详解
  9. datagrid如何获取一行数据中的某个字段值_redis 所支持的数据类型以及其应用场景...
  10. java httpclient教程_HttpClient4.5.2 HTTP协议的请求和执行
  11. Vue 打包后打开为空白页面 并且控制台报错‘Failed to load resource: net::ERR_FILE_NOT_FOUND’
  12. LightOJ - 1422 (区间DP)
  13. 于无声处 启明星辰吹响工控安全号角
  14. 【postMan】发送post请求,返回错误码415
  15. Java内存管理及GC算法
  16. Atitit 号码规范 靓号指南 attilax总结 v4 r926.docx
  17. 省钱兄淘宝客APP源码商城抖客电商源码uniapp前端模版源码
  18. 微信小程序中slider实现拾色器功能
  19. linux ipad 视频,是否可以在iPad或iPad上同时播放多个视频文件?
  20. 电脑桌面老是弹出计算机,电脑桌面老是弹出游戏怎么解决

热门文章

  1. css 实现一个尖角_css中尖角的制作实例方法总结
  2. i18n 支持参数的写法
  3. 删除ttf字体文件中无用文字
  4. 联合概率密度函数的基本结论
  5. CTFT、DTFT、DFT、FFT
  6. 程序员如何写简历之简介篇(一)
  7. 拍出来好看的拍照软件?这4款好看好用的App简直赞到爆~
  8. Python openpyxl 删除excel有删除线的文字
  9. 猫有哪些比较常见的肢体语言?
  10. 二叉树由遍历确定一棵树