一、产品特点
• 压力范围±500Pa,精度高达±3.0%m.v.
• 基于热式流量测量的压力
• 出色的迟滞性和重复性
• 线性化和温度补偿
• 16位分辨率的数字I2C
• 低零点漂移
• 最小可检测压差0.02pa
二、典型应用
|
引脚 |
名字 |
描述 |
|
1 |
SCL |
I2C总线串行时钟线 |
|
2 |
VDD |
电源 |
|
3 |
GND |
地 |
|
4 |
SDA |
I2C总线串行数据线 |

三、通信协议
每个SCL和SDA线路必须使用约4.7k欧姆的上拉电阻器连接到VDD,GXPP800的VDD输入范围为3-5.5V,但建议的VDD为5V(校准条件)。
I2C地址:0x25

|
字节数量 |
数据定义 |
|
Byte1 |
差压高字节 |
|
Byte2 |
差压低字节 |
|
Byte3 |
CRC |
|
Byte4 |
温度高字节 |
|
Byte5 |
温度低字节 |
|
Byte6 |
CRC |
CRC校验字节是对16 bit数据进行的CRC运算:

四、驱动代码
1、I2C1.h
#ifndef __IIC_H
#define __IIC_H
#include "stdint.h"
#include "stm32f10x.h" // Device header
#include "string.h"
void I2C_init(void);
void I2C_Start(void);
void I2C_Spot(void);
void I2C_SendByte(uint8_t Byte);
uint8_t I2C_ReceiveByte(void);
void I2C_SendAck(uint8_t Ackbit);
uint8_t I2C_ReceiveAck(void);
void I2C_SCL_H(void);
void I2C_SCL_L(void);
void I2C_W_SDA(uint8_t BitValue);
void I2C_W_SCL(uint8_t BitValue);
uint8_t I2C_R_SDA(void);
#endif
2、 I2C1.c
#include "I2C1.h"
#include "delay.h"
#include "stdio.h"
/***********
* 推挽输出
************/
void I2C1_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = I2C1_SCL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(I2C1_SCL_GPIOX, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = I2C1_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(I2C1_SDA_GPIOX, &GPIO_InitStructure);
I2C1_SCL_H;
I2C1_SDA_H;
}
/*******************************************************************************
* 函 数 名 : I2C_SDA_OUT
* 函数功能 : SDA输出配置
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void I2C1_SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = I2C1_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(I2C1_SDA_GPIOX, &GPIO_InitStructure);
}
void I2C1_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = I2C1_SDA;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(I2C1_SDA_GPIOX, &GPIO_InitStructure);
}
/*******************************************************************************
* 函 数 名 : I2C1_Start
* 函数功能 : 产生起始信号
*******************************************************************************/
void I2C1_Start(void)
{
I2C1_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)
{
I2C1_SDA_OUT();
I2C1_SCL_L;
I2C1_SDA_L;
I2C1_SCL_H;
Delay_us(6);
I2C1_SDA_H;
Delay_us(6);
}
void I2C_RS(void)
{
I2C1_SDA_OUT();
I2C1_SCL_L;
Delay_us(2);
I2C1_SDA_L;
Delay_us(2);
I2C1_SDA_H;
Delay_us(2);
I2C1_SCL_H;
Delay_us(2);
I2C1_SDA_L;
Delay_us(2);
I2C1_SCL_L;
Delay_us(2);
}
/*******************************************************************************
* 函 数 名 : I2C1_Ack
* 函数功能 : 主机产生应答信号ACK
*******************************************************************************/
void I2C1_Ack(void)
{
I2C1_SCL_L;
I2C1_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;
I2C1_SDA_OUT();
I2C1_SDA_H;
Delay_us(1);
I2C1_SCL_H;
Delay_us(3);
I2C1_SCL_L;
}
/*******************************************************************************
* 函 数 名 : I2C1_Wait_Ack
* 函数功能 : 等待从机应答信号
返回值: 1 接收应答失败
0 接收应答成功
*******************************************************************************/
uint8_t I2C1_Wait_Ack(void)
{
uint8_t tempTime = 0;
I2C1_SDA_IN();
I2C1_SDA_H;
Delay_us(1);
I2C1_SCL_H;
Delay_us(1);
while(GPIO_ReadInputDataBit(I2C1_SDA_GPIOX, I2C1_SDA))
{
tempTime++;
Delay_us(1);
if(tempTime > 250)
{
I2C1_Stop();
return 1;
}
}
I2C1_SCL_L;
Delay_us(1);
return 0;
}
/*******************************************************************************
* 函 数 名 : I2C1_SendByte
* 函数功能 : 发送一个字节
*******************************************************************************/
void I2C1_SendByte(uint8_t txd)
{
uint8_t i = 0;
I2C1_SDA_OUT();
I2C1_SCL_L;
for(i = 0; i < 8; i++)
{
if((txd & 0x80) > 0) // 0x80 1000 0000
I2C1_SDA_H;
else
I2C1_SDA_L;
txd <<= 1;
Delay_us(1);
I2C1_SCL_H;
Delay_us(2);
I2C1_SCL_L;
Delay_us(2);
}
}
/*******************************************************************************
* 函 数 名 : I2C1_Read_Byte
* 函数功能 : 主机读取一个字节
*******************************************************************************/
uint8_t I2C1_ReadByte(uint8_t ack)
{
uint8_t i = 0, receive = 0;
uint8_t tempTime = 0;
I2C1_SDA_IN();
for(i = 0; i < 8; i++)
{
I2C1_SCL_L;
Delay_us(2);
I2C1_SCL_H;
while((!GPIO_ReadInputDataBit(I2C1_SCL_GPIOX, I2C1_SCL)) && tempTime < 10)
{
tempTime += 1;
Delay_us(1);
}
receive <<= 1;
if(GPIO_ReadInputDataBit(I2C1_SDA_GPIOX, I2C1_SDA))
receive++;
Delay_us(1);
}
if(ack == 0)
I2C1_NAck();
else
I2C1_Ack();
return receive;
}
/*******************************************************************************
* 函 数 名 : I2C_read_bit
* 函数功能 : 主机读取一位
*******************************************************************************/
uint8_t I2C_read_bit(void)
{
uint8_t i;
I2C1_SDA_IN();
I2C1_SCL_L;
Delay_us(2);
I2C1_SCL_H;
Delay_us(2);
// while(!GPIO_ReadInputDataBit(I2C1_SCL_GPIOX, I2C_SCL_L))
// ;
i = GPIO_ReadInputDataBit(I2C1_SDA_GPIOX, I2C1_SDA);
Delay_us(2);
I2C1_SCL_L;
Delay_us(2);
return i;
}
3、GXP800.h
#ifndef __GXP800_H
#define __GXP800_H
#include "stm32f10x.h"
// 初始化I2C1串口
void GXP800_init(void);
//GXP800连续测量
void GXP800_Write_Cmd(uint16_t cmd);
//GXP800获取值
void GXP800_GetValue(void);
void GXP800_Read(uint16_t add);
void GXP800_GetValue1(void);
void GXP800_ReadData(void);
void GXP800_ReadData1(void);
uint8_t crc8(uint16_t data);
#endif
4、GXP800.c
#include "GXP800.h"
#include "Delay.h"
#include "stdio.h" // printf用
#include "Serial.h"
#include "I2C1.h"
//uint8_t crc = 0xff;
uint16_t dif_pressure;//差压
uint16_t tempre; //温度
uint16_t Scale_Factors; //压差系数
// 初始化I2C1串口
void GXP800_init(void)
{
I2C1_INIT();
}
void GXP800_Read(uint16_t add)
{
I2C1_Start();
I2C1_SendByte(0X4a); //发送写地址
I2C1_Wait_Ack();
I2C1_SendByte(add>>8);//发送高地址
I2C1_Wait_Ack();
I2C1_SendByte(add); //发送低地址
I2C1_Wait_Ack();
I2C1_Stop();//停止
SDP800_ReadData();
}
void GXP800_ReadData(void)
{
uint8_t i=0;
uint8_t ack=0;
uint8_t p[8];
Delay_ms(20);
I2C1_Start();
I2C1_SendByte(0X4b); //发送读地址
I2C1_Wait_Ack();
for(i=0;i<6;i++)
{
if(i<5)
{
ack=1;
}
else
{
ack=0;//最后一个发送nack
}
p[i]=I2C1_ReadByte(ack);
}
I2C1_Stop();//停 止
Delay_ms(5);
if((crc8((p[0]<<8)+p[1])==p[2])&&(crc8((p[3]<<8)+p[4])==p[5]))
{
Serial_SendByte(p[0]);
Serial_SendByte(p[1]);
Serial_SendByte(p[2]);
Serial_SendByte(p[3]);
Serial_SendByte(p[4]);
Serial_SendByte(p[5]);
}
else
{
GXP800_ReadData1();
}
}
void GXP800_ReadData1(void)
{
uint8_t i=0;
uint8_t ack=0;
uint8_t p[8];
Delay_ms(20);
I2C1_Start();
I2C1_SendByte(0X4b); //发送读地址
I2C1_Wait_Ack();
for(i=0;i<6;i++)
{
if(i<5)
{
ack=1;
}
else
{
ack=0;//最后一个发送nack
}
p[i]=I2C1_ReadByte(ack);
}
I2C1_Stop();//停 止
Delay_ms(5);
if((crc8((p[0]<<8)+p[1])==p[2])&&(crc8((p[3]<<8)+p[4])==p[5]))
{
Serial_SendByte(p[0]);
Serial_SendByte(p[1]);
Serial_SendByte(p[2]);
Serial_SendByte(p[3]);
Serial_SendByte(p[4]);
Serial_SendByte(p[5]);
}
else
{
SDP800_ReadData();
}
}
//GXP800连续测量
void GXP800_Write_Cmd(uint16_t cmd)
{
I2C1_Start();
I2C1_SendByte(0X4a); //读地址
I2C1_Wait_Ack();
I2C1_SendByte(cmd>>8);//发送高地址
I2C1_Wait_Ack();
I2C1_SendByte(cmd); //发送低地址
I2C1_Wait_Ack();
I2C1_Stop();//停止
Delay_ms(10);
}
//GXP800获取值
void GXP800_GetValue(void)
{
GXP800_Read(0x3615);
}
//滤波输出
void GXP800_GetValue1(void)
{
GXP800_Read(0x361e);
}
/******************************************************************************
* Name: CRC-8 x8+x5+x4+1
* Poly: 0x31
* Init: 0xFF
* Refin: False
* Refout: False
* Xorout: 0x00
* Note:
*****************************************************************************/
uint8_t crc8(uint16_t data) {
uint8_t i,j;
uint8_t dat[2];
dat[0]=data>>8;
dat[1]=data;
uint8_t crc=0XFF; /* 计算的初始crc值: 0 - 输入值, 1 - 输入翻转 */
for(j=0;j<2;j++)
{
crc ^= dat[j]; /* 每次先与需要计算的数据异或,计算完指向下一数据 */
for (i=8; i>0; --i) /* 下面这段计算过程与计算一个字节crc一样 */
{
if (crc & 0x80)
crc = (crc << 1) ^ 0x31;
else
crc = (crc << 1);
}
}
//reture (~crc); /* 输出翻转 */
return (crc);
}
本文详细介绍了STM32平台上的GXP800压力与温度传感器的I2C通信接口,包括其特点、典型应用、通信协议以及提供了一些关键驱动函数的代码示例,如初始化、数据传输和CRC校验。
2949

被折叠的 条评论
为什么被折叠?



