STM32H7驱动GY906红外测温传感器
STM32H7通过iic驱动GY906红外测温模块 ,大部分代码来自网上
1、将iic.h和iic.c文件添加到自己项目中
2、初始化GY906
SMBus_Init(); //初始化GY906
3、 读取测试温度
float tem = SMBus_ReadTemp();
代码:
iic.h
#ifndef __IIC_H
#define __IIC_H#include "stm32h7xx.h"void SMBus_StartBit(void);
void SMBus_StopBit(void);
void SMBus_SendBit(uint8_t);
uint8_t SMBus_SendByte(uint8_t);
uint8_t SMBus_ReceiveBit(void);
uint8_t SMBus_ReceiveByte(uint8_t);
void SMBus_Init(void);
uint16_t SMBus_ReadMemory(uint8_t, uint8_t);
uint8_t PEC_Calculation(uint8_t*);
float SMBus_ReadTemp(void); //获取温度值void PY_usDelayTest(void);
void PY_usDelayOptimize(void);
void SMBus_Delay(uint32_t Delay);#endif
iic.c
#include "iic.h"
#include "stm32h7xx.h"#define ACK 0 //应答
#define NACK 1 //无应答#define SA 0x00 //Slave address 单个MLX90614时地址为0x00,多个时地址默认为0x5a
#define RAM_ACCESS 0x00 //RAM access command RAM存取命令
#define EEPROM_ACCESS 0x20 //EEPROM access command EEPROM存取命令
#define RAM_TOBJ1 0x07 //To1 address in the eeprom 目标1温度,检测到的红外温度 -70.01 ~ 382.19度#define SMBUS_PORT GPIOD //PD端口(端口和下面的两个针脚可自定义)
#define SMBUS_SCK GPIO_PIN_0 //PD0:SCL
#define SMBUS_SDA GPIO_PIN_1 //PD1:SDA#define SMBUS_SCK_H() HAL_GPIO_WritePin(SMBUS_PORT, SMBUS_SCK, GPIO_PIN_SET) //时钟线置高电平
#define SMBUS_SCK_L() HAL_GPIO_WritePin(SMBUS_PORT, SMBUS_SCK, GPIO_PIN_RESET) //时钟线置低电平
#define SMBUS_SDA_H() HAL_GPIO_WritePin(SMBUS_PORT, SMBUS_SDA, GPIO_PIN_SET) //数据线置高电平
#define SMBUS_SDA_L() HAL_GPIO_WritePin(SMBUS_PORT, SMBUS_SDA, GPIO_PIN_RESET) //数据线置低电平//IO方向设置
#define SDA_IN() {GPIOD->MODER&=~(3<<(1*2));GPIOD->MODER|=0<<1*2;} //数据线PD1输入模式
#define SDA_OUT() {GPIOD->MODER&=~(3<<(1*2));GPIOD->MODER|=1<<1*2;} //数据线PD1输出模式#define SMBUS_SDA_PIN() HAL_GPIO_ReadPin(SMBUS_PORT, SMBUS_SDA) //读取数据线PD1引脚电平//下面三个位延时函数,具体解释见:https://blog.csdn.net/hwytree/article/details/120825485
float usDelayBase;
void PY_usDelayTest(void)
{uint32_t firstms, secondms;uint32_t counter = 0;firstms = HAL_GetTick()+1;secondms = firstms+1;while(uwTick!=firstms) ;while(uwTick!=secondms) counter++;usDelayBase = ((float)counter)/1000;
}void PY_usDelayOptimize(void)
{uint32_t firstms, secondms;float coe = 1.0;firstms = HAL_GetTick();SMBus_Delay(1000000) ;secondms = HAL_GetTick();coe = ((float)1000)/(secondms-firstms);usDelayBase = coe*usDelayBase;
}void SMBus_Delay(uint32_t Delay)
{uint32_t delayReg;uint32_t usNum = (uint32_t)(Delay*usDelayBase);delayReg = 0;while(delayReg!=usNum) delayReg++;
}/*******************************************************************************
* Function Name : SMBus_StartBit
* Description : Generate START condition on SMBus
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SMBus_StartBit(void)
{SMBUS_SDA_H(); // Set SDA lineSMBus_Delay(5); // Wait a few microsecondsSMBUS_SCK_H(); // Set SCL lineSMBus_Delay(5); // Generate bus free time between StopSMBUS_SDA_L(); // Clear SDA lineSMBus_Delay(5); // Hold time after (Repeated) Start// Condition. After this period, the first clock is generated.//(Thd:sta=4.0us min)在SCK=1时,检测到SDA由1到0表示通信开始(下降沿)SMBUS_SCK_L(); // Clear SCL lineSMBus_Delay(5); // Wait a few microseconds
}/*******************************************************************************
* Function Name : SMBus_StopBit
* Description : Generate STOP condition on SMBus
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SMBus_StopBit(void)
{SMBUS_SCK_L(); // Clear SCL lineSMBus_Delay(5); // Wait a few microsecondsSMBUS_SDA_L(); // Clear SDA lineSMBus_Delay(5); // Wait a few microsecondsSMBUS_SCK_H(); // Set SCL lineSMBus_Delay(5); // Stop condition setup time(Tsu:sto=4.0us min)SMBUS_SDA_H(); // Set SDA line在SCK=1时,检测到SDA由0到1表示通信结束(上升沿)
}/*******************************************************************************
* Function Name : SMBus_SendByte
* Description : Send a byte on SMBus
* Input : Tx_buffer
* Output : None
* Return : None
*******************************************************************************/
uint8_t SMBus_SendByte(uint8_t Tx_buffer)
{uint8_t Bit_counter;uint8_t Ack_bit;uint8_t 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 SDATx_buffer<<=1; // Get next bit for checking}Ack_bit=SMBus_ReceiveBit(); // Get acknowledgment bitreturn Ack_bit;
}/*******************************************************************************
* Function Name : SMBus_SendBit
* Description : Send a bit on SMBus 82.5kHz
* Input : bit_out
* Output : None
* Return : None
*******************************************************************************/
void SMBus_SendBit(uint8_t bit_out)
{if(bit_out==0){SMBUS_SDA_L();}else{SMBUS_SDA_H();}SMBus_Delay(2); // Tsu:dat = 250ns minimumSMBUS_SCK_H(); // Set SCL lineSMBus_Delay(6); // High Level of Clock PulseSMBUS_SCK_L(); // Clear SCL lineSMBus_Delay(3); // Low Level of Clock Pulse
// SMBUS_SDA_H(); // Master release SDA line ,return;
}/*******************************************************************************
* Function Name : SMBus_ReceiveBit
* Description : Receive a bit on SMBus
* Input : None
* Output : None
* Return : Ack_bit
*******************************************************************************/
uint8_t SMBus_ReceiveBit(void)
{uint8_t Ack_bit;SMBUS_SDA_H(); //引脚靠外部电阻上拉,当作输入SMBus_Delay(2); // High Level of Clock PulseSMBUS_SCK_H(); // Set SCL lineSMBus_Delay(5); // High Level of Clock Pulseif (SMBUS_SDA_PIN()){Ack_bit=1;}else{Ack_bit=0;}SMBUS_SCK_L(); // Clear SCL lineSMBus_Delay(3); // Low Level of Clock Pulsereturn Ack_bit;
}/*******************************************************************************
* Function Name : SMBus_ReceiveByte
* Description : Receive a byte on SMBus
* Input : ack_nack
* Output : None
* Return : RX_buffer
*******************************************************************************/
uint8_t SMBus_ReceiveByte(uint8_t ack_nack)
{uint8_t RX_buffer;uint8_t 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_bufferRX_buffer |=0x01;}else{RX_buffer <<= 1; // If the bit is LOW save 0 in RX_bufferRX_buffer &=0xfe;}}SMBus_SendBit(ack_nack); // Sends acknowledgment bitreturn RX_buffer;
}/*******************************************************************************
* Function Name : SMBus_Init
* Description : SMBus初始化
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void SMBus_Init()
{GPIO_InitTypeDef GPIO_InitStruct;__HAL_RCC_GPIOD_CLK_ENABLE();GPIO_InitStruct.Pin = SMBUS_SCK | SMBUS_SDA;; // SCL引脚GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 开漏输出GPIO_InitStruct.Pull = GPIO_NOPULL; // 不带上下拉GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; // 速度等级 HAL_GPIO_Init(SMBUS_PORT, &GPIO_InitStruct);// GPIO_InitStruct.Pin = SMBUS_SDA; // SDA引脚
// HAL_GPIO_Init(SMBUS_PORT, &GPIO_InitStruct); SMBUS_SCK_H();SMBUS_SDA_H();
}/******************************************************************************** Function Name : SMBus_ReadMemory* Description : READ DATA FROM RAM/EEPROM* Input : slaveAddress, command* Output : None* Return : Data
*******************************************************************************/
uint16_t SMBus_ReadMemory(uint8_t slaveAddress, uint8_t command)
{uint16_t data; // Data storage (DataH:DataL)uint8_t Pec; // PEC byte storageuint8_t DataL=0; // Low data byte storageuint8_t DataH=0; // High data byte storageuint8_t arr[6]; // Buffer for the sent bytesuint8_t PecReg; // Calculated PEC byte storageuint8_t ErrorCounter; // Defines the number of the attempts for communication with MLX90614ErrorCounter=0x00; // Initialising of ErrorCounterslaveAddress <<= 1; //2-7位表示从机地址do{
repeat:SMBus_StopBit(); //If slave send NACK stop comunication--ErrorCounter; //Pre-decrement ErrorCounterif(!ErrorCounter) //ErrorCounter=0?{break; //Yes,go out from do-while{}}SMBus_StartBit(); //Start conditionif(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 conditionif(SMBus_SendByte(slaveAddress+1)) //Send SlaveAddress 最低位Rd=1表示接下来读数据{goto repeat; //Repeat comunication again}DataL = SMBus_ReceiveByte(ACK); //Read low data,master must send ACKDataH = SMBus_ReceiveByte(ACK); //Read high data,master must send ACKPec = SMBus_ReceiveByte(NACK); //Read PEC byte, master must send NACKSMBus_StopBit(); //Stop conditionarr[5] = slaveAddress; //arr[4] = command; //arr[3] = slaveAddress+1; //Load array arrarr[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:DataLreturn data;
}/*******************************************************************************
* Function Name : PEC_calculation
* Description : Calculates the PEC of received bytes
* Input : pec[]
* Output : None
* Return : pec[0]-this byte contains calculated crc value
*******************************************************************************/
uint8_t PEC_Calculation(uint8_t pec[])
{uint8_t crc[6];uint8_t BitPosition=47;uint8_t shift;uint8_t i;uint8_t j;uint8_t 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];
}/******************************************************************************** Function Name : SMBus_ReadTemp* Description : Calculate and return the temperature* Input : None* Output : None* Return : SMBus_ReadMemory(0x00, 0x07)*0.02-273.15
*******************************************************************************/
float SMBus_ReadTemp(void)
{ float temp;temp = SMBus_ReadMemory(SA, RAM_ACCESS|RAM_TOBJ1)*0.02-273.15;return temp;
}
STM32H7驱动GY906红外测温传感器相关推荐
- STM32驱动MLX90614红外测温模块
简介:STM32F103C8T6驱动MLX90614红外测温模块源码介绍. 开发平台:KEIL ARM MCU型号:STM32F103C8T6 传感器型号:MLX90614 特别提示:驱动内可能使用了 ...
- 4Gwifi无线远程非接触红外测温传感器mqtt/http推送数据
1产品概述 DAQ-GP-IRT4G无线红外测温传感器终端是上海数采物联网科技有限公司推出的一款无线非接触红外测温产品.本产品红外探测器(热敏探测器和光电探测器)将红外辐射能量测出并转变成电信号,再根 ...
- 【使用笔记】树莓派基于Python操作IIC接口的红外测温传感器
最近在使用红外测温传感器,IIC通信,在单片机上已能读取数据,但是想把数据读取到电脑上用python做一些处理,想到树莓派自带IIC接口,于是尝试直接将红外传感器接到树莓派的IIC管脚. 启用树莓派I ...
- GY-906-DCI红外测温传感器
有大佬玩过Mlx90614的GY-906-DCI红外测温传感器吗 这个传感器通电之后背后的灯会亮的吗,我这个不亮的,一直读不出温度怕是硬件问题 ,
- 第二十七篇、基于Arduino uno,获取mlx90614非接触式红外测温传感器的温度值——结果导向
0.结果 说明:先来看看串口调试助手显示的结果,第一个值是空气的温度,第二个值是被测量的物体温度,如果是你想要的,可以接着往下看. 1.外观 说明:虽然mlx90614非接触式红外测温传感器形态各异, ...
- GY906 MLX90614 非接触式 红外测温传感器 LabVIEW i2c总线数据读取
GY906使用的红外测温芯片为MLX90614. 使用LabVIEW读取i2c总线数据时,需要知道传感器的地址,出厂默认为0x5A.传感器地址支持自己修改,存放在芯片EEPROM的0x0E位置,可以通 ...
- Arduino使用MLX90614 非接触式红外测温传感器
相关资料链接 链接:https://pan.baidu.com/s/1eE0rkaSJsKJMU_RUorS5OA 提取码:3ujh 1.1 介绍: MLX90614是一款由迈来芯公司提供的低成本,无 ...
- ESP32设备驱动-MLX90614红外测温传感器驱动
MLX90614红外测温传感器驱动 1.MLX90614介绍 MLX90614 是一款用于非接触式温度测量的红外温度计.IR 敏感型热电堆检测器芯片和信号调节 ASIC 都集成在同一 TO-39 罐封 ...
- TI红外测温传感器TMP006
最近在做红外测温的项目,试了几个不同公司的红外产品,最早拿到手的是TI的这款芯片式的红外温度传感器TMP006,TI关于这款芯片的介绍是世界上首款单片数字IR MEMS温度传感器,首次为便携式消费电子 ...
最新文章
- mysql之字符编码问题
- 咱们码农可以从曾国藩身上学到点什么呢?
- 在Android 华为手机上运行React_Native工程时出现了如下错误,做以记录:
- 中音萨克斯指法表图_萨克斯的几个特殊指法记忆和几个概念
- 自定义控件实现(转)
- 如何构建自己的笔记系统?
- 计算机考试准考证下载打不开
- 系统架构设计师 - ESB 企业服务总线
- 将RDL报表转换成RDLC报表的函数
- 十年微博与没落搜狐的社交求变
- 嵌入式单片机基础篇(二十三)之串口通信
- signature=5a522a8356f9906b0b775bdada02a4c6,合肥2016年4月29日至2016年5月12日交通违章查询...
- [Web端接入经验分享] 腾讯云即时通信TIM、实时音视频TRTC
- 2021.07.22禾赛提前批一面面经
- ggalluvial:冲击图展示组间变化、时间序列和复杂多属性alluvial diagram
- 安卓如何实现动态广告栏
- WordPress网站底部设置网站已运行时间
- 百度搜索引擎压力测试报告
- 无线通信信号传输模型
- 反编译apk获得源代码