目录
概述
最近项目上的需要,增加气压检测功能,通过网上搜索得知,这个传感器的资料比较少,在此写了一个Demo,希望能帮助到需要的攻城狮们,一起学习一起探讨,加油 加油 加油!
一、原理图
二、平台
1、keil5.29
2、RTL8762D(瑞昱 蓝牙芯片)
三、编码
1、spl06_007.h文件
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SPL06_007_H__
#define __SPL06_007_H__
#include "stdint.h"
#define SPL06_7BITI2C_ADDRESS 0x76
//Barometric rate(sample/sec),Background Model using
#define PM_RATE_1 (0<<4) //1 measurements pr. sec.
#define PM_RATE_2 (1<<4) //2 measurements pr. sec.
#define PM_RATE_4 (2<<4) //4 measurements pr. sec.
#define PM_RATE_8 (3<<4) //8 measurements pr. sec.
#define PM_RATE_16 (4<<4) //16 measurements pr. sec.
#define PM_RATE_32 (5<<4) //32 measurements pr. sec.
#define PM_RATE_64 (6<<4) //64 measurements pr. sec.
#define PM_RATE_128 (7<<4) //128 measurements pr. sec.
//Air pressure resampling rate(times),Background Model using
#define PM_PRC_1 0 //Sigle kP=524288 ,3.6ms
#define PM_PRC_2 1 //2 times kP=1572864 ,5.2ms
#define PM_PRC_4 2 //4 times kP=3670016 ,8.4ms
#define PM_PRC_8 3 //8 times kP=7864320 ,14.8ms
#define PM_PRC_16 4 //16 times kP=253952 ,27.6ms
#define PM_PRC_32 5 //32 times kP=516096 ,53.2ms
#define PM_PRC_64 6 //64 times kP=1040384 ,104.4ms
#define PM_PRC_128 7 //128 times kP=2088960 ,206.8ms
//Temperature measurement rate(sample/sec),Background Model using
#define TMP_RATE_1 (0<<4) //1 measurements pr. sec.
#define TMP_RATE_2 (1<<4) //2 measurements pr. sec.
#define TMP_RATE_4 (2<<4) //4 measurements pr. sec.
#define TMP_RATE_8 (3<<4) //8 measurements pr. sec.
#define TMP_RATE_16 (4<<4) //16 measurements pr. sec.
#define TMP_RATE_32 (5<<4) //32 measurements pr. sec.
#define TMP_RATE_64 (6<<4) //64 measurements pr. sec.
#define TMP_RATE_128 (7<<4) //128 measurements pr. sec.
//Temperature resampling rate(times),Background Model using
#define TMP_PRC_1 0 //Sigle
#define TMP_PRC_2 1 //2 times
#define TMP_PRC_4 2 //4 times
#define TMP_PRC_8 3 //8 times
#define TMP_PRC_16 4 //16 times
#define TMP_PRC_32 5 //32 times
#define TMP_PRC_64 6 //64 times
#define TMP_PRC_128 7 //128 times
//SPL06_MEAS_CFG
#define MEAS_COEF_RDY 0x80
#define MEAS_SENSOR_RDY 0x40 //The sensor is initialized
#define MEAS_TMP_RDY 0x20 //There are new temperature data
#define MEAS_PRS_RDY 0x10 //We have new barometric data
#define MEAS_CTRL_Standby 0x00 //idle mode
#define MEAS_CTRL_PressMeasure 0x01 //Single pressure measurement
#define MEAS_CTRL_TempMeasure 0x02 //Single temperature measurement
#define MEAS_CTRL_ContinuousPress 0x05 //Continuous pressure measurement
#define MEAS_CTRL_ContinuousTemp 0x06 //Continuous temperature measurement
#define MEAS_CTRL_ContinuousPressTemp 0x07 //Continuous barometric temperature measurement
//FIFO_STS
#define SPL06_FIFO_FULL 0x02
#define SPL06_FIFO_EMPTY 0x01
//INT_STS
#define SPL06_INT_FIFO_FULL 0x04
#define SPL06_INT_TMP 0x02
#define SPL06_INT_PRS 0x01
//CFG_REG
#define SPL06_CFG_T_SHIFT 0x08 //oversampling times>8 Must be used at 8 o 'clock
#define SPL06_CFG_P_SHIFT 0x04
#define SP06_PSR_B2 0x00 //pressure value
#define SP06_PSR_B1 0x01
#define SP06_PSR_B0 0x02
#define SP06_TMP_B2 0x03 //Temperature value
#define SP06_TMP_B1 0x04
#define SP06_TMP_B0 0x05
#define SP06_PSR_CFG 0x06 //Barometric configuration
#define SP06_TMP_CFG 0x07 //Temperature measurement configuration
#define SP06_MEAS_CFG 0x08 //Measurement mode configuration
#define SP06_CFG_REG 0x09
#define SP06_INT_STS 0x0A
#define SP06_FIFO_STS 0x0B
#define SP06_RESET 0x0C
#define SP06_ID 0x0D
#define SP06_COEF 0x10 //-0x21
#define SP06_COEF_SRCE 0x28
uint8_t spl06_init(void);
uint8_t spl06_007_bpm_algo_handler(void);
#endif /* __MODULE_SPL06_007_IIC__H__ */
/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/
2、spl06_007.c文件
/*********************************************************************************************************
* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
**********************************************************************************************************
* @file spl06_007.c
* @brief
* @details
* @author
* @date
* @version v0.1
*********************************************************************************************************
*/
#include "trace.h"
#include "rtl876x_spi.h"
#include "rtl876x_i2c.h"
#include "rtl876x_rcc.h"
#include "rtl876x_gpio.h"
#include "rtl876x_nvic.h"
#include "board.h"
#include "string.h"
#include "hub_task.h"
#include "os_sched.h"
#include "os_timer.h"
#include "SEGGER_RTT.h"
#include "rtl876x_tim.h"
#include "BD_health_math.h"
#include "spl06_007.h"
#include "math.h"
#define BAROCEPTOR_LOG_EN (true)
#if (BAROCEPTOR_LOG_EN == true)
#include "xky_private_service.h"
#include "stdio.h"
#define BAROCEPTOR_LOG DBG_LOG
#else
#define HEART_LOG(...)
#endif
float _kT=0, _kP=0;
int16_t _C0=0, _C1=0, _C01=0, _C11=0, _C20=0, _C21=0, _C30=0;
int32_t _C00=0, _C10=0;
void SPL06_007_Delay_ms(uint16_t delay_time)
{
os_delay(delay_time);
}
uint8_t SPL06_007_I2c_Write(uint8_t reg, uint8_t dat)
{
uint8_t I2C_WriteBuf[2] = {0x0, 0x0};
I2C_WriteBuf[0] = reg;
I2C_WriteBuf[1] = dat;
uint32_t time_out = SYSTEM_IIC_TIMEROUT;
while ((I2C_GetFlagState(HRS_I2C_BUS, I2C_FLAG_TFE) == RESET) && (--time_out != 0));
time_out = SYSTEM_IIC_TIMEROUT;
while ((I2C_GetFlagState(HRS_I2C_BUS, I2C_FLAG_MST_ACTIVITY) == SET) && (--time_out != 0));
I2C_SetSlaveAddress(HRS_I2C_BUS, SPL06_7BITI2C_ADDRESS);
I2C_MasterWrite(HRS_I2C_BUS, I2C_WriteBuf, 2);
if (time_out == 0) {
RtkWristbandSys.flag_field.i2c_bus_lock = true;
}
return 0;
}
uint8_t SPL06_007_I2c_Read(uint8_t reg, uint8_t *buf, uint8_t len)
{
uint8_t tmp_buffer[1] = {0};
uint32_t time_out = SYSTEM_IIC_TIMEROUT;
tmp_buffer[0] = reg;
while ((I2C_GetFlagState(HRS_I2C_BUS, I2C_FLAG_TFE) == RESET) && (--time_out != 0));
time_out = SYSTEM_IIC_TIMEROUT;
while ((I2C_GetFlagState(HRS_I2C_BUS, I2C_FLAG_MST_ACTIVITY) == SET) && (--time_out != 0));
// I2C_SetSlaveAddress(HRS_I2C_BUS, (SPL06_7BITI2C_ADDRESS << 1));
I2C_SetSlaveAddress(HRS_I2C_BUS, SPL06_7BITI2C_ADDRESS);
I2C_Status ret = I2C_RepeatRead(HRS_I2C_BUS, tmp_buffer, 1, buf, len);
if (time_out == 0) {
RtkWristbandSys.flag_field.i2c_bus_lock = true;
}
if (ret != I2C_Success) {
return 1;
}
return 0;
}
uint8_t SPL06_007_Write_Reg(uint8_t regAddr, uint8_t data)
{
return SPL06_007_I2c_Write(regAddr, data);
}
uint8_t SPL06_007_Read_Reg(uint8_t regAddr, uint8_t *buf)
{
return SPL06_007_I2c_Read(regAddr, buf, 1);
}
uint8_t SPL06_007_MultiRead_Reg(uint8_t regAddr, uint8_t *buf, uint16_t len)
{
return SPL06_007_I2c_Read(regAddr, buf, len);
}
void SPL06_Start(uint8_t mode)
{
SPL06_007_Write_Reg(SP06_MEAS_CFG, mode);//Measurement mode configuration
}
void SPL06_Config_Temperature(uint8_t rate,uint8_t oversampling)
{
uint8_t temp = 0;
switch(oversampling)
{
case TMP_PRC_1:
_kT = 524288;
break;
case TMP_PRC_2:
_kT = 1572864;
break;
case TMP_PRC_4:
_kT = 3670016;
break;
case TMP_PRC_8:
_kT = 7864320;
break;
case TMP_PRC_16:
_kT = 253952;
break;
case TMP_PRC_32:
_kT = 516096;
break;
case TMP_PRC_64:
_kT = 1040384;
break;
case TMP_PRC_128:
_kT = 2088960;
break;
}
SPL06_007_Write_Reg(SP06_TMP_CFG,rate|oversampling|0x80); //Temperature measured 128 times per second (maximum speed)
if (oversampling > TMP_PRC_8)
{
SPL06_007_Read_Reg(SP06_CFG_REG, &temp);
SPL06_007_Write_Reg(SP06_CFG_REG,temp|SPL06_CFG_T_SHIFT);
}
}
void SPL06_Config_Pressure(uint8_t rate,uint8_t oversampling)//Set the compensation coefficient and sampling rate
{
uint8_t temp = 0;
switch(oversampling)
{
case PM_PRC_1:
_kP = 524288;
break;
case PM_PRC_2:
_kP = 1572864;
break;
case PM_PRC_4:
_kP = 3670016;
break;
case PM_PRC_8:
_kP = 7864320;
break;
case PM_PRC_16:
_kP = 253952;
break;
case PM_PRC_32:
_kP = 516096;
break;
case PM_PRC_64:
_kP = 1040384;
break;
case PM_PRC_128:
_kP = 2088960;
break;
}
SPL06_007_Write_Reg(SP06_PSR_CFG,rate|oversampling);
if(oversampling > PM_PRC_8)
{
SPL06_007_Read_Reg(SP06_CFG_REG, &temp);
SPL06_007_Write_Reg(SP06_CFG_REG,temp|SPL06_CFG_P_SHIFT);
}
}
int32_t SPL06_Get_Pressure_ADC(void)//Get the pressure ADC value
{
uint8_t buf[3];
int32_t adc;
SPL06_007_MultiRead_Reg(SP06_PSR_B2, buf, 3);
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)//Get the temperature ADC value
{
uint8_t buf[3];
int32_t adc;
SPL06_007_MultiRead_Reg(SP06_TMP_B2,buf,3);
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(float *Temp,float *Press)//Obtain and calculate the temperature value, the pressure value
{
float Praw_src=0,Traw_src=0;
float qua2=0, qua3=0;
Traw_src = SPL06_Get_Temperature_ADC()/_kT;
Praw_src = SPL06_Get_Pressure_ADC()/_kP ;
//calculating temperature
*Temp = 0.5f*_C0 + Traw_src * _C1;
//Calculation of pressure
qua2 = _C10 + Praw_src * (_C20 + Praw_src* _C30);
qua3 = Traw_src * Praw_src * (_C11 + Praw_src * _C21);
*Press = _C00 + Praw_src * qua2 + Traw_src * _C01 + qua3;
return 0;
}
uint8_t spl06_init(void)
{
uint8_t coef[18];
uint8_t id;
if (SPL06_007_Write_Reg(SP06_RESET, 0x89))
return 1;
SPL06_007_Delay_ms(40);
SPL06_007_Read_Reg(SP06_ID, &id);
BAROCEPTOR_LOG("SPL06-ID: 0x%x\n",id);
if (id != 0x10)
{
return 2;
}
BAROCEPTOR_LOG("SPL06 is OK: 0x%x\r\n",id);
SPL06_007_Delay_ms(100); //Reset after coefficient ready required at least 40ms
SPL06_007_MultiRead_Reg(SP06_COEF, coef, 18);//Read relevant data
_C0 = ((int16_t)coef[0]<<4 ) | ((coef[1]&0xF0)>>4);
_C0 = (_C0&0x0800)?(0xF000|_C0):_C0;
_C1 = ((int16_t)(coef[1]&0x0F)<<8 ) | coef[2];
_C1 = (_C1&0x0800)?(0xF000|_C1):_C1;
_C00 = (int32_t)coef[3]<<12 | (int32_t)coef[4]<<4 | (int32_t)coef[5]>>4;
_C10 = (int32_t)(coef[5]&0x0F)<<16 | (int32_t)coef[6]<<8 | (int32_t)coef[7];
_C00 = (_C00&0x080000)?(0xFFF00000|_C00):_C00;
_C10 = (_C10&0x080000)?(0xFFF00000|_C10):_C10;
_C01 = ((int16_t)coef[8]<<8 ) | coef[9];
_C01 = (_C01&0x0800)?(0xF000|_C01):_C01;
_C11 = ((int16_t)coef[10]<<8 ) | coef[11];
_C11 = (_C11&0x0800)?(0xF000|_C11):_C11;
_C20 = ((int16_t)coef[12]<<8 ) | coef[13];
_C20 = (_C20&0x0800)?(0xF000|_C20):_C20;
_C21 = ((int16_t)coef[14]<<8 ) | coef[15];
_C21 = (_C21&0x0800)?(0xF000|_C21):_C21;
_C30 = ((int16_t)coef[16]<<8 ) | coef[17];
_C30 = (_C30&0x0800)?(0xF000|_C30):_C30;
SPL06_Config_Pressure(PM_RATE_128,PM_PRC_64);
SPL06_Config_Temperature(PM_RATE_8,TMP_PRC_8);
SPL06_Start(MEAS_CTRL_ContinuousPressTemp); //Start continuous pressure temperature measurement
SPL06_007_Delay_ms(20);
return 0;
}
float Caculate_Altitude(float GasPress)
{
float Altitude=0;
Altitude =(44330.0 *(1.0-pow((float)(GasPress) / 101325.0,1.0/5.255)));
return Altitude;
}
static uint8_t spl06_007_bpm_algo_handler(void)
{
static float paValue = 0;
static float AltitudeHight = 0;
float temp =0;
SPL06_UpDate(&temp, &paValue);
char Buffer_pa[100]={0};
char Buffer_temp[100]={0};
char Buffer_AltitudeHight[100]={0};
sprintf(Buffer_pa,"%0.2f ",paValue);
sprintf(Buffer_temp,"%0.2f ",temp);
// BAROCEPTOR_LOG("t:%s p:%s\r\n", Buffer_pa, Buffer_temp);
AltitudeHight = Caculate_Altitude(paValue);
sprintf(Buffer_AltitudeHight,"%0.2f ", AltitudeHight);
BAROCEPTOR_LOG("paValue:%s AltitudeHight:%s\r\n", Buffer_pa, Buffer_AltitudeHight);
SPL06_007_Delay_ms(5);
if (0) { //open hr monitor
return HRM_MeasureOutput;
}
return HRM_Measuring;
}
static uint16_t spl06_007_driver_timer_event_handler(void)
{
return spl06_007_bpm_algo_handler();
}
3、main.c文件
#include <stdlib.h>
#include "board.h"
#include "os_sched.h"
#include "string.h"
#include "trace.h"
#include "gap.h"
#include "gap_adv.h"
#include "gap_bond_le.h"
#include "app_task.h"
#include "communicate_task.h"
#include "dlps.h"
#include "ftl.h"
#include "ias.h"
#include "bas.h"
#include "hids_media.h"
#include "ancs.h"
#include "ams.h"
#include <gatts_client.h>
#include "rtl876x_io_dlps.h"
#include "rtl876x_rcc.h"
#include "rtl876x_i2c.h"
#include "otp_config.h"
#include "rtl876x_lib_platform.h"
#include "single_tone.h"
#include "profile_server.h"
#include "hub_clock.h"
#include "app_flash_config.h"
#include "profile_client.h"
#include "ota_service.h"
#include "hub_task.h"
#include "hci_app.h"
#include "flash_test_temp.h"
#include "spl06_007.h"
int main(void)
{
le_gap_init(1);
gap_lib_init();
app_le_gap_init();
app_le_profile_init();
pwr_mgr_init();
task_init();
os_sched_start();
}
四、运行结果
五、总结
好了,就介绍到此为止,做个笔录,同时也希望能帮助到需要帮助的攻城狮们。
参考文章:
1、关于SPL06的使用_HES_C的博客-CSDN博客_spl06
供参考示例代码:
1、STM32_SPL06-01-I2C例程.rar-其它文档类资源-CSDN下载
2、STM32_SPL06-01-SPI例程.rar-嵌入式文档类资源-CSDN下载
版权声明:本文为CSDN博主「Ch_champion」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36075612/article/details/119965875
目录
概述
最近项目上的需要,增加气压检测功能,通过网上搜索得知,这个传感器的资料比较少,在此写了一个Demo,希望能帮助到需要的攻城狮们,一起学习一起探讨,加油 加油 加油!
一、原理图
二、平台
1、keil5.29
2、RTL8762D(瑞昱 蓝牙芯片)
三、编码
1、spl06_007.h文件
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SPL06_007_H__
#define __SPL06_007_H__
#include "stdint.h"
#define SPL06_7BITI2C_ADDRESS 0x76
//Barometric rate(sample/sec),Background Model using
#define PM_RATE_1 (0<<4) //1 measurements pr. sec.
#define PM_RATE_2 (1<<4) //2 measurements pr. sec.
#define PM_RATE_4 (2<<4) //4 measurements pr. sec.
#define PM_RATE_8 (3<<4) //8 measurements pr. sec.
#define PM_RATE_16 (4<<4) //16 measurements pr. sec.
#define PM_RATE_32 (5<<4) //32 measurements pr. sec.
#define PM_RATE_64 (6<<4) //64 measurements pr. sec.
#define PM_RATE_128 (7<<4) //128 measurements pr. sec.
//Air pressure resampling rate(times),Background Model using
#define PM_PRC_1 0 //Sigle kP=524288 ,3.6ms
#define PM_PRC_2 1 //2 times kP=1572864 ,5.2ms
#define PM_PRC_4 2 //4 times kP=3670016 ,8.4ms
#define PM_PRC_8 3 //8 times kP=7864320 ,14.8ms
#define PM_PRC_16 4 //16 times kP=253952 ,27.6ms
#define PM_PRC_32 5 //32 times kP=516096 ,53.2ms
#define PM_PRC_64 6 //64 times kP=1040384 ,104.4ms
#define PM_PRC_128 7 //128 times kP=2088960 ,206.8ms
//Temperature measurement rate(sample/sec),Background Model using
#define TMP_RATE_1 (0<<4) //1 measurements pr. sec.
#define TMP_RATE_2 (1<<4) //2 measurements pr. sec.
#define TMP_RATE_4 (2<<4) //4 measurements pr. sec.
#define TMP_RATE_8 (3<<4) //8 measurements pr. sec.
#define TMP_RATE_16 (4<<4) //16 measurements pr. sec.
#define TMP_RATE_32 (5<<4) //32 measurements pr. sec.
#define TMP_RATE_64 (6<<4) //64 measurements pr. sec.
#define TMP_RATE_128 (7<<4) //128 measurements pr. sec.
//Temperature resampling rate(times),Background Model using
#define TMP_PRC_1 0 //Sigle
#define TMP_PRC_2 1 //2 times
#define TMP_PRC_4 2 //4 times
#define TMP_PRC_8 3 //8 times
#define TMP_PRC_16 4 //16 times
#define TMP_PRC_32 5 //32 times
#define TMP_PRC_64 6 //64 times
#define TMP_PRC_128 7 //128 times
//SPL06_MEAS_CFG
#define MEAS_COEF_RDY 0x80
#define MEAS_SENSOR_RDY 0x40 //The sensor is initialized
#define MEAS_TMP_RDY 0x20 //There are new temperature data
#define MEAS_PRS_RDY 0x10 //We have new barometric data
#define MEAS_CTRL_Standby 0x00 //idle mode
#define MEAS_CTRL_PressMeasure 0x01 //Single pressure measurement
#define MEAS_CTRL_TempMeasure 0x02 //Single temperature measurement
#define MEAS_CTRL_ContinuousPress 0x05 //Continuous pressure measurement
#define MEAS_CTRL_ContinuousTemp 0x06 //Continuous temperature measurement
#define MEAS_CTRL_ContinuousPressTemp 0x07 //Continuous barometric temperature measurement
//FIFO_STS
#define SPL06_FIFO_FULL 0x02
#define SPL06_FIFO_EMPTY 0x01
//INT_STS
#define SPL06_INT_FIFO_FULL 0x04
#define SPL06_INT_TMP 0x02
#define SPL06_INT_PRS 0x01
//CFG_REG
#define SPL06_CFG_T_SHIFT 0x08 //oversampling times>8 Must be used at 8 o 'clock
#define SPL06_CFG_P_SHIFT 0x04
#define SP06_PSR_B2 0x00 //pressure value
#define SP06_PSR_B1 0x01
#define SP06_PSR_B0 0x02
#define SP06_TMP_B2 0x03 //Temperature value
#define SP06_TMP_B1 0x04
#define SP06_TMP_B0 0x05
#define SP06_PSR_CFG 0x06 //Barometric configuration
#define SP06_TMP_CFG 0x07 //Temperature measurement configuration
#define SP06_MEAS_CFG 0x08 //Measurement mode configuration
#define SP06_CFG_REG 0x09
#define SP06_INT_STS 0x0A
#define SP06_FIFO_STS 0x0B
#define SP06_RESET 0x0C
#define SP06_ID 0x0D
#define SP06_COEF 0x10 //-0x21
#define SP06_COEF_SRCE 0x28
uint8_t spl06_init(void);
uint8_t spl06_007_bpm_algo_handler(void);
#endif /* __MODULE_SPL06_007_IIC__H__ */
/******************* (C) COPYRIGHT 2012 STMicroelectronics *****END OF FILE****/
2、spl06_007.c文件
/*********************************************************************************************************
* Copyright(c) 2018, Realtek Semiconductor Corporation. All rights reserved.
**********************************************************************************************************
* @file spl06_007.c
* @brief
* @details
* @author
* @date
* @version v0.1
*********************************************************************************************************
*/
#include "trace.h"
#include "rtl876x_spi.h"
#include "rtl876x_i2c.h"
#include "rtl876x_rcc.h"
#include "rtl876x_gpio.h"
#include "rtl876x_nvic.h"
#include "board.h"
#include "string.h"
#include "hub_task.h"
#include "os_sched.h"
#include "os_timer.h"
#include "SEGGER_RTT.h"
#include "rtl876x_tim.h"
#include "BD_health_math.h"
#include "spl06_007.h"
#include "math.h"
#define BAROCEPTOR_LOG_EN (true)
#if (BAROCEPTOR_LOG_EN == true)
#include "xky_private_service.h"
#include "stdio.h"
#define BAROCEPTOR_LOG DBG_LOG
#else
#define HEART_LOG(...)
#endif
float _kT=0, _kP=0;
int16_t _C0=0, _C1=0, _C01=0, _C11=0, _C20=0, _C21=0, _C30=0;
int32_t _C00=0, _C10=0;
void SPL06_007_Delay_ms(uint16_t delay_time)
{
os_delay(delay_time);
}
uint8_t SPL06_007_I2c_Write(uint8_t reg, uint8_t dat)
{
uint8_t I2C_WriteBuf[2] = {0x0, 0x0};
I2C_WriteBuf[0] = reg;
I2C_WriteBuf[1] = dat;
uint32_t time_out = SYSTEM_IIC_TIMEROUT;
while ((I2C_GetFlagState(HRS_I2C_BUS, I2C_FLAG_TFE) == RESET) && (--time_out != 0));
time_out = SYSTEM_IIC_TIMEROUT;
while ((I2C_GetFlagState(HRS_I2C_BUS, I2C_FLAG_MST_ACTIVITY) == SET) && (--time_out != 0));
I2C_SetSlaveAddress(HRS_I2C_BUS, SPL06_7BITI2C_ADDRESS);
I2C_MasterWrite(HRS_I2C_BUS, I2C_WriteBuf, 2);
if (time_out == 0) {
RtkWristbandSys.flag_field.i2c_bus_lock = true;
}
return 0;
}
uint8_t SPL06_007_I2c_Read(uint8_t reg, uint8_t *buf, uint8_t len)
{
uint8_t tmp_buffer[1] = {0};
uint32_t time_out = SYSTEM_IIC_TIMEROUT;
tmp_buffer[0] = reg;
while ((I2C_GetFlagState(HRS_I2C_BUS, I2C_FLAG_TFE) == RESET) && (--time_out != 0));
time_out = SYSTEM_IIC_TIMEROUT;
while ((I2C_GetFlagState(HRS_I2C_BUS, I2C_FLAG_MST_ACTIVITY) == SET) && (--time_out != 0));
// I2C_SetSlaveAddress(HRS_I2C_BUS, (SPL06_7BITI2C_ADDRESS << 1));
I2C_SetSlaveAddress(HRS_I2C_BUS, SPL06_7BITI2C_ADDRESS);
I2C_Status ret = I2C_RepeatRead(HRS_I2C_BUS, tmp_buffer, 1, buf, len);
if (time_out == 0) {
RtkWristbandSys.flag_field.i2c_bus_lock = true;
}
if (ret != I2C_Success) {
return 1;
}
return 0;
}
uint8_t SPL06_007_Write_Reg(uint8_t regAddr, uint8_t data)
{
return SPL06_007_I2c_Write(regAddr, data);
}
uint8_t SPL06_007_Read_Reg(uint8_t regAddr, uint8_t *buf)
{
return SPL06_007_I2c_Read(regAddr, buf, 1);
}
uint8_t SPL06_007_MultiRead_Reg(uint8_t regAddr, uint8_t *buf, uint16_t len)
{
return SPL06_007_I2c_Read(regAddr, buf, len);
}
void SPL06_Start(uint8_t mode)
{
SPL06_007_Write_Reg(SP06_MEAS_CFG, mode);//Measurement mode configuration
}
void SPL06_Config_Temperature(uint8_t rate,uint8_t oversampling)
{
uint8_t temp = 0;
switch(oversampling)
{
case TMP_PRC_1:
_kT = 524288;
break;
case TMP_PRC_2:
_kT = 1572864;
break;
case TMP_PRC_4:
_kT = 3670016;
break;
case TMP_PRC_8:
_kT = 7864320;
break;
case TMP_PRC_16:
_kT = 253952;
break;
case TMP_PRC_32:
_kT = 516096;
break;
case TMP_PRC_64:
_kT = 1040384;
break;
case TMP_PRC_128:
_kT = 2088960;
break;
}
SPL06_007_Write_Reg(SP06_TMP_CFG,rate|oversampling|0x80); //Temperature measured 128 times per second (maximum speed)
if (oversampling > TMP_PRC_8)
{
SPL06_007_Read_Reg(SP06_CFG_REG, &temp);
SPL06_007_Write_Reg(SP06_CFG_REG,temp|SPL06_CFG_T_SHIFT);
}
}
void SPL06_Config_Pressure(uint8_t rate,uint8_t oversampling)//Set the compensation coefficient and sampling rate
{
uint8_t temp = 0;
switch(oversampling)
{
case PM_PRC_1:
_kP = 524288;
break;
case PM_PRC_2:
_kP = 1572864;
break;
case PM_PRC_4:
_kP = 3670016;
break;
case PM_PRC_8:
_kP = 7864320;
break;
case PM_PRC_16:
_kP = 253952;
break;
case PM_PRC_32:
_kP = 516096;
break;
case PM_PRC_64:
_kP = 1040384;
break;
case PM_PRC_128:
_kP = 2088960;
break;
}
SPL06_007_Write_Reg(SP06_PSR_CFG,rate|oversampling);
if(oversampling > PM_PRC_8)
{
SPL06_007_Read_Reg(SP06_CFG_REG, &temp);
SPL06_007_Write_Reg(SP06_CFG_REG,temp|SPL06_CFG_P_SHIFT);
}
}
int32_t SPL06_Get_Pressure_ADC(void)//Get the pressure ADC value
{
uint8_t buf[3];
int32_t adc;
SPL06_007_MultiRead_Reg(SP06_PSR_B2, buf, 3);
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)//Get the temperature ADC value
{
uint8_t buf[3];
int32_t adc;
SPL06_007_MultiRead_Reg(SP06_TMP_B2,buf,3);
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(float *Temp,float *Press)//Obtain and calculate the temperature value, the pressure value
{
float Praw_src=0,Traw_src=0;
float qua2=0, qua3=0;
Traw_src = SPL06_Get_Temperature_ADC()/_kT;
Praw_src = SPL06_Get_Pressure_ADC()/_kP ;
//calculating temperature
*Temp = 0.5f*_C0 + Traw_src * _C1;
//Calculation of pressure
qua2 = _C10 + Praw_src * (_C20 + Praw_src* _C30);
qua3 = Traw_src * Praw_src * (_C11 + Praw_src * _C21);
*Press = _C00 + Praw_src * qua2 + Traw_src * _C01 + qua3;
return 0;
}
uint8_t spl06_init(void)
{
uint8_t coef[18];
uint8_t id;
if (SPL06_007_Write_Reg(SP06_RESET, 0x89))
return 1;
SPL06_007_Delay_ms(40);
SPL06_007_Read_Reg(SP06_ID, &id);
BAROCEPTOR_LOG("SPL06-ID: 0x%x\n",id);
if (id != 0x10)
{
return 2;
}
BAROCEPTOR_LOG("SPL06 is OK: 0x%x\r\n",id);
SPL06_007_Delay_ms(100); //Reset after coefficient ready required at least 40ms
SPL06_007_MultiRead_Reg(SP06_COEF, coef, 18);//Read relevant data
_C0 = ((int16_t)coef[0]<<4 ) | ((coef[1]&0xF0)>>4);
_C0 = (_C0&0x0800)?(0xF000|_C0):_C0;
_C1 = ((int16_t)(coef[1]&0x0F)<<8 ) | coef[2];
_C1 = (_C1&0x0800)?(0xF000|_C1):_C1;
_C00 = (int32_t)coef[3]<<12 | (int32_t)coef[4]<<4 | (int32_t)coef[5]>>4;
_C10 = (int32_t)(coef[5]&0x0F)<<16 | (int32_t)coef[6]<<8 | (int32_t)coef[7];
_C00 = (_C00&0x080000)?(0xFFF00000|_C00):_C00;
_C10 = (_C10&0x080000)?(0xFFF00000|_C10):_C10;
_C01 = ((int16_t)coef[8]<<8 ) | coef[9];
_C01 = (_C01&0x0800)?(0xF000|_C01):_C01;
_C11 = ((int16_t)coef[10]<<8 ) | coef[11];
_C11 = (_C11&0x0800)?(0xF000|_C11):_C11;
_C20 = ((int16_t)coef[12]<<8 ) | coef[13];
_C20 = (_C20&0x0800)?(0xF000|_C20):_C20;
_C21 = ((int16_t)coef[14]<<8 ) | coef[15];
_C21 = (_C21&0x0800)?(0xF000|_C21):_C21;
_C30 = ((int16_t)coef[16]<<8 ) | coef[17];
_C30 = (_C30&0x0800)?(0xF000|_C30):_C30;
SPL06_Config_Pressure(PM_RATE_128,PM_PRC_64);
SPL06_Config_Temperature(PM_RATE_8,TMP_PRC_8);
SPL06_Start(MEAS_CTRL_ContinuousPressTemp); //Start continuous pressure temperature measurement
SPL06_007_Delay_ms(20);
return 0;
}
float Caculate_Altitude(float GasPress)
{
float Altitude=0;
Altitude =(44330.0 *(1.0-pow((float)(GasPress) / 101325.0,1.0/5.255)));
return Altitude;
}
static uint8_t spl06_007_bpm_algo_handler(void)
{
static float paValue = 0;
static float AltitudeHight = 0;
float temp =0;
SPL06_UpDate(&temp, &paValue);
char Buffer_pa[100]={0};
char Buffer_temp[100]={0};
char Buffer_AltitudeHight[100]={0};
sprintf(Buffer_pa,"%0.2f ",paValue);
sprintf(Buffer_temp,"%0.2f ",temp);
// BAROCEPTOR_LOG("t:%s p:%s\r\n", Buffer_pa, Buffer_temp);
AltitudeHight = Caculate_Altitude(paValue);
sprintf(Buffer_AltitudeHight,"%0.2f ", AltitudeHight);
BAROCEPTOR_LOG("paValue:%s AltitudeHight:%s\r\n", Buffer_pa, Buffer_AltitudeHight);
SPL06_007_Delay_ms(5);
if (0) { //open hr monitor
return HRM_MeasureOutput;
}
return HRM_Measuring;
}
static uint16_t spl06_007_driver_timer_event_handler(void)
{
return spl06_007_bpm_algo_handler();
}
3、main.c文件
#include <stdlib.h>
#include "board.h"
#include "os_sched.h"
#include "string.h"
#include "trace.h"
#include "gap.h"
#include "gap_adv.h"
#include "gap_bond_le.h"
#include "app_task.h"
#include "communicate_task.h"
#include "dlps.h"
#include "ftl.h"
#include "ias.h"
#include "bas.h"
#include "hids_media.h"
#include "ancs.h"
#include "ams.h"
#include <gatts_client.h>
#include "rtl876x_io_dlps.h"
#include "rtl876x_rcc.h"
#include "rtl876x_i2c.h"
#include "otp_config.h"
#include "rtl876x_lib_platform.h"
#include "single_tone.h"
#include "profile_server.h"
#include "hub_clock.h"
#include "app_flash_config.h"
#include "profile_client.h"
#include "ota_service.h"
#include "hub_task.h"
#include "hci_app.h"
#include "flash_test_temp.h"
#include "spl06_007.h"
int main(void)
{
le_gap_init(1);
gap_lib_init();
app_le_gap_init();
app_le_profile_init();
pwr_mgr_init();
task_init();
os_sched_start();
}
四、运行结果
五、总结
好了,就介绍到此为止,做个笔录,同时也希望能帮助到需要帮助的攻城狮们。
参考文章:
1、关于SPL06的使用_HES_C的博客-CSDN博客_spl06
供参考示例代码:
1、STM32_SPL06-01-I2C例程.rar-其它文档类资源-CSDN下载
2、STM32_SPL06-01-SPI例程.rar-嵌入式文档类资源-CSDN下载
版权声明:本文为CSDN博主「Ch_champion」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36075612/article/details/119965875
暂无评论