温度转换等待时间建议大于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;
  	}
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