Microfelt.net | 微感论坛-传感器技术交流社区
返回列表 发布新帖
查看: 38|回复: 1

[技术交流] WF282A 气压传感器接口配置完整代码(STM32F103)

7

主题

3

回帖

29

积分

新手上路

发表于 7 天前 | 查看全部 |阅读模式
以下是基于 STM32F103 系列 MCU 的 WF282A 完整接口配置代码,包含 I2C/SPI 底层驱动、传感器初始化、数据读取、校准参数写入等全功能片段,代码可直接移植,适配 Keil MDK 开发环境。
一、通用头文件定义(wf282a.h)

  1. <font face="宋体">#ifndef __WF282A_H
  2. #define __WF282A_H

  3. #include "stm32f10x.h"
  4. #include "delay.h"

  5. /************************** 引脚定义 **************************/
  6. // I2C模式(默认使用I2C1)
  7. #define WF282A_I2C                  I2C1
  8. #define WF282A_I2C_CLK              RCC_APB1Periph_I2C1
  9. #define WF282A_I2C_SCL_PIN          GPIO_Pin_6
  10. #define WF282A_I2C_SCL_PORT         GPIOB
  11. #define WF282A_I2C_SCL_CLK          RCC_APB2Periph_GPIOB
  12. #define WF282A_I2C_SDA_PIN          GPIO_Pin_7
  13. #define WF282A_I2C_SDA_PORT         GPIOB
  14. #define WF282A_I2C_SDA_CLK          RCC_APB2Periph_GPIOB

  15. // SPI模式(默认使用SPI1)
  16. #define WF282A_SPI                  SPI1
  17. #define WF282A_SPI_CLK              RCC_APB2Periph_SPI1
  18. #define WF282A_SPI_SCK_PIN          GPIO_Pin_5
  19. #define WF282A_SPI_SCK_PORT         GPIOA
  20. #define WF282A_SPI_SCK_CLK          RCC_APB2Periph_GPIOA
  21. #define WF282A_SPI_MOSI_PIN         GPIO_Pin_7
  22. #define WF282A_SPI_MOSI_PORT        GPIOA
  23. #define WF282A_SPI_MOSI_CLK         RCC_APB2Periph_GPIOA
  24. #define WF282A_SPI_MISO_PIN         GPIO_Pin_6
  25. #define WF282A_SPI_MISO_PORT        GPIOA
  26. #define WF282A_SPI_MISO_CLK         RCC_APB2Periph_GPIOA
  27. #define WF282A_SPI_CS_PIN           GPIO_Pin_4
  28. #define WF282A_SPI_CS_PORT          GPIOA
  29. #define WF282A_SPI_CS_CLK           RCC_APB2Periph_GPIOA

  30. /************************** 设备参数 **************************/
  31. // I2C地址(CS接3.3V为0x77,接GND为0x76,左移1位适配STM32 I2C地址格式)
  32. #define WF282A_I2C_ADDR             (0x77 << 1)
  33. // SPI指令宏
  34. #define WF282A_SPI_READ_CMD         0x80  // 读操作位(最高位1)

  35. /************************** 寄存器地址 **************************/
  36. #define WF282A_REG_PRESS_MSB        0x00  // 气压数据高8位
  37. #define WF282A_REG_PRESS_MID        0x01  // 气压数据中8位
  38. #define WF282A_REG_PRESS_LSB        0x02  // 气压数据低8位
  39. #define WF282A_REG_TEMP_MSB         0x04  // 温度数据高8位
  40. #define WF282A_REG_TEMP_MID         0x05  // 温度数据中8位
  41. #define WF282A_REG_TEMP_LSB         0x06  // 温度数据低8位
  42. #define WF282A_REG_CTRL             0x10  // 控制寄存器
  43. #define WF282A_REG_CALIB_OFFSET     0x18  // 校准偏移寄存器
  44. #define WF282A_REG_TEMP_COMP        0x1C  // 温度补偿寄存器
  45. #define WF282A_REG_ID               0x20  // 设备ID寄存器

  46. /************************** 控制寄存器配置 **************************/
  47. #define WF282A_CTRL_NORMAL_MODE     0x01  // 正常工作模式
  48. #define WF282A_CTRL_LOW_POWER       0x02  // 低功耗模式
  49. #define WF282A_CTRL_FILTER_EN       0x04  // 启用数字滤波
  50. #define WF282A_CTRL_SAMPLE_1HZ      0x00  // 1Hz采样率
  51. #define WF282A_CTRL_SAMPLE_10HZ     0x10  // 10Hz采样率
  52. #define WF282A_CTRL_SAMPLE_100HZ    0x20  // 100Hz采样率

  53. /************************** 函数声明 **************************/
  54. // I2C接口函数
  55. void WF282A_I2C_Init(void);
  56. uint8_t WF282A_I2C_ReadByte(uint8_t reg_addr);
  57. void WF282A_I2C_WriteByte(uint8_t reg_addr, uint8_t data);
  58. void WF282A_I2C_ReadBytes(uint8_t reg_addr, uint8_t len, uint8_t *buf);
  59. void WF282A_I2C_WriteBytes(uint8_t reg_addr, uint8_t len, uint8_t *buf);

  60. // SPI接口函数
  61. void WF282A_SPI_Init(void);
  62. void WF282A_SPI_CS_Enable(void);
  63. void WF282A_SPI_CS_Disable(void);
  64. uint8_t WF282A_SPI_ReadWriteByte(uint8_t tx_data);
  65. uint8_t WF282A_SPI_ReadByte(uint8_t reg_addr);
  66. void WF282A_SPI_WriteByte(uint8_t reg_addr, uint8_t data);

  67. // 传感器核心函数
  68. uint8_t WF282A_Check_ID(void);          // 检测设备ID
  69. void WF282A_Init(uint8_t mode);         // 初始化传感器(mode:工作模式)
  70. float WF282A_Read_Pressure(void);       // 读取气压值(Pa)
  71. float WF282A_Read_Temperature(void);    // 读取温度值(℃)
  72. void WF282A_Write_Calib_Offset(int16_t offset); // 写入校准偏移量
  73. void WF282A_Write_Temp_Comp(uint8_t comp);      // 写入温度补偿系数

  74. #endif</font>
