GXP9541差压传感器驱动程序

发布时间:2024年01月06日

一、产品特点

  1. 小型化、MEMS?技术
  2. 压力量程可定制差压、表压?0.2KPa.0.5KPa.2.5KPa.10KPa
  3. 高速?24bit?I2C?数字输出
  4. 高精度压力监测
  5. 耐用型?SOIC?封装、双垂直气嘴易安装

二、典型应用

引脚编号

引脚定义

说明

1.2.3.4.5.8.9.12.13.14.15.16

?????????????NC

空置

6

VSS

电源地

7

VDD

电源正

10

SDA

数据

11

SCL

时钟?

I2C ?总线使用 ?SCL ?和 ?SDA ?作为信号线。这两根线都通过上拉电阻连接到 ?VDD,通信时都保持为高电平。

?三、通信协议

1、寄存器地址?

地址

位地址

寄存器名称

默认值

描述描述

0x30

7-4

Reserve

4'b0000

写入0x0A开始单次压力采集模式,当寄存器值变为0x02时,单次采集完 成;

3

Sco

1'b0

2-0

Measurement ctn<2:0>

3'b000

0x06

7-0

PDATA<23:16>

0x00

24bit有符号数,存储经过校准的压力传感器数据 若最高位为0,?

Pdata = PDataxos*65536+ PData.o7*256+PDataoxo8;

若最高位为1,?

Pdata = PData.o6*65536+PDataxo*256+ PDatax8-16777216;

0x07

7-0

PDATA<15:8>

?0x00

0x08

7-0

PDATA<7:0>

0x00

2、数字输出转换?

使用如下等式,可将数字输出寄存器值转化为压力值:

P=(Code-0.5)/0.4*PH

其中 Code 为数据寄存器归一化值(Pdata /8388608);PH 为满量程压力值,P 为实际压力

值,单位为 kPa;

测量压力值转换示例:

若所选型号满量程气压为10kPa,当 0x06、0x07、0x08 寄存器的值分别为 0x5E,0xBE,0xBF,

Pdata =94 * 65536+ 190 * 256 + 191 = 6209215,

得到压力值 P(kPa) = (Pdata /8388608-0.5)/0.4*10= 6 kPa。

3、接口协议

(1)设备地址

该系列产品的 ?I2C ?设备地址如下:

A7

A6

A5

A4

A3

A2

A1

A0

W/R

1

1

1

1

1

1

1

1

1

(2)I2C协议?

?(3)I2C 写时序:
写操作是以写入模式(读写位为0)发送从机地址来实现的, 从而产生从机写地址11111110b。然后主机发送成对的寄存器地址及对应的数值。写操作以 STOP 位终止。 图示表格以写 0x30 寄存器为例,

I2C 读时序如下:

在开始读操作之前,首先寄存器地址在写模式(从机地址 11111110b)下被发送。然后重新产生开始信号,之后从机在读模式下以 I2C 地址(11111111b)被寻址。从机从寄存器地址开始发送寄存器值直到一个 NOACK 信号和停止条件产生,读操作结束。图示表格以读取0x06,0x07,0x08 寄存器,

四、单片机驱动程序

?STM32F103 + GXP9541压差传感器驱动实例?

1、I2C1.h

#ifndef __IIC1_H
#define __IIC1_H


#include "stdint.h"
#include "stm32f10x.h"                  // Device header
#include "string.h"


#define SCL GPIO_Pin_8		//PB6---CTRL_SCL
#define SDA GPIO_Pin_9		//PB7---CTRL_SDA
#define I2C1_PORT GPIOB		//IIC端口
#define I2C1_SCL_H GPIO_SetBits(I2C1_PORT,SCL)
#define I2C1_SCL_L GPIO_ResetBits(I2C1_PORT,SCL)
#define I2C1_SDA_H GPIO_SetBits(I2C1_PORT,SDA)
#define I2C1_SDA_L GPIO_ResetBits(I2C1_PORT,SDA)
#define I2C1_Read GPIO_ReadInputDataBit(I2C1_PORT, SDA)

