打印
[STM32F1]

Stm32f103c8t6驱动JX90614红外测温传感器

[复制链接]
288|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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);
        }
}

实验结果如图



完整工程可以访问顶部链接
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/qq_44465154/article/details/147044311

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

27

主题

80

帖子

0

粉丝