当前位置:网站首页>Spl06-007 air pressure sensor (example of barometer)
Spl06-007 air pressure sensor (example of barometer)
2022-07-03 11:26:00 【Ch_ champion】
Catalog
summary
Needs on recent projects , Add air pressure detection function , Through online search, we know , There is less information about this sensor , Here is a Demo, Hope to help the siege lions in need , Study and discuss together , come on. come on. come on. !
One 、 Schematic diagram

Two 、 platform
1、keil5.29
2、RTL8762D( Realtek Bluetooth chip )
3、 ... and 、 code
1、spl06_007.h file
/* 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 file
/*********************************************************************************************************
* 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 file
#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();
}Four 、 Running results

5、 ... and 、 summary
Okay , That's all for the introduction , Take a note , At the same time, I hope I can help the siege lions who need help .
Reference article :
1、 About SPL06 Use _HES_C The blog of -CSDN Blog _spl06
2、SPL06-001 barometer _ Super brother's column -CSDN Blog
Sample code for reference :
1、STM32_SPL06-01-I2C routine .rar- Other document resources -CSDN download
2、STM32_SPL06-01-SPI routine .rar- Embedded document resources -CSDN download
边栏推荐
- Hal - General
- 软考中级软件设计师该怎么备考
- How to clean up v$rman_ backup_ job_ Details view reports error ora-02030
- Gut | Yu Jun group of the Chinese University of Hong Kong revealed that smoking changes intestinal flora and promotes colorectal cancer (do not smoke)
- Reading notes: heart like Bodhi, Cao Dewang
- 一文搞懂Go语言Context
- 1. Hal driven development
- 项目管理精华读书笔记(七)
- 【obs】封装obs实现采集的基础流程
- Using onvif protocol to operate the device
猜你喜欢

面試題總結(2) IO模型,集合,NIO 原理,緩存穿透,擊穿雪崩

Crawl with requests

Google Earth Engine(GEE)——GHSL 全球人口网格数据集250米分辨率

【obs】obs的ini格式的ConfigFile
![[proteus simulation] 16 channel water lamp composed of 74hc154 four wire to 12 wire decoder](/img/1f/729594930c7c97d3e731987f4c3645.png)
[proteus simulation] 16 channel water lamp composed of 74hc154 four wire to 12 wire decoder

Tencent micro app to get wechat user information

AIDL

The element form shows the relationship between elementary transformation and elementary matrix

Multi dimensional monitoring: the data base of intelligent monitoring

有赞CTO崔玉松:有赞Jarvis核心目标是使产品变得更加聪明和可靠
随机推荐
ORACLE 11G 单机冷备数据库
[vtk] interpretation of source code comments of vtkwindowedsincpolydatafilter
搭建ADG后,实例2无法启动 ORA-29760: instance_number parameter not specified
After using the thread pool for so long, do you really know how to reasonably configure the number of threads?
Tablespace creation management and control file management
C language log base zlog basic use
[OBS] configFile in ini format of OBS
[proteus simulation] 16 channel water lamp composed of 74hc154 four wire to 12 wire decoder
FL Studio 20无限试用版水果编曲下载
Oracle 11g single machine cold standby database
2022 东北四省赛 VP记录/补题
[OBS] encapsulate the basic process of OBS acquisition
高精度室内定位技术,在智慧工厂安全管理的应用
Solve undefined reference to`__ aeabi_ Uidivmod 'and undefined reference to`__ aeabi_ Uidiv 'error
软考中级软件设计师该怎么备考
机器学习 3.2 决策树模型 学习笔记(待补)
C语言日志库zlog基本使用
Using onvif protocol to operate the device
CSRF
反正切熵(Arctangent entropy):2022.7月最新SCI论文