STM32 模拟SPI读写HP303S气压传感器

HP303S气压传感器读取温度压力的步骤
在这里插入图片描述
SPI读写HP303S气压传感器有三线和四线两种接线方式,支持SPI模式4,SPI读取是通过设置CSB低并发送单个控制字节来启动的。控制字节由SPI寄存器地址和读取命令(bit7= RW = ‘1’)组成。写入控制字节后,数据输出SDO引脚(三线模式SDI);寄存器地址自动递增。发送CSB高端结束SPI读取事务。SPI读取协议如下图所示
在这里插入图片描述
hp303s.h

#ifndef __HP303S_H__
#define __HP303S_H__

#include "main.h"
#include "soft_spi.h"//模拟SPI程序

#define HP303S_KP 253952.0
#define HP303S_TP 1

#define Write 1
#define Read 0

#define HP303_CS(x)		HAL_GPIO_WritePin(SPI6_NSS_GPIO_Port,SPI6_NSS_Pin,(GPIO_PinState)x)

typedef struct
{
	//压力数据
	uint8_t PRS_B[3];

	//温度数据
	uint8_t TMP_B[3];		
}HP303S_T_and_P;

typedef struct
{
	int32_t C0;
	int32_t C1;
	long C00;
	long C01;
	int32_t C10;
	int32_t C11;
	int32_t C20;
	int32_t C21;
	int32_t C30;
	
	int32_t Praw;
	double Praw_sc;
	int32_t Traw;
	double Traw_sc;
	
	double Pcomp;
	double Tcomp;	
}COEF_DATA;

void hp303_init(void);
void hp303_read(void);

#endif
/****END OF FILE****/

hp303s.c

#include "hp303s.h"

uint8_t reg_0x10_0x21[18];

uint8_t PRS_CFG = 0x74;//压力分辨率配置  128/s 16times oversampling   寄存器0x06
uint8_t TMP_CFG = 0XF4;//温度分辨率配置  外部传感器 128/s 16times oversampling 寄存器0x07
uint8_t CFG_REG = 0X0C;//FIFO配置  寄存器0x09


HP303S_T_and_P hp303sData;
COEF_DATA coefData;

/*******************************************************************************
函数名称 : hp303_reg_read
功    能 : HP303S寄存器数据读取
参    数 : reg_add--寄存器地址,reg_num--寄存器数量,reg_data--存储数组
返 回 值 : 无
*******************************************************************************/
void hp303_reg_read(uint8_t reg_add,uint8_t reg_num,uint8_t *reg_data)
{
	HP303_CS(0);
	delay_us(10);
	write_spi_byte(reg_add | 0x80);//SPI写一个字节
	for(int i = 0;i < reg_num;i++)
	{
		reg_data[i] = read_spi_byte();//SPI读一个字节
	}
	HP303_CS(1);
	delay_us(10);
}

/*******************************************************************************
函数名称 : hp303_reg_write
功    能 : HP303S寄存器数据写入
参    数 : reg_add--寄存器地址,reg_data--写入数据
返 回 值 : 无
*******************************************************************************/
void hp303_reg_write(uint8_t reg_add,uint8_t reg_data)
{
	HP303_CS(0);
	delay_us(10);
	write_spi_byte(reg_add);//SPI写一个字节
	write_spi_byte(reg_data);//SPI读一个字节
	HP303_CS(1);
	delay_us(10);
}

/*******************************************************************************
函数名称 : coef_calc
功    能 : HP303S出厂校准值获取
参    数 : 无
返 回 值 : 无
*******************************************************************************/
void coef_calc(void)
{
	
	coefData.C0 = ( reg_0x10_0x21[0] << 4) | ((reg_0x10_0x21[1] & 0XF0) >> 4);
	if(coefData.C0 > (2048 - 1))
	{
		coefData.C0 = coefData.C0 - 4096;
	}
	
	coefData.C1 = ((reg_0x10_0x21[1] & 0X0F) << 8 | (reg_0x10_0x21[2]));
	if(coefData.C1 > 2047)
	{
		coefData.C1 = coefData.C1-4096;
	}
	
	coefData.C00 = (reg_0x10_0x21[3] << 12)|(reg_0x10_0x21[4] << 4)|((reg_0x10_0x21[5] & 0xF0) >> 4);
	if(coefData.C00 > 524287)
	{
		coefData.C00 = coefData.C00 - 1048576;
	}
	
	coefData.C10 = ((reg_0x10_0x21[5] & 0x0F) << 16) |   (reg_0x10_0x21[6] << 8) | reg_0x10_0x21[7];
	if(coefData.C10 > 524287)
	{
		coefData.C10 = coefData.C10 - 1048576;
	}
	
	coefData.C01= (reg_0x10_0x21[8] << 8) | (reg_0x10_0x21[9]);
	if(coefData.C01 > 32767)
	{
		coefData.C01 = coefData.C01 - 65536;
	}
	
	coefData.C11 = (reg_0x10_0x21[10] << 8) |(reg_0x10_0x21[11]);
	if(coefData.C11 > 32767)
	{
			coefData.C11 = coefData.C11 - 65536;
	}
	
	coefData.C20 = reg_0x10_0x21[11] | (reg_0x10_0x21[12] << 8);
	if(coefData.C20 > (32768-1))
	{
		coefData.C20 = coefData.C20 - 65536;
	}
	
	coefData.C21 = (reg_0x10_0x21[14] << 8) | (reg_0x10_0x21[15]);
	if(coefData.C21 > 32767)
	{
		coefData.C21 = coefData.C21 - 65536;
	}
	
	coefData.C30 = (reg_0x10_0x21[16] << 8 ) | (reg_0x10_0x21[17]);
	if(coefData.C30 > 32767)
	{
		coefData.C30  = coefData.C30  - 65536;
	}
}