复制代码
二、I2C 接口驱动实现(wf282a_i2c.c)
  1. <font face="宋体">#include "wf282a.h"

  2. /************************** I2C底层初始化 **************************/
  3. void WF282A_I2C_Init(void)
  4. {
  5.     GPIO_InitTypeDef GPIO_InitStruct;
  6.     I2C_InitTypeDef I2C_InitStruct;

  7.     // 使能时钟
  8.     RCC_APB2PeriphClockCmd(WF282A_I2C_SCL_CLK | WF282A_I2C_SDA_CLK, ENABLE);
  9.     RCC_APB1PeriphClockCmd(WF282A_I2C_CLK, ENABLE);

  10.     // 配置SCL引脚(复用开漏输出)
  11.     GPIO_InitStruct.GPIO_Pin = WF282A_I2C_SCL_PIN;
  12.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;
  13.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  14.     GPIO_Init(WF282A_I2C_SCL_PORT, &GPIO_InitStruct);

  15.     // 配置SDA引脚(复用开漏输出)
  16.     GPIO_InitStruct.GPIO_Pin = WF282A_I2C_SDA_PIN;
  17.     GPIO_Init(WF282A_I2C_SDA_PORT, &GPIO_InitStruct);

  18.     // 配置I2C参数
  19.     I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
  20.     I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
  21.     I2C_InitStruct.I2C_OwnAddress1 = 0x00;  // 主机无地址
  22.     I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
  23.     I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  24.     I2C_InitStruct.I2C_ClockSpeed = 400000; // 400KHz高速模式
  25.     I2C_Init(WF282A_I2C, &I2C_InitStruct);

  26.     // 使能I2C
  27.     I2C_Cmd(WF282A_I2C, ENABLE);
  28. }

  29. /************************** I2C单字节读取 **************************/
  30. uint8_t WF282A_I2C_ReadByte(uint8_t reg_addr)
  31. {
  32.     uint8_t data = 0;

  33.     // 等待I2C总线空闲
  34.     while(I2C_GetFlagStatus(WF282A_I2C, I2C_FLAG_BUSY));

  35.     // 发送起始信号
  36.     I2C_GenerateSTART(WF282A_I2C, ENABLE);
  37.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_MODE_SELECT));

  38.     // 发送设备地址+写操作
  39.     I2C_Send7bitAddress(WF282A_I2C, WF282A_I2C_ADDR, I2C_Direction_Transmitter);
  40.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

  41.     // 发送寄存器地址
  42.     I2C_SendData(WF282A_I2C, reg_addr);
  43.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  44.     // 发送重复起始信号
  45.     I2C_GenerateSTART(WF282A_I2C, ENABLE);
  46.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_MODE_SELECT));

  47.     // 发送设备地址+读操作
  48.     I2C_Send7bitAddress(WF282A_I2C, WF282A_I2C_ADDR, I2C_Direction_Receiver);
  49.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

  50.     // 关闭应答,准备接收
  51.     I2C_AcknowledgeConfig(WF282A_I2C, DISABLE);
  52.     I2C_GenerateSTOP(WF282A_I2C, ENABLE); // 发送停止信号

  53.     // 读取数据
  54.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED));
  55.     data = I2C_ReceiveData(WF282A_I2C);

  56.     // 重新使能应答
  57.     I2C_AcknowledgeConfig(WF282A_I2C, ENABLE);

  58.     return data;
  59. }

  60. /************************** I2C单字节写入 **************************/
  61. void WF282A_I2C_WriteByte(uint8_t reg_addr, uint8_t data)
  62. {
  63.     // 等待I2C总线空闲
  64.     while(I2C_GetFlagStatus(WF282A_I2C, I2C_FLAG_BUSY));

  65.     // 发送起始信号
  66.     I2C_GenerateSTART(WF282A_I2C, ENABLE);
  67.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_MODE_SELECT));

  68.     // 发送设备地址+写操作
  69.     I2C_Send7bitAddress(WF282A_I2C, WF282A_I2C_ADDR, I2C_Direction_Transmitter);
  70.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

  71.     // 发送寄存器地址
  72.     I2C_SendData(WF282A_I2C, reg_addr);
  73.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  74.     // 发送写入数据
  75.     I2C_SendData(WF282A_I2C, data);
  76.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  77.     // 发送停止信号
  78.     I2C_GenerateSTOP(WF282A_I2C, ENABLE);
  79. }

  80. /************************** I2C多字节读取 **************************/
  81. void WF282A_I2C_ReadBytes(uint8_t reg_addr, uint8_t len, uint8_t *buf)
  82. {
  83.     uint8_t i = 0;

  84.     if(len == 0 || buf == NULL) return;

  85.     // 等待I2C总线空闲
  86.     while(I2C_GetFlagStatus(WF282A_I2C, I2C_FLAG_BUSY));

  87.     // 发送起始信号
  88.     I2C_GenerateSTART(WF282A_I2C, ENABLE);
  89.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_MODE_SELECT));

  90.     // 发送设备地址+写操作
  91.     I2C_Send7bitAddress(WF282A_I2C, WF282A_I2C_ADDR, I2C_Direction_Transmitter);
  92.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

  93.     // 发送寄存器地址
  94.     I2C_SendData(WF282A_I2C, reg_addr);
  95.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  96.     // 发送重复起始信号
  97.     I2C_GenerateSTART(WF282A_I2C, ENABLE);
  98.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_MODE_SELECT));

  99.     // 发送设备地址+读操作
  100.     I2C_Send7bitAddress(WF282A_I2C, WF282A_I2C_ADDR, I2C_Direction_Receiver);
  101.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

  102.     // 读取多字节数据
  103.     for(i=0; i<len; i++)
  104.     {
  105.         if(i == len-1)
  106.         {
  107.             // 最后一个字节,关闭应答并发送停止信号
  108.             I2C_AcknowledgeConfig(WF282A_I2C, DISABLE);
  109.             I2C_GenerateSTOP(WF282A_I2C, ENABLE);
  110.         }

  111.         while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED));
  112.         buf[i] = I2C_ReceiveData(WF282A_I2C);
  113.     }

  114.     // 重新使能应答
  115.     I2C_AcknowledgeConfig(WF282A_I2C, ENABLE);
  116. }

  117. /************************** I2C多字节写入 **************************/
  118. void WF282A_I2C_WriteBytes(uint8_t reg_addr, uint8_t len, uint8_t *buf)
  119. {
  120.     uint8_t i = 0;

  121.     if(len == 0 || buf == NULL) return;

  122.     // 等待I2C总线空闲
  123.     while(I2C_GetFlagStatus(WF282A_I2C, I2C_FLAG_BUSY));

  124.     // 发送起始信号
  125.     I2C_GenerateSTART(WF282A_I2C, ENABLE);
  126.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_MODE_SELECT));

  127.     // 发送设备地址+写操作
  128.     I2C_Send7bitAddress(WF282A_I2C, WF282A_I2C_ADDR, I2C_Direction_Transmitter);
  129.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

  130.     // 发送寄存器地址
  131.     I2C_SendData(WF282A_I2C, reg_addr);
  132.     while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

  133.     // 发送多字节数据
  134.     for(i=0; i<len; i++)
  135.     {
  136.         I2C_SendData(WF282A_I2C, buf[i]);
  137.         while(!I2C_CheckEvent(WF282A_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  138.     }

  139.     // 发送停止信号
  140.     I2C_GenerateSTOP(WF282A_I2C, ENABLE);
  141. }</font>
复制代码

三、SPI 接口驱动实现(wf282a_spi.c)
  1. <font face="宋体">#include "wf282a.h"

  2. /************************** SPI底层初始化 **************************/
  3. void WF282A_SPI_Init(void)
  4. {
  5.     GPIO_InitTypeDef GPIO_InitStruct;
  6.     SPI_InitTypeDef SPI_InitStruct;

  7.     // 使能时钟
  8.     RCC_APB2PeriphClockCmd(WF282A_SPI_SCK_CLK | WF282A_SPI_MOSI_CLK |
  9.                            WF282A_SPI_MISO_CLK | WF282A_SPI_CS_CLK, ENABLE);
  10.     RCC_APB2PeriphClockCmd(WF282A_SPI_CLK, ENABLE);

  11.     // 配置SCK引脚(复用推挽输出)
  12.     GPIO_InitStruct.GPIO_Pin = WF282A_SPI_SCK_PIN;
  13.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
  14.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  15.     GPIO_Init(WF282A_SPI_SCK_PORT, &GPIO_InitStruct);

  16.     // 配置MOSI引脚(复用推挽输出)
  17.     GPIO_InitStruct.GPIO_Pin = WF282A_SPI_MOSI_PIN;
  18.     GPIO_Init(WF282A_SPI_MOSI_PORT, &GPIO_InitStruct);

  19.     // 配置MISO引脚(浮空输入)
  20.     GPIO_InitStruct.GPIO_Pin = WF282A_SPI_MISO_PIN;
  21.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  22.     GPIO_Init(WF282A_SPI_MISO_PORT, &GPIO_InitStruct);

  23.     // 配置CS引脚(推挽输出)
  24.     GPIO_InitStruct.GPIO_Pin = WF282A_SPI_CS_PIN;
  25.     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  26.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  27.     GPIO_Init(WF282A_SPI_CS_PORT, &GPIO_InitStruct);

  28.     // 初始拉高CS引脚
  29.     WF282A_SPI_CS_Disable();

  30.     // 配置SPI参数
  31.     SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  32.     SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
  33.     SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
  34.     SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        // 时钟极性:低电平空闲
  35.     SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // 第一个边沿采样
  36.     SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;         // 软件控制NSS
  37.     SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // 1MHz(72/16=4.5MHz,可调整)
  38.     SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; // 高位先行
  39.     SPI_InitStruct.SPI_CRCPolynomial = 7;
  40.     SPI_Init(WF282A_SPI, &SPI_InitStruct);

  41.     // 使能SPI
  42.     SPI_Cmd(WF282A_SPI, ENABLE);
  43. }

  44. /************************** SPI片选控制 **************************/
  45. void WF282A_SPI_CS_Enable(void)
  46. {
  47.     GPIO_ResetBits(WF282A_SPI_CS_PORT, WF282A_SPI_CS_PIN);
  48.     delay_us(1); // 延时确保片选稳定
  49. }

  50. void WF282A_SPI_CS_Disable(void)
  51. {
  52.     delay_us(1);
  53.     GPIO_SetBits(WF282A_SPI_CS_PORT, WF282A_SPI_CS_PIN);
  54. }

  55. /************************** SPI单字节读写 **************************/
  56. uint8_t WF282A_SPI_ReadWriteByte(uint8_t tx_data)
  57. {
  58.     // 等待发送缓冲区为空
  59.     while(SPI_I2S_GetFlagStatus(WF282A_SPI, SPI_I2S_FLAG_TXE) == RESET);
  60.     // 发送数据
  61.     SPI_I2S_SendData(WF282A_SPI, tx_data);
  62.     // 等待接收缓冲区非空
  63.     while(SPI_I2S_GetFlagStatus(WF282A_SPI, SPI_I2S_FLAG_RXNE) == RESET);
  64.     // 返回接收数据
  65.     return SPI_I2S_ReceiveData(WF282A_SPI);
  66. }

  67. /************************** SPI单字节读取 **************************/
  68. uint8_t WF282A_SPI_ReadByte(uint8_t reg_addr)
  69. {
  70.     uint8_t data = 0;

  71.     WF282A_SPI_CS_Enable(); // 拉低CS
  72.     // 发送寄存器地址+读操作位
  73.     WF282A_SPI_ReadWriteByte(reg_addr | WF282A_SPI_READ_CMD);
  74.     // 读取数据
  75.     data = WF282A_SPI_ReadWriteByte(0xFF);
  76.     WF282A_SPI_CS_Disable(); // 拉高CS

  77.     return data;
  78. }

  79. /************************** SPI单字节写入 **************************/
  80. void WF282A_SPI_WriteByte(uint8_t reg_addr, uint8_t data)
  81. {
  82.     WF282A_SPI_CS_Enable(); // 拉低CS
  83.     // 发送寄存器地址(写操作位为0)
  84.     WF282A_SPI_ReadWriteByte(reg_addr & ~WF282A_SPI_READ_CMD);
  85.     // 写入数据
  86.     WF282A_SPI_ReadWriteByte(data);
  87.     WF282A_SPI_CS_Disable(); // 拉高CS
  88. }</font>
复制代码

7

主题

3

回帖

29

积分

新手上路

 楼主| 发表于 7 天前 | 查看全部
四、传感器核心功能实现(wf282a_core.c)
  1. <font face="宋体">#include "wf282a.h"

  2. /************************** 设备ID检测 **************************/
  3. uint8_t WF282A_Check_ID(void)
  4. {
  5.     uint8_t dev_id = 0;
  6.     // I2C模式检测
  7.     dev_id = WF282A_I2C_ReadByte(WF282A_REG_ID);
  8.     if(dev_id == 0x28) // WF282A默认ID为0x28
  9.     {
  10.         return 1;
  11.     }
  12.     // SPI模式检测(备用)
  13.     dev_id = WF282A_SPI_ReadByte(WF282A_REG_ID);
  14.     if(dev_id == 0x28)
  15.     {
  16.         return 1;
  17.     }
  18.     return 0;
  19. }

  20. /************************** 传感器初始化 **************************/
  21. void WF282A_Init(uint8_t mode)
  22. {
  23.     uint8_t ctrl_reg = 0;

  24.     // 初始化接口(按需选择I2C/SPI)
  25.     // WF282A_I2C_Init(); // I2C模式
  26.     WF282A_SPI_Init();   // SPI模式

  27.     // 检测设备ID
  28.     while(!WF282A_Check_ID())
  29.     {
  30.         // ID检测失败,可添加错误处理逻辑
  31.         delay_ms(100);
  32.     }

  33.     // 配置控制寄存器
  34.     ctrl_reg |= WF282A_CTRL_FILTER_EN; // 启用滤波
  35.     ctrl_reg |= WF282A_CTRL_SAMPLE_10HZ; // 10Hz采样率
  36.     switch(mode)
  37.     {
  38.         case 0: ctrl_reg |= WF282A_CTRL_NORMAL_MODE; break;
  39.         case 1: ctrl_reg |= WF282A_CTRL_LOW_POWER; break;
  40.         default: ctrl_reg |= WF282A_CTRL_NORMAL_MODE; break;
  41.     }

  42.     // 写入控制寄存器(按需选择I2C/SPI)
  43.     // WF282A_I2C_WriteByte(WF282A_REG_CTRL, ctrl_reg);
  44.     WF282A_SPI_WriteByte(WF282A_REG_CTRL, ctrl_reg);

  45.     delay_ms(10); // 等待配置生效
  46. }

  47. /************************** 读取气压值 **************************/
  48. float WF282A_Read_Pressure(void)
  49. {
  50.     uint8_t press_buf[3];
  51.     uint32_t press_raw = 0;
  52.     float pressure = 0.0f;

  53.     // 读取3字节气压数据(按需选择I2C/SPI)
  54.     // WF282A_I2C_ReadBytes(WF282A_REG_PRESS_MSB, 3, press_buf);
  55.     WF282A_SPI_CS_Enable();
  56.     WF282A_SPI_ReadWriteByte(WF282A_REG_PRESS_MSB | WF282A_SPI_READ_CMD);
  57.     press_buf[0] = WF282A_SPI_ReadWriteByte(0xFF); // 高8位
  58.     press_buf[1] = WF282A_SPI_ReadWriteByte(0xFF); // 中8位
  59.     press_buf[2] = WF282A_SPI_ReadWriteByte(0xFF); // 低8位
  60.     WF282A_SPI_CS_Disable();

  61.     // 拼接原始数据
  62.     press_raw = ((uint32_t)press_buf[0] << 16) | ((uint32_t)press_buf[1] << 8) | press_buf[2];
  63.     // 转换为实际气压值(Pa),公式适配WF282A量程
  64.     pressure = (float)press_raw / 100.0f - 10000.0f;

  65.     return pressure;
  66. }

  67. /************************** 读取温度值 **************************/
  68. float WF282A_Read_Temperature(void)
  69. {
  70.     uint8_t temp_buf[3];
  71.     uint32_t temp_raw = 0;
  72.     float temperature = 0.0f;

  73.     // 读取3字节温度数据(按需选择I2C/SPI)
  74.     // WF282A_I2C_ReadBytes(WF282A_REG_TEMP_MSB, 3, temp_buf);
  75.     WF282A_SPI_CS_Enable();
  76.     WF282A_SPI_ReadWriteByte(WF282A_REG_TEMP_MSB | WF282A_SPI_READ_CMD);
  77.     temp_buf[0] = WF282A_SPI_ReadWriteByte(0xFF); // 高8位
  78.     temp_buf[1] = WF282A_SPI_ReadWriteByte(0xFF); // 中8位
  79.     temp_buf[2] = WF282A_SPI_ReadWriteByte(0xFF); // 低8位
  80.     WF282A_SPI_CS_Disable();

  81.     // 拼接原始数据
  82.     temp_raw = ((uint32_t)temp_buf[0] << 16) | ((uint32_t)temp_buf[1] << 8) | temp_buf[2];
  83.     // 转换为实际温度值(℃)
  84.     temperature = (float)temp_raw / 1000.0f - 40.0f;

  85.     return temperature;
  86. }

  87. /************************** 写入校准偏移量 **************************/
  88. void WF282A_Write_Calib_Offset(int16_t offset)
  89. {
  90.     uint8_t offset_buf[2];
  91.     // 拆分16位偏移量为2字节
  92.     offset_buf[0] = (offset >> 8) & 0xFF;
  93.     offset_buf[1] = offset & 0xFF;

  94.     // 写入校准偏移寄存器(按需选择I2C/SPI)
  95.     // WF282A_I2C_WriteBytes(WF282A_REG_CALIB_OFFSET, 2, offset_buf);
  96.     WF282A_SPI_CS_Enable();
  97.     WF282A_SPI_ReadWriteByte(WF282A_REG_CALIB_OFFSET & ~WF282A_SPI_READ_CMD);
  98.     WF282A_SPI_ReadWriteByte(offset_buf[0]);
  99.     WF282A_SPI_ReadWriteByte(offset_buf[1]);
  100.     WF282A_SPI_CS_Disable();

  101.     delay_ms(5); // 等待参数生效
  102. }

  103. /************************** 写入温度补偿系数 **************************/
  104. void WF282A_Write_Temp_Comp(uint8_t comp)
  105. {
  106.     // 写入温度补偿寄存器(按需选择I2C/SPI)
  107.     // WF282A_I2C_WriteByte(WF282A_REG_TEMP_COMP, comp);
  108.     WF282A_SPI_WriteByte(WF282A_REG_TEMP_COMP, comp);
  109.     delay_ms(5);
  110. }</font>
复制代码
五、代码使用说明

  • 底层依赖:代码依赖delay.h(延时函数)和 STM32 标准库,需确保项目中已实现delay_us()、delay_ms()函数;
  • 接口选择:默认启用 SPI 模式,如需切换 I2C 模式,注释 SPI 相关初始化,启用 I2C 初始化及数据读写函数;
  • 参数调整:SPI 时钟频率可通过SPI_BaudRatePrescaler调整,建议≤1MHz;I2C 速率固定为 400KHz,适配 WF282A 规格;
  • 校准使用:批量校准时,通过WF282A_Write_Calib_Offset()写入偏移量,WF282A_Write_Temp_Comp()写入温度补偿系数;
  • 测试示例
    1. <font face="宋体">int main(void)
    2. {
    3.     float pressure, temperature;
    4.     // 初始化传感器,低功耗模式
    5.     WF282A_Init(1);

    6.     while(1)
    7.     {
    8.         pressure = WF282A_Read_Pressure();
    9.         temperature = WF282A_Read_Temperature();
    10.         // 打印数据(需实现串口输出函数)
    11.         // printf("Pressure: %.2f Pa, Temperature: %.2f ℃\r\n", pressure, temperature);
    12.         delay_ms(1000);
    13.     }
    14. }</font>
    复制代码
    六、注意事项
    • 硬件接线时,I2C 上拉电阻需靠近 WF282A 引脚焊接,阻值推荐 4.7KΩ;
    • SPI 通信时,CS 引脚需严格遵循 “拉低 - 传输 - 拉高” 时序,避免数据错乱;
    • 校准参数写入后,需重启传感器或等待 5ms 以上确保参数生效;
    • 户外使用时,建议在代码中增加温度补偿逻辑,进一步提升气压测量精度。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Microfelt|微感论坛-传感器技术交流社区 © 2001-2025 Discuz! Team. Powered by Discuz! W1.5 粤ICP备18044996号-3|81f01e9418981fd496123c701618b320
在本版发帖
论坛管理
论坛管理 返回顶部
快速回复 返回顶部 返回列表