STM32CubeMX配置

打开I2C,设置为Fast Mode Plus

代码编写

 SPL06-001.c

//
// Created by Lenovo on 2025/7/3.
//
#include "SPL06-001.h"
/*寄存器函数*/
#define SPL06_SENSOR_ADDR (0x77 << 1) //SPL06传感器地址
/*传感器初始化函数*/
#define RESET_Addr          0x0C
#define ID_Addr             0x0D
#define MEAS_CFG_Addr       0x08
#define PRS_CFG_Addr        0x06
#define TMP_CFG_Addr        0x07
#define CFG_REG_Addr        0x09

uint8_t SPL06_Init(I2C_HandleTypeDef *hi2c){
    // 复位传感器
    uint8_t reset_cmd = 0x09;
    HAL_I2C_Mem_Write(hi2c, SPL06_SENSOR_ADDR, RESET_Addr, I2C_MEMADD_SIZE_8BIT, &reset_cmd, 1, 100);
    HAL_Delay(200);  // 等待复位完成

    // 读取ID(验证通信)
    uint8_t SPL06_ID;
    HAL_I2C_Mem_Read(hi2c, SPL06_SENSOR_ADDR, ID_Addr, I2C_MEMADD_SIZE_8BIT, &SPL06_ID, 1, 100);

    // 读取校准系数
    SPL06_Read_Calib_SPL06_Coeffs(hi2c);

    // 配置压力测量(128倍过采样,4Hz)
    uint8_t prs_cfg = 0x27;  // PM_RATE=4Hz, PM_PRC=128x
    HAL_I2C_Mem_Write(hi2c, SPL06_SENSOR_ADDR, PRS_CFG_Addr, I2C_MEMADD_SIZE_8BIT, &prs_cfg, 1, 100);

    // 配置温度测量(外部传感器,单次采样,4Hz)
    uint8_t tmp_cfg = 0xA0;  // TMP_RATE=4Hz, TMP_EXT=1
    HAL_I2C_Mem_Write(hi2c, SPL06_SENSOR_ADDR, TMP_CFG_Addr, I2C_MEMADD_SIZE_8BIT, &tmp_cfg, 1, 100);

    // 启用数据移位(P_SHIFT)
    uint8_t cfg_reg = 0x04;  // P_SHIFT=1
    HAL_I2C_Mem_Write(hi2c, SPL06_SENSOR_ADDR, CFG_REG_Addr, I2C_MEMADD_SIZE_8BIT, &cfg_reg, 1, 100);

    // 配置工作模式(连续测量)
    uint8_t meas_cfg = 0x07;  // Background Mode
    HAL_I2C_Mem_Write(hi2c, SPL06_SENSOR_ADDR, MEAS_CFG_Addr, I2C_MEMADD_SIZE_8BIT, &meas_cfg, 1, 100);

    //首次读数丢弃
    SPL06_Read_Pressure_Raw_Data(hi2c);
    SPL06_Read_Temperature_Raw_Data(hi2c);

    return SPL06_ID;  // 返回ID(通常应为0x10)
}
/*读取校准系数*/
typedef struct {
    int16_t c0, c1;
    int32_t c00, c10, c01, c11, c20, c21, c30;
} SPL06CalibCoeffs;
SPL06CalibCoeffs SPL06_coeffs;

// 读取校准系数
void SPL06_Read_Calib_SPL06_Coeffs(I2C_HandleTypeDef *hi2c)
{
    uint8_t buf[18];
    HAL_I2C_Mem_Read(hi2c,SPL06_SENSOR_ADDR,0x10, I2C_MEMADD_SIZE_8BIT,buf, 18,1000); // 读取所有校准系数
    uint8_t meas_cfg;
    do {
        HAL_I2C_Mem_Read(hi2c, SPL06_SENSOR_ADDR, 0x08, I2C_MEMADD_SIZE_8BIT, &meas_cfg, 1, 100);
        HAL_Delay(10);
    } while((meas_cfg & 0xC0) != 0xC0); // 等待双RDY置位
    // 解析温度系数(12位有符号)
    SPL06_coeffs.c0 = (int16_t)((buf[0] << 4) | ((buf[1] & 0xF0) >> 4));
    if(SPL06_coeffs.c0 > 0x7FF) SPL06_coeffs.c0 -= 0x1000;

    SPL06_coeffs.c1 = (int16_t)(((buf[1] & 0x0F) << 8) | buf[2]);
    if(SPL06_coeffs.c1 > 0x7FF) SPL06_coeffs.c1 -= 0x1000;

    // 解析压力系数(16/20位有符号)
    SPL06_coeffs.c00 = (int32_t)((buf[3] << 12) | (buf[4] << 4) | ((buf[5] & 0xF0) >> 4));
    if(SPL06_coeffs.c00 > 0x7FFFF) SPL06_coeffs.c00 -= 0x100000;

    SPL06_coeffs.c10 = (int32_t)(((buf[5] & 0x0F) << 16) | (buf[6] << 8) | buf[7]);
    if(SPL06_coeffs.c10 > 0x7FFFF) SPL06_coeffs.c10 -= 0x100000;

    SPL06_coeffs.c01 = (int16_t)((buf[8] << 8) | buf[9]);
    SPL06_coeffs.c11 = (int16_t)((buf[10] << 8) | buf[11]);
    SPL06_coeffs.c20 = (int16_t)((buf[12] << 8) | buf[13]);
    SPL06_coeffs.c21 = (int16_t)((buf[14] << 8) | buf[15]);
    SPL06_coeffs.c30 = (int16_t)((buf[16] << 8) | buf[17]);
}