void I2C1_INIT(void);
void I2C_SDA_OUT(void);
void I2C1_SDA_IN(void);
void I2C1_Start(void);
void I2C1_Stop(void);
void I2C1_SendByte(uint8_t Byte);
void I2C1_Ack(void);
void I2C1_NAck(void);
uint8_t I2C1_Read_Byte(uint8_t ack);
uint8_t I2C1_Wait_Ack(void);
#endif

2、I2C1.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "string.h"
#include "I2C1.h"
/***********
*		推挽输出
************/
void I2C1_INIT(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = SDA | SCL;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;	
	GPIO_Init(I2C1_PORT,&GPIO_InitStructure);
	
	I2C1_SCL_H;
	I2C1_SDA_H;
}
/*******************************************************************************
 * 函 数 名         : I2C_SDA_OUT
 * 函数功能		   : SDA输出配置
 * 输    入         : 无
 * 输    出         : 无
 *******************************************************************************/
void I2C_SDA_OUT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = SDA;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_Init(I2C1_PORT, &GPIO_InitStructure);
}
void I2C1_SDA_IN(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = SDA;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(I2C1_PORT, &GPIO_InitStructure);
}
/*******************************************************************************
* 函 数 名         : I2C1_Start
* 函数功能		   : 产生起始信号
*******************************************************************************/
void I2C1_Start(void)
{

	I2C_SDA_OUT();
	I2C1_SCL_H;
	I2C1_SDA_H;

	Delay_us(5);
	I2C1_SDA_L;
	Delay_us(6);
	I2C1_SCL_L;
	
}
/*******************************************************************************
* 函 数 名         : I2C1_Stop
* 函数功能		   : 产生停止信号
*******************************************************************************/
void I2C1_Stop(void)
{
	I2C_SDA_OUT();
	I2C1_SCL_L;
	I2C1_SDA_L;
	I2C1_SCL_H;
	Delay_us(6);
	I2C1_SDA_H;
	Delay_us(6);

}

/*******************************************************************************
* 函 数 名         : I2C1_SendByte
* 函数功能		   : 发送一个字节
*******************************************************************************/
void I2C1_SendByte(uint8_t Byte)
{
	uint8_t i;
	I2C_SDA_OUT();
	I2C1_SCL_L;

	for(i=0;i<8;i++)
	{
		if((Byte & 0x80) > 0)  // 0x80  1000 0000
				I2C1_SDA_H;
		else
				I2C1_SDA_L;

		Byte <<= 1;
		Delay_us(1);
		I2C1_SCL_H;
		Delay_us(2);
		I2C1_SCL_L;
		Delay_us(2);
	}
}

/*******************************************************************************
* 函 数 名         : I2C1_Ack
* 函数功能		   : 主机产生应答信号ACK
*******************************************************************************/

void I2C1_Ack(void)
{
	I2C1_SCL_L;
	I2C_SDA_OUT();
	
	I2C1_SDA_L;
	Delay_us(1);
	
	I2C1_SCL_H;
	Delay_us(3);
	I2C1_SCL_L;
}
/*******************************************************************************
* 函 数 名         : I2C1_NAck
* 函数功能		   : 主机不产生应答信号NACK
*******************************************************************************/

void I2C1_NAck(void)
{
	I2C1_SCL_L;
	I2C_SDA_OUT();
	
	I2C1_SDA_H;
	Delay_us(1);
	
	I2C1_SCL_H;
	Delay_us(3);
	I2C1_SCL_L;
}
/*******************************************************************************
* 函 数 名         : I2C1_Read_Byte
* 函数功能		   : 主机读取一个字节
*******************************************************************************/
uint8_t I2C1_Read_Byte(uint8_t ack)
{
    uint8_t i = 0, receive = 0,tempTime=0;
    I2C1_SDA_IN();

    for(i = 0; i < 8; i++)
    {
        I2C1_SCL_L;
        Delay_us(2);
        I2C1_SCL_H;
        while((!GPIO_ReadInputDataBit(I2C1_PORT, SCL)) && tempTime < 10)
        {
            tempTime += 1;
            Delay_us(1);
        }
        receive <<= 1;
				
        if(GPIO_ReadInputDataBit(I2C1_PORT, SDA))receive++;
        Delay_us(1);
    }

    if(ack == 0)
        I2C1_NAck();
    else
        I2C1_Ack();

    return receive;
}