/*******************************************************************************
函数名称 : hp303_init
功    能 : HP303S初始化
参    数 : 无
返 回 值 : 无
*******************************************************************************/
void hp303_init(void)
{	
	HP303_CS(1);
	delay_us(10);
	
	hp303_reg_read(0x10,18,reg_0x10_0x21);//Get coefficient
	delay_ms(4000);
	
	hp303_reg_write(0x06,PRS_CFG);//Pressure Resolution Config 0x06
	delay_ms(200);
	
	hp303_reg_write(0x07,TMP_CFG);//Temperature Resolution Config 0x07
	delay_ms(200);
	
	hp303_reg_write(0x09,CFG_REG);//Set P result shift 0x09
	delay_ms(200);
	
	coef_calc();
}

int step_cnt = 0;
/*******************************************************************************
函数名称 : hp303_read
功    能 : HP303S数据读取
参    数 : 无
返 回 值 : 无
*******************************************************************************/
void hp303_read(void)
{
	switch(step_cnt)
	{
		//计算温度
		case 0 :
		{
			hp303_reg_write(0x08,0x02);
			step_cnt = 1;
		}
		break;
		case 1:
		{
			hp303_reg_read(0x03,3,hp303sData.TMP_B);
			step_cnt = 2;
		}
		break;
		case 2:
		{
			coefData.Traw = (hp303sData.TMP_B[0] << 16) | (hp303sData.TMP_B[1] << 8) | (hp303sData.TMP_B[0] << 0);
			if(coefData.Traw > 8388607)
			{
				coefData.Traw = coefData.Traw -16777216;
			}
			coefData.Traw_sc = ((double)coefData.Traw / HP303S_KP);
			coefData.Tcomp = coefData.C0 * 0.5 + coefData.C1 * coefData.Traw_sc;
			step_cnt = 3;
		}
		break;
		//计算压力
		case 3:
		{
			hp303_reg_write(0x08,0x01);
			step_cnt = 4;
		}
		break;
		case 4:
		{
			hp303_reg_read(0x00,3,hp303sData.PRS_B);
			step_cnt = 5;
		}
		break;
		case 5:
		{
			coefData.Praw = (hp303sData.PRS_B[0] << 16) | (hp303sData.PRS_B[1] << 8) | (hp303sData.PRS_B[2] << 0);
			if( coefData.Praw > 8388607)
			{
				coefData.Praw = coefData.Praw - 16777216;
			}
			
			coefData.Praw_sc = ((double)coefData.Praw / HP303S_KP);
			coefData.Pcomp = coefData.C00 + (coefData.Praw_sc * (coefData.C10 + coefData.Praw_sc * (coefData.C20 + (coefData.Praw_sc * coefData.C30))))
				+ (coefData.Traw_sc * coefData.C01) + (coefData.Traw_sc * coefData.Praw_sc * (coefData.C11 + (coefData.Praw_sc * coefData.C21)));
			step_cnt = 6;
		}
		break;
		case 6:
		{
			InputReg[8] = coefData.Pcomp / 100 + pressure_offsets[0];
			step_cnt = 0;
		}
		break;	
	}
}

main.c

int main(void)
{
	HAL_Init();
	SystemClock_Config();
	MX_GPIO_Init();
	MX_TIM6_Init();
	HAL_TIM_Base_Start_IT(&htim6);					//主要定时
	hp303_init();									//HP303S初始化
	while (1)
	{
		if(it_100ms_flag == 1)//压力转换需要时间,故分步执行,减少延时对系统的影响
		{
			hp303_read();		//环境气压获取
			it_100ms_flag = 0;
		}
	}
}
  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值