STM32 SPI 气压传感器WF5803F_14BAR驱动
·

温度转换等待时间建议大于2ms,压力转换时间建议大于3ms。
#include "wf5803.h"
/*
** 返回值 : temp--SPI读取的一字节数据
** 描 述 : 下降沿读数据,每次读取 1 bit
*/
uint8_t SPI_Read_OneByte(void)
{
uint8_t i;
uint8_t temp = 0;
for (i = 0; i < 8; i++)
{
//读取MISO 8次输入的值,存入temp。之所以不放在“SCK = 0”语句之后的位置是因为:
//读取最后1byte的最后一位(即LSB)之后,不能再左移了
temp <<= 1;
WF5803_SCK(1);
delay_tick(4);
if(WF5803_MISO) //读取最高位,保存至最末尾,通过左移位完成读整个字节
temp |= 0x01;
else
temp &= ~0x01;
delay_tick(4);
WF5803_SCK(0);
delay_tick(4);
}
return temp;
}
/*
** 参 数 : u8_writedata--SPI写入的一字节数据
** 描 述 : 上升沿写数据,每次写入 1 bit
*/
void SPI_Write_OneByte(uint8_t u8_writedata)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
delay_tick(4);
if (u8_writedata & 0x80) //判断最高位,总是发送最高位
{
WF5803_MOSI(1); //MOSI输出1,数据总线准备数据1
}
else
{
WF5803_MOSI(0);//MOSI输出0,数据总线准备数据0
}
WF5803_SCK(1); //上升沿来了(SCK从0-->1),数据总线上的数据写入到器件
delay_tick(4);
u8_writedata <<= 1; //左移抛弃已经输出的最高位
WF5803_SCK(0); //拉低SCK信号,初始化为0
delay_tick(4);
}
}
/*
** 返回值 : u8_readdata--SPI读取的一字节数据
** 参 数 : u8_writedata--SPI写入的一字节数据
** 描 述 : 上升沿写,下降沿读
*/
uint8_t SPI_WriteAndRead_OneByte(uint8_t u8_writedata)
{
uint8_t i;
uint8_t u8_readdata = 0x00;
for (i = 0; i < 8; i++)
{
u8_readdata <<= 1;//读取MISO 8次输入的值,存入u8_readdata
if (u8_writedata & 0x80)//判断最高位,总是写最高位(输出最高位)
WF5803_MOSI(1);//MOSI输出1,数据总线准备数据1
else
WF5803_MOSI(0);//MOSI输出0,数据总线准备数据0
u8_writedata <<= 1;//左移抛弃已经输出的最高位
WF5803_SCK(1);//上升沿来了(SCK从0-->1),数据总线上的数据写入器件
if(WF5803_MISO)//读取最高位,保存至最末尾,通过左移位完成读整个字节
u8_readdata |= 0x01;
else
u8_readdata &= ~0x01;
WF5803_SCK(0);//下降沿来了(SCK从1-->0),MISO上将产生新的数据,读取存入u8——readdata
}
return u8_readdata;
}
/*
** 参 数 : (1)uint8_t addr--寄存器地址
** (2)uint8_t value--写入值
** 说 明 : wf5803寄存器写函数
*/
void wf5803_WriteReg(uint8_t addr, uint8_t value)
{
ClrCS();//CS片选拉低
SPI_Write_OneByte(0x00);//SPI写地址命令
SPI_Write_OneByte(addr);
SPI_Write_OneByte(value);//SPI写数据
SetCS();//CS片选拉高
}
/*
** 返回值: value--读取寄存器值
** 参 数 : addr--寄存器地址
** 说 明 : wf5803寄存器读函数
*/
uint8_t wf5803_ReadReg(uint8_t addr)
{
uint8_t value;
ClrCS();//CS片选拉低
SPI_Write_OneByte(0x80);//SPI写地址命令
SPI_Write_OneByte(addr);
value = SPI_Read_OneByte();//SPI读数据
SetCS();//CS片选拉高
return value;
}
uint8_t RawData[5];
uint8_t* GetSensorData()
{
//重置清0
memset(RawData, 0, sizeof(uint8_t) * 5);
//采集温度数据
wf5803_WriteReg(0x30, 0x08);
delay_ms(2);
RawData[3] = wf5803_ReadReg(0x09);
RawData[4] = wf5803_ReadReg(0x0A);
//采集气压数据
wf5803_WriteReg(0x30, 0x09);
delay_ms(3);
RawData[0] = wf5803_ReadReg(0x06);
RawData[1] = wf5803_ReadReg(0x07);
RawData[2] = wf5803_ReadReg(0x08);
return RawData;
}
void wf5803_ReadRegMulti(uint8_t addr, uint8_t lens, uint8_t* value)
{
ClrCS();//CS片选拉低
if (lens == 1)
{
SPI_Write_OneByte(0x80);//SPI写地址命令
}
else if (lens == 2)
{
SPI_Write_OneByte(0xA0);//SPI写地址命令
}
else if (lens == 3)
{
SPI_Write_OneByte(0xC0);//SPI写地址命令
}
else
{
SPI_Write_OneByte(0xE0);//SPI写地址命令
}
SPI_Write_OneByte(addr);
for (uint8_t i = 0; i < lens; i++)
{
value[i] = SPI_Read_OneByte();//SPI读数据
}
SetCS();//CS片选拉高
}
void wf5803_setup()
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = MISO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SPI_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SCLK_PIN|MOSI_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(SPI_PORT, &GPIO_InitStruct);
SetCS();//CS片选拉高
delay_ms(1);
//0x00:SDO_active: 1: 4-wire SPI, 0: 3-wire SPI
wf5803_WriteReg(0x00, 0x81);
}
long press_reading = 0,temp_reading = 0;;
float press = 0;//kPa
float temp = 0;//℃
float fDat;
void wf5803_loop()
{
uint8_t* p1 = GetSensorData();
press_reading = p1[0];
press_reading = press_reading << 8;
press_reading |= p1[1];
press_reading = press_reading << 8;
press_reading |= p1[2];
if(press_reading >= 8388608)
{
fDat = (int32_t)(press_reading - 16777216) / 8388608.0f;
}
else
{
fDat = press_reading / 8388608.0f;
}
press = (10000 * fDat + 9000) / 12.0f;
temp_reading = p1[3];
temp_reading = temp_reading << 8;
temp_reading |= p1[4];
if (temp_reading > 32768)
{
temp = (temp_reading - 65844) / 256.0;
}
else
{
temp = (temp_reading - 308) / 256.0;
}
}
#ifndef __WF5803_H__
#define __WF5803_H__
#include "math.h"
#include "string.h"
#include "main.h"
#include "modbus.h"
#include "ms5803.h"
#include "gpio.h"
#define WF5803_SCK(x) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,(GPIO_PinState)x)
#define WF5803_MOSI(x) HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,(GPIO_PinState)x)
#define WF5803_MISO HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6)
void wf5803_WriteReg(uint8_t addr, uint8_t value);
uint8_t wf5803_ReadReg(uint8_t addr);
void wf5803_ReadRegMulti(uint8_t addr, uint8_t lens, uint8_t* value);
void wf5803_setup(void);
void wf5803_loop(void);
#endif
温度压力转换公式参考
/*=============================================================================
---函数:press_unit_factor(void)
---功能:传感器压力计量单位换算
---输入:
---输出:转换关系系数值
-----------------------------------------------------------------------------*/
wf_t press_unit_factor(void){
// switch(press_measurement_unit){
press_measurement_unit u = drv_state.pressUnit;
wf_t n = 1;
if(u== bar) n=0.01;
else if(u== kPa) n=1;
else if(u== hPa) n=10;
else if(u== mbar) n=10;
else if(u== Pa) n=1000;
else if(u== PSI) n=0.14503774;
else if(u== kgf_cm2) n=0.010197162;
else if(u== Torr) n=7.5006168;
return n;
}
/*=============================================================================
---函数:analyze_press_data(void)
---功能:传感器各型号的压力算法
---输入:
---输出:按初始化的压力单位输出压力值
-----------------------------------------------------------------------------*/
wf_t analyze_press_data(void){
// switch(sensor_model){
sensor_model m = drv_state.model;
wf_t n = drv_state.factor;
wf_t u = press_unit_factor();
if(m == WF5803F_1BAR) return (125 * n + 17.5) * u;
else if(m == WF5803F_2BAR) return (180 / 0.81 * (n - 0.1) + 30) * u;
else if(m == WF5803F_7BAR) return (1000 * n - 50) * u;
else if(m == WF5803F_12BAR) return (700* n + 530) * u;
else if(m == WF100D_5KPA) return (5 * n + 0.25) * u;
else if(m == WF100D_10KPA) return (15 * n + 2) * u;
else if(m == WF100D_40KPA) return (50 * n + 5) * u;
else if(m == WF100D_100KPA) return (125 * n -12.5) * u;
else if(m == WF100D_200KPA) return (250 * n +25) * u;
else if(m == WF100D_300KPA) return (400 * n +10) * u;
else if(m == WF200D_5KPA) return (5 * n + 0.25) * u;
return 0;
}
...
drv_state.rawData = drv_state.arrData[0];
drv_state.rawData = drv_state.rawData << 8;
drv_state.rawData |= drv_state.arrData[1];
drv_state.rawData = drv_state.rawData << 8;
drv_state.rawData |= drv_state.arrData[2];
if (drv_state.rawData > 8388608) {
drv_state.factor = (int32_t)(drv_state.rawData - 16777216) / 8388608.0;
} else {
drv_state.factor = drv_state.rawData / 8388608.0;
}
data->pressure = analyze_press_data();
drv_state.rawData = drv_state.arrData[3];
drv_state.rawData = drv_state.rawData << 8;
drv_state.rawData |= drv_state.arrData[4];
if (drv_state.rawData > 32768) {
data->temperature = (drv_state.rawData - 65536) / 256.0;
}
else {
data->temperature = drv_state.rawData / 256.0;
}
}
...
14bar型号公式与上述不同
drv_state.rawData = drv_state.arrData[0];
drv_state.rawData = drv_state.rawData << 8;
drv_state.rawData |= drv_state.arrData[1];
drv_state.rawData = drv_state.rawData << 8;
drv_state.rawData |= drv_state.arrData[2];
if (drv_state.rawData>= 8388608) {
drv_state.factor= (int32_t)(drv_state.rawData- 16777216) / 8388608.0f;
} else
{
drv_state.factor= drv_state.rawData/ 8388608.0f;
}
data->pressure= (10000 * fDat + 9000) / 12.0M;
drv_state.rawData = drv_state.arrData[3];
drv_state.rawData = drv_state.rawData << 8;
drv_state.rawData |= drv_state.arrData[4];
if (drv_state.rawData> 32768)
{
data->temperature= (drv_state.rawData- 65844) / 256.0f;
}
else
{
data->temperature= (drv_state.rawData-308) / 256.0f;
}
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)