/*******************************************************************************
* 函 数 名         : I2C1_Wait_Ack
* 函数功能		   : 等待从机应答信号
  返回值:            1 接收应答失败
		  	         0 接收应答成功
*******************************************************************************/
uint8_t I2C1_Wait_Ack(void)	//返回值为0表示做出应答
{
	uint8_t ucErrTime=0;
	I2C1_SDA_IN();
	
	I2C1_SDA_H;
	Delay_us(1);
	
	I2C1_SCL_H;	
	Delay_us(1);
	
		while(GPIO_ReadInputDataBit(I2C1_PORT, SDA))
	{
		ucErrTime++;
		Delay_us(1);
		if(ucErrTime>250)
		{
			I2C1_Stop();
			return 1;
		}
	}
	I2C1_SCL_L;	
	Delay_us(1);

	return 0;
}

3、GXP9541.h

#ifndef __GXP9541_H
#define __GXP9541_H 
  
#include "stm32f10x.h"


// 初始化I2C1串口
void GXP9541_Init(void);
void GXP9541_Add(u8 add);
void GXP9541_Write(u8 add,u8 data);
void GXP9541_ReadData(void);
#endif

4、GXP9541.c

#include "GXP9541.h"
#include "Delay.h"
#include "stdio.h" // printf用
#include "Serial.h"
#include "I2C1.h"

uint16_t Pdata;


// 初始化I2C1串口
void GXP9541_Init(void)
{
	I2C1_INIT();
}
void GXP9541_Add(u8 add)//写寄存器地址
{
	I2C1_Start();//开始
	I2C1_SendByte(0Xfe);           //发送写地址	   
	I2C1_Wait_Ack();
	I2C1_SendByte(add);						//要写的寄存器地址
	I2C1_Wait_Ack();
	I2C1_Stop();//停止
}
void GXP9541_Write(u8 add,u8 data)//向某寄存疲写某值
{
	I2C1_Start();//开始
	I2C1_SendByte(0Xfe);           //发送写地址	   
	I2C1_Wait_Ack();
	I2C1_SendByte(add);						//要写的寄存器地址
	I2C1_Wait_Ack();
	I2C1_SendByte(data);					//要写的数据
	I2C1_Wait_Ack(); 
	I2C1_Stop();//停止
}
uint8_t GXP9541_Gather(void)			//单次压力采集模式
{
	uint8_t data=0;
	GXP9541_Write(0X30,0X0a);           //开始单次压力采集模式
	GXP9541_Add(0X30);           				//写寄存器地址
	
	data=I2C1_Read_Byte(0);							//读取寄存器值
	I2C1_Stop();//停止
	if(data==0X02)											//寄存器值为0X02时单次压力采集完成
	{
		return 1;	
	}
	else
	{
		return 0;
	}
}
void GXP9541_ReadData(void)
{    
	uint8_t i=0,ack=0;
	uint8_t p[3];
	while(GXP9541_Gather())//等待压力采集完成
		{
			I2C1_Start();//开始
			GXP9541_Add(0X06);
			
			Delay_ms(10);
			I2C1_Start();
			I2C1_SendByte(0Xff);
			I2C1_Wait_Ack();	
			
			for(i=0;i<3;i++)
			{
			 if(i<2)
			 {
					ack=1;
			 }
			 else
			 {
					ack=0;//最后一个发送nack
			 }
			p[i]=I2C1_Read_Byte(ack);	
			}
		 I2C1_Stop();//停	止
		}
	Delay_ms(10);
	
//	if(p[2] & 0X80)
//	{
//		Pdata=(float)(p[0]*65536+p[1]*256+p[2]-16777216);
//	}
//	else
//	{
//		Pdata=(float)(p[0]*65536+p[1]*256+p[2]);
//	}
//	Pa=(Pdata/8388608-0.5)/0.4*10;   //Kpa
	Serial_SendByte(p[0]);
	Serial_SendByte(p[1]);
	Serial_SendByte(p[2]);
}	
友情提示:
欢迎各位伙伴咨询、测试有任何问题可随时交流沟通。
TEL : 15134034823?!!! 欢迎骚扰,哈哈^_^。
文章来源:https://blog.csdn.net/weixin_45837673/article/details/135412593
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。