Stm32f103c8t6驱动JX90614红外测温传感器

1.JX90614红外测温传感器

之前想要做一期红外测温的实验,但是发现可参考的资料多是主流的MLX90614,JX90614的资料非常稀少,决定自己写驱动根据数据手册复现。该传感器使用IIC协议进行通信,通过读取数据寄存器当中的值即可获得当前的温度值(具体参考数据手册)

首先是他的电路连接,非常简单,我们采用软件IIC进行通信(任意选择两个GPIO配置为开漏输出模式即可),这里需要注意的是,该模块没有包含上拉电阻,需要在SDA、SCK与VCC之前都接上4.7K的电阻。

2.手把手复现

首先完成软件IIC接口的编写,这里使用PB11作为SDA,PB10作为SCK。

MI2C.h

#ifndef _MI2C_H
#define _MI2C_H

#include "stm32f10x.h"                  // Device header
#define GPIO_SDA_PORT  GPIOB
#define GPIO_SDA_PIN   GPIO_Pin_11
#define GPIO_SCK_PORT  GPIOB
#define GPIO_SCK_PIN   GPIO_Pin_10


void MI2C_Init(void);
void MI2C_W_SDA(uint8_t BitV);
void MI2C_W_SCK(uint8_t BitV);
uint8_t MI2C_R_SDA(void);
void App_I2C_Start(void);
void App_I2C_Stop(void);
void App_I2C_WriteByte(uint8_t Data);
uint8_t App_I2C_ReadByte(void);
void App_I2C_SendAck(uint8_t BitAck);
uint8_t App_I2C_ReceiveAck(void);

#endif

MI2C.c

#include "stm32f10x.h"                  // Device header
#include "MI2C.h"
#include "Delay.h"
//IO初始化
void MI2C_Init(void)
{
		/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);		//开启GPIOB的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);						//将PB10和PB11引脚初始化为开漏输出
	
	GPIO_SetBits(GPIOB, GPIO_Pin_10 | GPIO_Pin_11);
}

//写数据线
void MI2C_W_SDA(uint8_t BitV)
{
		GPIO_WriteBit(GPIO_SDA_PORT,GPIO_SDA_PIN,(BitAction)BitV);
	  Delay_us(2);
}
//写时钟线
void MI2C_W_SCK(uint8_t BitV)
{
	  GPIO_WriteBit(GPIO_SCK_PORT,GPIO_SCK_PIN,(BitAction)BitV);
	  Delay_us(2);
}

//读数据线
uint8_t MI2C_R_SDA(void)
{
		uint8_t Data;
	  Data = GPIO_ReadInputDataBit(GPIO_SDA_PORT,GPIO_SDA_PIN);
	  Delay_us(2);
	  return Data;
}
//起始位
void App_I2C_Start(void)
{
	  MI2C_W_SDA(1);
		MI2C_W_SCK(1);
	  MI2C_W_SDA(0);
		MI2C_W_SCK(0);
}
//停止位
void App_I2C_Stop(void)
{
	
	  MI2C_W_SDA(0);
		MI2C_W_SCK(1);
		MI2C_W_SDA(1);
}

//写1Byte数据
void App_I2C_WriteByte(uint8_t Data)
{
	 for(int i=0;i<8;i++)
	 {
			MI2C_W_SDA((0x80>>i)&Data);
		  MI2C_W_SCK(1);
		  MI2C_W_SCK(0);
	 }
}

//read 1Byte Data
uint8_t App_I2C_ReadByte(void)
{
		uint8_t Byte = 0x00;
	  MI2C_W_SDA(1);
	  for(int i=0;i<8;i++)
		{
			 MI2C_W_SCK(1);
			 if(MI2C_R_SDA()==1)
			 {
					Byte = Byte|(0x80>>i);
			 }
			 MI2C_W_SCK(0);
		}
		return Byte;
}

//发送应答
void App_I2C_SendAck(uint8_t BitAck)
{
		MI2C_W_SDA(BitAck);
	  MI2C_W_SCK(1);
	  MI2C_W_SCK(0);
}

//接收应答
uint8_t App_I2C_ReceiveAck(void)
{
	  uint8_t Data=0;
		MI2C_W_SDA(1);//主机释放总线
	  MI2C_W_SCK(1);
		Data = MI2C_R_SDA();
	  MI2C_W_SCK(0);
	  return Data;
}

然后我们通过查数据手册知道JX90164的设备地址为0x7F,设备的初始化和运行过程如下图

另外,从寄存器的描述章节可以找到数据存储的方式

可以看到温度数据是一个24bit的数据,我们需要分别接收MSB,CSB、LSB的8bit数据,然后合成一个24bit数据,就如下面的JX90164_Get_T_Data函数所写的内容一样。

JX90164.h

#ifndef _JX90614_H
#define _JX90614_H
#include "stm32f10x.h"                  // Device header
#include "MI2C.h"
#include "Serial.h"

void JX90164_WriteReg(uint8_t Address,uint8_t data);
uint8_t JX90164_ReadReg(uint8_t Address);
void JX90164_Init(void);
void JX90164_Get_T_Data(int32_t* Temp);

#endif 

JX90164_REG.h

#ifndef __JX90164_REG_H
#define __JX90164_REG_H


#define Soft_Reset 0x00
#define Data_ready 0x02
#define DATA1_MSB  0x10
#define DATA1_CSB  0x11
#define DATA1_LSB  0x12
#define CMD        0x30
#endif

JX90164.c

#include "stm32f10x.h"                  // Device header
#include "MI2C.h"
#include "Serial.h"
#include "JX90614.h"
#include "JX90614_reg.h"
#include "math.h"
#define JX90164_ADDRESS 0x7F


