#include "main.h" #include "bsp/time.h" #include "math.h" #include "BarometerDriver/SPL06.h" #include "BarometerDriver/user_iic.h" SPL06 spl06; SPL06_Calib_Param spl06_calib_param; /*************************************************************************** * 函 数 名: spl06_write_reg * 功能说明: IIC写 * 形 参: 无 * 返 回 值: 无 **************************************************************************/ uint8_t spl06_write_reg(uint8_t reg_addr,uint8_t reg_val) { IIC_Start(); IIC_Send_Byte((SP06_Advice_Address<<1)|0);//发送器件地址+写命令 if(IIC_Wait_Ack()) //等待应答 { IIC_Stop(); return 1; } IIC_Send_Byte(reg_addr); //写寄存器地址 IIC_Wait_Ack(); //等待应答 IIC_Send_Byte(reg_val);//发送数据 if(IIC_Wait_Ack()) //等待ACK { IIC_Stop(); return 1; } IIC_Stop(); return 0; // /*HAL库*/ // uint8_t status = 0; // // // 使用HAL库发送数据(器件地址+寄存器地址+数据) // status = HAL_I2C_Mem_Write(&hi2c2, // (SP06_Advice_Address << 1), // reg_addr, // I2C_MEMADD_SIZE_8BIT, // ®_val, // 1, // 100); // // return (status == HAL_OK) ? 0 : 1; } //IIC读SPL06寄存器 uint8_t spl06_read_reg(uint8_t reg_addr) { uint8_t res; IIC_Start(); IIC_Send_Byte((SP06_Advice_Address<<1)|0);//发送器件地址+写命令 IIC_Wait_Ack(); //等待应答 IIC_Send_Byte(reg_addr); //写寄存器地址 IIC_Wait_Ack(); //等待应答 IIC_Start(); IIC_Send_Byte((SP06_Advice_Address<<1)|1);//发送器件地址+读命令 IIC_Wait_Ack(); //等待应答 res=IIC_Read_Byte(0);//读取数据,发送nACK IIC_Stop(); //产生一个停止条件 return res; // /*HAL库*/ // uint8_t reg_val = 0; // // HAL_I2C_Mem_Read(&hi2c2, // (SP06_Advice_Address << 1), // reg_addr, // I2C_MEMADD_SIZE_8BIT, // ®_val, // 1, // 100); // // return reg_val; } // void spl06_start(uint8_t mode) { spl06_write_reg(SP06_MEAS_CFG, mode);//测量模式配置 } void spl06_config_temperature(uint8_t rate,uint8_t oversampling) { uint8_t data; data = (1<<7)|rate|oversampling; if(oversampling > TMP_PRC_8)//过采样次数大于EMPERATURE_RATE_8_TIMES,应当允许数据被新的数据覆盖,内部拥有气压和温度共32级的FIFO,在大于8次(也就是大于或等于16次过采样)的时候需要被新的数据覆盖,否则数据就会丢失 { uint8_t data; data = spl06_read_reg(SP06_CFG_REG);//读取原寄存器值 data |= SPL06_CFG_T_SHIFT;//P-SHIFT位置1 spl06_write_reg(SP06_CFG_REG, data);//重新写回寄存器 } switch(oversampling) { case TMP_PRC_1: spl06.i32kT = 524288; break; case TMP_PRC_2: spl06.i32kT = 1572864; break; case TMP_PRC_4: spl06.i32kT = 3670016; break; case TMP_PRC_8: spl06.i32kT = 7864320; break; case TMP_PRC_16: spl06.i32kT = 253952; break; case TMP_PRC_32: spl06.i32kT = 516096; break; case TMP_PRC_64: spl06.i32kT = 1040384; break; case TMP_PRC_128: spl06.i32kT = 2088960; break; } spl06_write_reg(SP06_TMP_CFG, data);//重新写回寄存器 } void spl06_config_pressure(uint8_t rate,uint8_t oversampling)//设置补偿系数及采样速率 { uint8_t data; data = rate|oversampling; if(oversampling > PM_PRC_8)//过采样次数大于EMPERATURE_RATE_8_TIMES,应当允许数据被新的数据覆盖,内部拥有气压和温度共32级的FIFO,在大于8次(也就是大于或等于16次过采样)的时候需要被新的数据覆盖,否则数据就会丢失 { uint8_t data; data = spl06_read_reg(SP06_CFG_REG);//读取原寄存器值 data |= SPL06_CFG_P_SHIFT;//P-SHIFT位置1 spl06_write_reg(SP06_CFG_REG, data);//重新写回寄存器 } switch(oversampling) { case PM_PRC_1: spl06.i32kP = 524288; break; case PM_PRC_2: spl06.i32kP = 1572864; break; case PM_PRC_4: spl06.i32kP = 3670016; break; case PM_PRC_8: spl06.i32kP = 7864320; break; case PM_PRC_16: spl06.i32kP = 253952; break; case PM_PRC_32: spl06.i32kP = 516096; break; case PM_PRC_64: spl06.i32kP = 1040384; break; case PM_PRC_128: spl06.i32kP = 2088960; break; } spl06_write_reg(SP06_PSR_CFG, data); //写入配置 } int32_t spl06_get_pressure_adc(void)//获取压力ADC值 { uint8_t buf[3]; int32_t adc; buf[0] = spl06_read_reg(SP06_PSR_B2); buf[1] = spl06_read_reg(SP06_PSR_B1); buf[2] = spl06_read_reg(SP06_PSR_B0); adc = (int32_t)buf[0]<<16 | (int32_t)buf[1]<<8 | (int32_t)buf[2]; adc = (adc&0x800000)?(0xFF000000|adc):adc; return adc; } int32_t spl06_get_temperature_adc(void)//获取温度ADC值 { uint8_t buf[3]; int32_t adc; buf[0] = spl06_read_reg(SP06_TMP_B2); buf[1] = spl06_read_reg(SP06_TMP_B1); buf[2] = spl06_read_reg(SP06_TMP_B0); adc = (int32_t)buf[0]<<16 | (int32_t)buf[1]<<8 | (int32_t)buf[2]; adc = (adc&0x800000)?(0xFF000000|adc):adc; return adc; } uint8_t SPL06_Update(int32_t *Temp,int32_t *Press)//获取并计算出温度值、气压值 { float Praw_src=0,Traw_src=0; float qua2=0, qua3=0; Traw_src = spl06_get_temperature_adc()/(float)spl06.i32kT; Praw_src = spl06_get_pressure_adc()/(float)spl06.i32kP ; //计算温度 *Temp = 0.5*spl06_calib_param.c0 + spl06_calib_param.c1* Traw_src; //计算气压 qua2 = spl06_calib_param.c10 + Praw_src * (spl06_calib_param.c20 + Praw_src*spl06_calib_param.c30); qua3 = Traw_src * Praw_src * (spl06_calib_param.c11 + Praw_src * spl06_calib_param.c21); *Press = spl06_calib_param.c00 + Praw_src * qua2 + Traw_src * spl06_calib_param.c01 + qua3; return 0; } //获取传感器数据就位状态,传感器就绪状态 uint8_t spl06_get_measure_status(void) { return spl06_read_reg(SP06_MEAS_CFG); } //设置读取模式+读取方式 void spl06_set_measure_mode(uint8_t mode) //参数为模式值 { spl06_write_reg(SP06_MEAS_CFG, mode); } //启动命令模式读取温度值 void spl06_start_temperature(void) { spl06_write_reg(SP06_MEAS_CFG, MEAS_CTRL_TempMeasure); } //启动命令模式读取气压值 void spl06_start_pressure(void) { spl06_write_reg(SP06_MEAS_CFG, MEAS_CTRL_PressMeasure); } //进入待机模式,进入后停止采集数据直到再次切换模式 void spl06_enter_standby(void) { spl06_write_reg(SP06_MEAS_CFG, MEAS_CTRL_Standby); } void spl06_get_calib_param() { unsigned long h; unsigned long m; unsigned long l; h = spl06_read_reg(0x10); l = spl06_read_reg(0x11); spl06_calib_param.c0 = (int16_t)h<<4 | l>>4; spl06_calib_param.c0 = (spl06_calib_param.c0&0x0800)?(0xF000|spl06_calib_param.c0):spl06_calib_param.c0; h = spl06_read_reg(0x11); l = spl06_read_reg(0x12); spl06_calib_param.c1 = (int16_t)(h&0x0F)<<8 | l; spl06_calib_param.c1 = (spl06_calib_param.c1&0x0800)?(0xF000|spl06_calib_param.c1):spl06_calib_param.c1; h = spl06_read_reg(0x13); m = spl06_read_reg(0x14); l = spl06_read_reg(0x15); spl06_calib_param.c00 = (int32_t)h<<12 | (int32_t)m<<4 | (int32_t)l>>4; spl06_calib_param.c00 = (spl06_calib_param.c00&0x080000)?(0xFFF00000|spl06_calib_param.c00):spl06_calib_param.c00; h = spl06_read_reg(0x15); m = spl06_read_reg(0x16); l = spl06_read_reg(0x17); spl06_calib_param.c10 = (int32_t)h<<16 | (int32_t)m<<8 | l; spl06_calib_param.c10 = (spl06_calib_param.c10&0x080000)?(0xFFF00000|spl06_calib_param.c10):spl06_calib_param.c10; h = spl06_read_reg(0x18); l = spl06_read_reg(0x19); spl06_calib_param.c01 = (int16_t)h<<8 | l; h = spl06_read_reg(0x1A); l = spl06_read_reg(0x1B); spl06_calib_param.c11 = (int16_t)h<<8 | l; h = spl06_read_reg(0x1C); l = spl06_read_reg(0x1D); spl06_calib_param.c20 = (int16_t)h<<8 | l; h = spl06_read_reg(0x1E); l = spl06_read_reg(0x1F); spl06_calib_param.c21 = (int16_t)h<<8 | l; h = spl06_read_reg(0x20); l = spl06_read_reg(0x21); spl06_calib_param.c30 = (int16_t)h<<8 | l; } uint8_t SPL06_Init(void) { uint8_t spl06_start_status; if(spl06_write_reg(SP06_RESET,0x89)) { return 1; } BSP_TIME_Delay(100); //复位后系数准备好需要至少40ms do spl06_start_status = spl06_get_measure_status(); //读取气压计启动状态 while((spl06_start_status&MEAS_COEF_RDY)!=MEAS_COEF_RDY); //读取内部校准值 spl06_get_calib_param(); do spl06_start_status = spl06_get_measure_status();//读取气压计启动状态 while((spl06_start_status&MEAS_SENSOR_RDY)!= MEAS_SENSOR_RDY); spl06.chip_id = spl06_read_reg(SP06_ID); if((spl06.chip_id & 0xf0) != SP06_COEF ) { return 2; } spl06_config_pressure(PM_RATE_128,PM_PRC_8); spl06_config_temperature(TMP_RATE_128,TMP_PRC_8); spl06_start(MEAS_CTRL_ContinuousPressTemp); //启动连续的气压温度测量 return 0; } //通过气压计算高度 int32_t SPL06_CaculateHeight(int32_t GasPress) { int32_t Altitude=0; Altitude =(44330.0 *(1.0-pow((float)(GasPress) / 101325.0,1.0/5.255)))*1000;//单位mm return Altitude; }