当前位置:网站首页>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
边栏推荐
- C language AES encryption and decryption
- 英特尔13代酷睿旗舰曝光,单核5.5GHz
- 如何让让别人畏惧你
- A simple method of adding dividing lines in recyclerview
- AMS series - application startup process
- 软件测试周刊(第78期):你对未来越有信心,你对现在越有耐心。
- Matlab extracts numerical data from irregular txt files (simple and practical)
- repo ~ 常用命令
- Application of high-precision indoor positioning technology in safety management of smart factory
- 2022 东北四省赛 VP记录/补题
猜你喜欢
反正切熵(Arctangent entropy):2022.7月最新SCI论文
A simple method of adding dividing lines in recyclerview
ASP.NET-酒店管理系統
如何清理v$rman_backup_job_details视图 报错ORA-02030
Expandablelistview that can expand and shrink (imitating the list page of professional selection of Zhilian recruitment)
面試題總結(2) IO模型,集合,NIO 原理,緩存穿透,擊穿雪崩
ASP. Net hotel management system
Numpy np.max和np.maximum实现relu函数
php服务器 与redis交互大量CLOSE_WAIT分析
机器学习 3.2 决策树模型 学习笔记(待补)
随机推荐
在腾讯云容器服务Node上执行 kubectl
(二)进制
The element form shows the relationship between elementary transformation and elementary matrix
[vtk] source code interpretation of vtkpolydatatoimagestencil
Encapsulation attempt of network request framework of retro + kotlin + MVVM
[OBS] encapsulate the basic process of OBS acquisition
Solicitation for JGG special issue: spatio-temporal omics
Inexplicable problems in the nesting of constraintlayout and relativelayout
MATLAB提取不规则txt文件中的数值数据(简单且实用)
Google Earth engine (GEE) - ghsl global population grid dataset 250 meter resolution
After using the thread pool for so long, do you really know how to reasonably configure the number of threads?
面试题总结(2) IO模型,集合,NIO 原理,缓存穿透,击穿雪崩
如何成为一名高级数字 IC 设计工程师(1-4)Verilog 编码语法篇:表达式
Function details of CorelDRAW graphics suite 2022
活动预告 | 直播行业“内卷”,以产品力拉动新的数据增长点
C语言二维数组
Arctangent entropy: the latest SCI paper in July 2022
MATLAB提取不規則txt文件中的數值數據(簡單且實用)
Oracle 11g single machine cold standby database
AMS series - application startup process