void JX90164_WriteReg(uint8_t Address,uint8_t data)
{
		App_I2C_Start();
	  App_I2C_WriteByte(JX90164_ADDRESS<<1);
	  App_I2C_ReceiveAck();
	  App_I2C_WriteByte(Address);
	  App_I2C_ReceiveAck();
	  App_I2C_WriteByte(data);
	  App_I2C_ReceiveAck();
	  App_I2C_Stop();
}

uint8_t JX90164_ReadReg(uint8_t Address)
{
	  uint8_t data;
		App_I2C_Start();
	  App_I2C_WriteByte(JX90164_ADDRESS<<1);
	  App_I2C_ReceiveAck();
	  App_I2C_WriteByte(Address);
	  App_I2C_ReceiveAck();
	
	
	  App_I2C_Start();
	  App_I2C_WriteByte(JX90164_ADDRESS<<1 | (0x01));
	  App_I2C_ReceiveAck();
	  data = App_I2C_ReadByte();
		App_I2C_SendAck(1);
	  App_I2C_Stop();
		
	  return data;
}

void JX90164_Init(void)
{
	  MI2C_Init();
		JX90164_WriteReg(CMD,0x00);
	  JX90164_WriteReg(CMD,0x08);
	  //JX90164_WriteReg(CMD,0x00);
}


void JX90164_Get_T_Data(int32_t* Temp)
{
		uint8_t DataH,DataC,DataL;
	  uint8_t Flag = 0x00;
	  Flag = JX90164_ReadReg(Data_ready);
	  DataH = JX90164_ReadReg(DATA1_MSB);
	  DataC = JX90164_ReadReg(DATA1_CSB);
	  DataL = JX90164_ReadReg(DATA1_LSB);
	  *Temp = (DataH<<16)|(DataC<<8)|(DataL);
}

最后需要对取得的数据在除以2的14次方就可以得到室温数据。

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "mpu6050.h"
#include "MI2C.h"
#include "Serial.h"
#include "JX90614.h"
#include "math.h"
int32_t Temp;
int32_t realT;
uint8_t data_sda;
uint8_t data_sck;
int main(void)
{
	/*模块初始化*/
	OLED_Init();		//OLED初始化
	Serial_Init();
	//MI2C_Init();
	JX90164_Init();
	
	while (1)
	{
		data_sda = MI2C_R_SDA();
//		data_sck = GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_10);
		OLED_ShowString(2,1,"tempTEST");
			JX90164_Get_T_Data(&Temp);
		 realT = Temp/(pow(2,14));
		Serial_Printf("temp: %d\r\n", realT);
		USART_Cmd(USART1,DISABLE);
		  OLED_ShowSignedNum(3, 1, realT, 5);
		USART_Cmd(USART1,ENABLE);
	}
}

实验结果如图

完整工程可以访问链接:https://download.csdn.net/download/qq_44465154/90576239?spm=1001.2101.3001.9500

### STM32 驱动 JX90614 红外测温传感器标准库示例代码 对于STM32平台上的JX90614红外测温传感器,其驱动程序主要依赖于I²C通信协议来完成数据交换。下面提供一段基于ST官方标准库的简化版代码实例用于初始化配置以及读取环境温度。 #### 初始化 IIC 接口函数 ```c void MX_I2C1_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; I2C_InitTypeDef I2C_InitStruct = {0}; /* 使能GPIO与时钟 */ __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_I2C1_CLK_ENABLE(); /**I2C1 GPIO Configuration PB6 ------> I2C1_SCL PB7 ------> I2C1_SDA */ GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // 设置I2C参数 I2C_InitStruct.Timing = 0x20909CEC; // 自定义时序设置 I2C_InitStruct.OwnAddress1 = 0; I2C_InitStruct.AddressingMode = I2C_ADDRESSINGMODE_7BIT; I2C_InitStruct.DualAddressMode = I2C_DUALADDRESS_DISABLE; I2C_InitStruct.OwnAddress2 = 0; I2C_InitStruct.GeneralCallMode = I2C_GENERALCALL_DISABLE; I2C_InitStruct.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK){ Error_Handler(); } } ``` #### 定义 MLX90614 寄存器地址与操作宏命令 ```c #define MLX90614_I2C_ADDR ((uint8_t)0x5A<<1) /* Object temperature register address */ #define MLX90614_TOBJ1 0x07 // 发送启动测量指令给MLX90614 static void Start_Measurement(void){ uint8_t data[2]; data[0]=MLX90614_TOBJ1; HAL_I2C_Master_Transmit(&hi2c1,(MLX90614_I2C_ADDR),data,1,HAL_MAX_DELAY); } // 获取目标物体温度值 float Get_Temperature(void){ float temp=0.0f; int16_t raw_data; uint8_t reg_addr = MLX90614_TOBJ1; uint8_t rx_buffer[2]; HAL_I2C_Master_Transmit(&hi2c1, MLX90614_I2C_ADDR,&reg_addr,sizeof(reg_addr),HAL_MAX_DELAY); HAL_Delay(10); // 延迟等待转换完成 HAL_I2C_Master_Receive(&hi2c1, MLX90614_I2C_ADDR,rx_buffer, sizeof(rx_buffer), HAL_MAX_DELAY); raw_data=((int16_t)(rx_buffer[0]<<8)|rx_buffer[1]); temp=(raw_data*0.02)-273.15; // 将原始数值转化为摄氏度 return temp; } ``` 上述代码展示了如何利用STM32的标准库通过I²C接口访问并获取来自JX90614(兼容MLX90614红外线温度计的数据[^1]。需要注意的是,在实际应用中可能还需要考虑更多细节如错误处理机制、电源管理等。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值