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;
}
}
}