一、GZP6859D传感器概述
GZP6859D是一款高精度数字式压力传感器,采用I2C数字接口通信。主要特性:
- 24位压力ADC输出
- 16位温度ADC输出
- 支持单次/连续测量模式
- 工作电压:2.7V~5.5V
二、驱动设计解析
在STM32CUBEMX中已经配置好了I2C
2.1 寄存器定义(GZP6859D.h)参考芯片手册
#define GZP6859_K_VALUE 512
#define GZP6859_I2C_ADDR 0x6D // I2C 地址
#define GZP6859_WRITE_BIT 0x00 // I2C 写操作标志位
#define GZP6859_READ_BIT 0x01 // I2C 读操作标志位
// 寄存器地址定义
#define GZP6859_DATA_MSB_ADDR 0x06 // 数据寄存器(MSB)
#define GZP6859_DATA_CSB_ADDR 0x07 // 数据寄存器(CSB)
#define GZP6859_DATA_LSB_ADDR 0x08 // 数据寄存器(LSB)
#define GZP6859_TEMP_MSB_ADDR 0x09 // 温度寄存器(MSB)
#define GZP6859_TEMP_LSB_ADDR 0x0A // 温度寄存器(LSB)
#define GZP6859_CMD_ADDR 0x30 // 命令寄存器地址
#define GZP6859_SYS_CONFIG_ADDR 0xA5 // 系统配置寄存器地址
#define GZP6859_P_CONFIG_ADDR 0xA6 // 压力配置寄存器地址
// 定义 Sleep Time 位掩码,用于设置休眠模式下的时间间隔
#define GZP6859_SLEEP_TIME_MASK (0x0F << 4) // 睡眠时间掩码(4 位,移位4个位置)
#define GZP6859_SET_SLEEP_TIME(value) ((value) << 4) // 设置 Sleep Time,值为 4 位,表示时间间隔
// 定义 Measurement Control 工作模式掩码,3 位
#define GZP6859_MCTRL_MASK (0x07) // 3 位掩码,支持的工作模式:000-011
#define GZP6859_SET_MCTRL(value) ((value) & 0x07) // 设置工作模式(0 到 3 之间的模式)
// 定义 SCO 位掩码,用于是否数据采集完成的标志
// 设置 SCO 位,表示数据采集是否完成,1 为开始采集,0 为采集结束(休眠工作模式除外)
#define GZP6859_SCO_MASK (0x01 << 3) // SCO 位,1 位掩码,表示是否持续采集数据
#define GZP6859_SET_SCO(value) (((value) & 0x01) << 3) // 设置 SCO 位,表示是否持续采集数据,1 为持续采集
#define GZP6859_SCO_START 0x01
#define GZP6859_SCO_END 0x00
// 组合命令:组合 Sleep Time、SCO 和 Measurement Control 设置
#define GZP6859_COMPOSE_CMD(Sleep_time, SCO, MCTRL) \
(GZP6859_SET_SLEEP_TIME(Sleep_time) | GZP6859_SET_SCO(SCO) | GZP6859_SET_MCTRL(MCTRL))
// 工作模式命令宏
#define GZP6859_CMD_SINGLE_TEMP_MODE GZP6859_COMPOSE_CMD(0, 1, 0) // 单次温度采集模式(MCTRL = 000)
#define GZP6859_CMD_SINGLE_PRESS_MODE GZP6859_COMPOSE_CMD(0, 1, 1) // 单次压力采集模式(MCTRL = 001)
#define GZP6859_CMD_COMBINED_MODE GZP6859_COMPOSE_CMD(0, 1, 2) // 组合采集模式(MCTRL = 010)
#define GZP6859_CMD_SLEEP_MODE(Sleep_time) GZP6859_COMPOSE_CMD(Sleep_time, 1, 3) // 休眠模式(MCTRL = 011),需要传入 Sleep_time
// 注释解释:
// - GZP6859_CMD_SINGLE_TEMP_MODE:单次温度采集模式,采集一次温度数据,MCTRL=000,SCO=1。
// - GZP6859_CMD_SINGLE_PRESS_MODE:单次压力采集模式,采集一次压力数据,MCTRL=001,SCO=1。
// - GZP6859_CMD_COMBINED_MODE:组合采集模式,先采集一次温度数据,再采集一次压力数据,MCTRL=010,SCO=1。
// - GZP6859_CMD_SLEEP_MODE:休眠模式,定期进行一次组合采集,SCO=1,MCTRL=011,Sleep_time 用来设置采集间隔(62.5ms 到 1s),间隔值由 Sleep_time 决定。
// Sleep_time 参数:
// 0000 = 无效(不使用)
// 0001 = 62.5ms
// 0010 = 125ms
// 0100 = 500ms
// 1111 = 1s
// 定义返回错误代码
#define GZP6859_READ_SUCCESS 0 // 读取成功
#define GZP6859_READ_ERROR 1 // 一般读取错误
#define GZP6859_READ_REG_ERROR 2 // 寄存器读取错误
2.2 核心数据结构
typedef struct {
int32_t raw_pressure_ad; // 24位原始AD值
int32_t pressure_pa; // 转换后的压力值(Pa)
uint8_t raw_press_data[3]; // 原始寄存器数据
} PressureData;
typedef struct {
int16_t raw_temperature_ad; // 16位温度AD值
int16_t temperature_celsius; // 转换后的温度值
uint8_t raw_temp_data[2]; // 原始温度寄存器数据
} TemperatureData;
2.3 基础通信函数
2.3.1 寄存器读写
HAL_StatusTypeDef GZP6859_ReadReg(I2C_HandleTypeDef *hi2c, uint8_t reg, uint8_t *data, uint8_t length) {
return HAL_I2C_Mem_Read(hi2c, // I2C 接口句柄
(GZP6859_I2C_ADDR << 1) | GZP6859_READ_BIT, // GZP6859 的设备地址,左移一位以符合 I2C 7 位地址协议,加上读标志位
reg, // 要读取的寄存器地址
I2C_MEMADD_SIZE_8BIT, // 寄存器地址的大小为 8 位
data, // 数据存储指针
length, // 数据长度
10 // 超时时间(单位:ms,这里设置为 10ms)
);
}
/**
* @brief 向 GZP6859 设备写入寄存器数据
* @param hi2c 指向 I2C 接口句柄的指针
* @param reg 要写入的寄存器地址
* @param data 要写入的数据指针
* @param length 要写入的数据长度(字节数)
* @retval HAL_StatusTypeDef HAL_I2C_Mem_Write 的返回状态
*/
HAL_StatusTypeDef GZP6859_WriteReg(I2C_HandleTypeDef *hi2c, uint8_t reg, uint8_t *data, uint8_t length) {
return HAL_I2C_Mem_Write(hi2c, // I2C 接口句柄
(GZP6859_I2C_ADDR << 1) | GZP6859_WRITE_BIT, // GZP6859 的设备地址,左移一位以符合 I2C 7 位地址协议,加上写标志位
reg, // 要写入的寄存器地址
I2C_MEMADD_SIZE_8BIT, // 寄存器地址的大小为 8 位
data, // 要写入的数据指针
length, // 数据长度
10 // 超时时间(单位:ms,这里设置为 10ms)
);
}
2.4 数据采集流程
2.4.1 压力数据读取
uint8_t GZP6859_ReadPress(I2C_HandleTypeDef *hi2c, PressureData *pressureData)
{
// 读取三个字节的原始数据
HAL_StatusTypeDef status;
status |= GZP6859_ReadReg(hi2c, GZP6859_DATA_MSB_ADDR,
pressureData->raw_press_data, 3);
// 组合24位AD值
pressureData->raw_pressure_ad = (pressureData->raw_press_data[0] << 16)
| (pressureData->raw_press_data[1] << 8)
| pressureData->raw_press_data[2];
// 补码转换
if(pressureData->raw_pressure_ad > 0x7FFFFF)
pressureData->raw_pressure_ad -= 16777216;
// 转换为Pa值
pressureData->pressure_pa = pressureData->raw_pressure_ad / GZP6859_K_VALUE;
return (status == HAL_OK) ? GZP6859_READ_SUCCESS : GZP6859_READ_ERROR;
}
三、工作模式配置
3.1 模式设置函数
void GZP6859_Set_SinglePress_Mode(I2C_HandleTypeDef *hi2c)
{
uint8_t cmd = GZP6859_CMD_SINGLE_PRESS_MODE;
GZP6859_WriteReg(hi2c, GZP6859_CMD_ADDR, &cmd, 1);
}
3.2 状态检测
uint8_t GZP6859_SCO_Status(I2C_HandleTypeDef *hi2c)
{
uint8_t status;
GZP6859_ReadReg(hi2c, GZP6859_CMD_ADDR, &status, 1);
return (status >> 3) & 0x01; // 提取SCO位
}
四、本次测试
// ============================================================================
// @brief GZP6859_Test1_init 函数初始化(主程序中调用该测试例程时先调用该函数)
// @details 初始化 GZP6859 传感器的组合模式,并读取初始温度数据。
// 该初始化过程是后续单次压力测量的基础。
// ============================================================================
void GZP6859_Test1_init(void){
// 初始化 GZP6859 传感器的组合测量模式
// 组合模式将同时测量温度和压力,为后续单次压力测量提供参考数据
GZP6859_Set_Combine_Mode(&hi2c1);
// 检查传感器配置状态,确保组合模式设置成功
// 如果状态异常,可能需要重新配置传感器
GZP6859_SCO_Status(&hi2c1);
// 以下代码被注释,可能用于调试或未来功能扩展
// 压力数据和温度数据的相关操作暂未启用
// 如果需要恢复这些功能,请取消注释并确保相关数据结构已正确定义
// PressureData pressureData;
// TemperatureData tempData;
// // 读取温度数据
// GZP6859_ReadTemp(&hi2c1, &tempData);
// // 发送原始温度数据(2 字节)
// RS485_SendData(tempData.raw_temp_data, 2);
// // 发送转换后的温度数据(2 字节)
// RS485_SendData(tempData.temperature_bytes, 2);
// // 读取压力数据
// GZP6859_ReadPress(&hi2c1, &pressureData);
// // 发送原始压力数据(3 字节)
// RS485_SendData(pressureData.raw_press_data, 3);
// // 发送转换后的压力数据(4 字节,单位为 Pa)
// RS485_SendData(pressureData.pressure_pa_bytes, 4);
}
// ============================================================================
// @brief GZP6859_Test1 函数(调用该测试例程时运行该函数,该函数循环运行,一般会卡在这个例程的循环中)
// @details 使用 GZP6859 传感器在单次压力测量模式下读取压力数据,并通过 RS485 发送。
// 该函数假设 `GZP6859_Test1_init` 已先调用,完成必要的初始化工作。
// ============================================================================
void GZP6859_Test1(void){
// 创建一个 PressureData 对象,用于存储压力测量结果
PressureData pressureData;
// 设置 GZP6859 传感器为单次压力测量模式
// 该模式将只测量压力,温度数据使用之前组合模式读取的值
GZP6859_Set_SinglePress_Mode(&hi2c1);
// 检查传感器配置状态,确保单次压力测量模式设置成功
// 如果状态异常,可能需要重新配置传感器
GZP6859_SCO_Status(&hi2c1);
// 以下代码被注释,可能用于调试温度数据或未来功能扩展
// 如果需要恢复这些功能,请取消注释并确保相关数据结构已正确定义
// TemperatureData tempData;
// // 设置温度单次测量模式
// GZP6859_Set_SingleTemp_Mode(&hi2c1);
// // 检查传感器配置状态
// GZP6859_SCO_Status(&hi2c1);
// // 读取温度数据
// GZP6859_ReadTemp(&hi2c1, &tempData);
// // 发送原始温度数据(2 字节)
// RS485_SendData(tempData.raw_temp_data, 2);
// // 发送转换后的温度数据(2 字节)
// RS485_SendData(tempData.temperature_bytes, 2);
// 读取压力数据
GZP6859_ReadPress(&hi2c1, &pressureData);
// 发送转换后的压力数据(4 字节,单位为 Pa)
// 该数据可用于后续的压力计算或显示
RS485_SendData(pressureData.pressure_pa_bytes, 4);
// // 发送原始压力数据(3 字节)
// RS485_SendData(pressureData.raw_press_data, 3);
}
五、开发注意事项
-
时序控制要点:
- 模式切换后需等待至少5ms
- 连续测量间隔建议≥50ms
- SCO位为0表示数据就绪
-
精度校准建议:
// 在已知压力环境下进行校准 #define CALIB_OFFSET -123 // 校准偏移量 pressure_pa = (raw_pressure_ad / GZP6859_K_VALUE) + CALIB_OFFSET;
-
异常处理策略:
- 连续3次读取失败触发硬件复位
- AD值超范围时启动自检程序
结语
实际开发中可根据需求调整:
- 增加IIR数字滤波器平滑数据
- 实现自动量程切换功能
- 添加EEPROM校准参数存储