// 读取压强原始数据(24位有符号)
int32_t SPL06_Read_Pressure_Raw_Data(I2C_HandleTypeDef *hi2c)
{
    uint8_t buf[3];
    int32_t pressure_raw_data;
    HAL_I2C_Mem_Read(hi2c,SPL06_SENSOR_ADDR,0x00,I2C_MEMADD_SIZE_8BIT, buf, 3,100);
    pressure_raw_data=(int32_t)((buf[0] << 16) | (buf[1] << 8) | buf[2]);
    return (pressure_raw_data & 0x800000) ? (pressure_raw_data - 0x1000000) : pressure_raw_data;
}

// 读取温度原始数据(24位有符号)
int32_t SPL06_Read_Temperature_Raw_Data(I2C_HandleTypeDef *hi2c)
{
    uint8_t buf[3];
    int32_t temperature_raw_data;
    HAL_I2C_Mem_Read(hi2c,SPL06_SENSOR_ADDR,0x03,I2C_MEMADD_SIZE_8BIT, buf, 3,100);
    temperature_raw_data=(int32_t)((buf[0] << 16) | (buf[1] << 8) | buf[2]);
    return temperature_raw_data;
}

// 温度补偿计算(文档5.6.2节)
float SPL06_Compensate_Temperature(int32_t raw_temp)
{
    float kT=524288.0f; // 2倍过采样的kT值
    float traw_sc = (float)raw_temp / kT;
    float temperature_data;
    temperature_data=(float)SPL06_coeffs.c0 * 0.5f + (float)SPL06_coeffs.c1 * traw_sc;
    return temperature_data;
}

// 压力补偿计算(文档5.6.1节)
float SPL06_Compensate_Pressure(int32_t raw_press, int32_t raw_temp)
{
    float kT=524288.0f; // 单次采样的kT值
    float kP=2088960.0f; // 128倍过采样的kP值
    float pressure_data;
    float traw_sc = (float)raw_temp / kT;
    float praw_sc = (float)raw_press / kP;
    pressure_data=(float)SPL06_coeffs.c00
                  + praw_sc * ((float)SPL06_coeffs.c10 + praw_sc * ((float)SPL06_coeffs.c20 + praw_sc * (float)SPL06_coeffs.c30))
                  + traw_sc * (float)SPL06_coeffs.c01
                  + traw_sc * praw_sc * ((float)SPL06_coeffs.c11 + praw_sc * (float)SPL06_coeffs.c21);
    return pressure_data;
}

SPL06-001.h

//
// Created by Lenovo on 2025/7/3.
//

#ifndef TRAIN_STAGE2_SPL06_001_H
#define TRAIN_STAGE2_SPL06_001_H

#include "main.h"
#include "stm32g4xx_hal_i2c.h"

uint8_t SPL06_Init(I2C_HandleTypeDef *hi2c);
void SPL06_Read_Calib_SPL06_Coeffs(I2C_HandleTypeDef *hi2c);
int32_t SPL06_Read_Pressure_Raw_Data(I2C_HandleTypeDef *hi2c);
int32_t SPL06_Read_Temperature_Raw_Data(I2C_HandleTypeDef *hi2c);
float SPL06_Compensate_Temperature(int32_t raw_temp);
float SPL06_Compensate_Pressure(int32_t raw_press, int32_t raw_temp);

#endif //TRAIN_STAGE2_SPL06_001_H

main.c

引用 "SPL06-001.h"库,并初始化

int32_t raw_press= SPL06_Read_Pressure_Raw_Data(&hi2c1);
int32_t raw_temp= SPL06_Read_Temperature_Raw_Data(&hi2c1);
float temperature = SPL06_Compensate_Temperature(raw_temp);
float pressure= SPL06_Compensate_Pressure(raw_press,raw_temp);
pressure/=100.0f; //单位转换为hp

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