TCBP001TA-Y 是一个高精度、低功耗的小型化数字式气压传感器产品。TCBP001TA-Y 既是压力传感器又是温度传感器。压力传感元件基于电容式感应原理,确保温度变化时的高精度。小巧的封装使TCBP001TA-Y
对于移动应用及可穿戴装置非常理想。
TCBP001TA-Y
的内部信号处理器将压力和温度传感元件的输出转化为24 位的结果。每一个压力传感器都单独校准过并且包含了校准系数,校准系数在应用中被用于将测量结果转化为真实的压力和温度值。
TCBP001TA-Y
有一个能够储存最近 32 组测量值的FIFO 寄存器。通过使用FIFO, 主机可以在两次读取之间在睡眠模式维持较长时间,这样可以降低整体系统功耗。传感器测量值及校准系数可以通过串行 I2
C 接口或 SPI 接口获取。
功能特征
•
工作范围: 压力
: 300 – 1200 hPa. 温度: -40 – 85 °C.
•
压力传感器精确度
:
± 0.006 hPa (or ±5 cm) (高精度模式).
•
压力传感器精度:
± 0.06 hPa (or ±50 cm) (非线性), ±1 hPa (or ±8 m) (绝对精度).
•
温度精度:
± 0.5°C.
•
压力的温度敏感系数:
< 0.5Pa/K
•
测量时间:
典型值
:
28 ms. 最小值: 3 ms.
•
平均电流消耗:
高精度模式: 60 µA, 低功耗模式: 3 µA, 待机模式: <1 µA.
•
工作电压:
VDDIO: 1.2 – 3.6 V, VDD: 1.7 – 3.6 V.
•
工作模式
:
命令模式(手动)、后台模式 (自动)及待机模式
•
校准
:
单独校准的系数用作测量结果校正
•
FIFO:
储存最近的 32 组压力或温度测量结果
•
接口
:
I
2
C 和 SPI (都带中断可选)
•
封装尺寸
:
8-pin LGA, 2.0 mm x 2.5 mm x 1.0 mm.
典型应用
•
室内导航
(楼层检测,如商场、停车场)
•
运动健康
(精确的抬升高度及垂直速度获取)
•
室外导航
(GPS 启动时间及精度提升、航迹推算,如隧道中)
•
气象站
(局部微气象预测)
#include "SPL06_01.h"
#if (BAROMETER_MODEL == SPL0601)
#define CONTINUOUS_PRESSURE 1
#define CONTINUOUS_TEMPERATURE 2
#define CONTINUOUS_P_AND_T 3
#define PRESSURE_SENSOR 0
#define TEMPERATURE_SENSOR 1
enum
{
START_PRESS_CONVERT = 0,
READ_PRESS_DATA,
START_TEMP_CONVERT,
READ_TEMP_DATA
};
#define BARO_VERIFY_ID_REPEAT_TIMES 100
//Luqing-TCBP001MB & goertek-SPL06-001 'S ID is 0x10
#define SPL06_01_TCBP001MB_ID 0X10
uint8_t baro_raw_buf[6];
E_BAROMETERSTATUS barometerStatus = BARO_UNINIT;
struct spl0601_calib_param_t {
int16_t c0;
int16_t c1;
int32_t c00;
int32_t c10;
int16_t c01;
int16_t c11;
int16_t c20;
int16_t c21;
int16_t c30;
};
struct spl0601_t {
struct spl0601_calib_param_t calib_param;/**<calibration data*/
uint8_t chip_id; /**<chip id*/
int32_t i32rawPressure;
int32_t i32rawTemperature;
int32_t i32kP;
int32_t i32kT;
};
struct spl0601_t spl0601;
void spl0601_write(uint8_t regadr, uint8_t val);
uint8_t spl0601_read(uint8_t regadr);
void spl0601_get_calib_param(void);
/*****************************************************************************
函 数 名 : spl0601_write
功能描述 : I2C 寄存器写入子函数
输入参数 : uint8_t hwadr 硬件地址
uint8_t regadr 寄存器地址
uint8_t val 值
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2015年11月30日
作 者 : WL
修改内容 : 新生成函数
*****************************************************************************/
void spl0601_write(uint8_t regadr, uint8_t val)
{
iic_start_send_1byte(SPL0601_IIC_ADR,regadr,val,NULL,NULL);
delay_ms(1);
}
/*****************************************************************************
函 数 名 : spl0601_read
功能描述 : I2C 寄存器读取子函数
输入参数 : uint8_t hwadr 硬件地址
uint8_t regadr 寄存器地址
输出参数 :
返 回 值 : uint8_t 读出值
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2015年11月30日
作 者 : WL
修改内容 : 新生成函数
*****************************************************************************/
uint8_t spl0601_read(uint8_t regadr)
{
uint8_t val = 0;
iic_start_read_bytes(SPL0601_IIC_ADR,regadr,&val,1,NULL,NULL);
delay_ms(1);
return val;
}
/*****************************************************************************
函 数 名 : spl0601_init
功能描述 : SPL06-01 初始化函数
输入参数 : void
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2015年11月30日
作 者 : WL
修改内容 : 新生成函数
*****************************************************************************/
void spl0601_init(void)
{
uint8_t sig;
uint8_t i = 0;
uint8_t reg;
spl0601.i32rawPressure = 0;
spl0601.i32rawTemperature = 0;
spl0601.chip_id = 0x34;
#ifdef SPL06_01_TCBP001MB_ID
barometerStatus = BARO_INITFAIL;
do
{
sig = spl0601_read(0x0D);
if (sig == SPL06_01_TCBP001MB_ID)
{
barometerStatus = BARO_INITOK;
break;
}
} while(i++ < BARO_VERIFY_ID_REPEAT_TIMES);
#else
barometerStatus = BARO_INITOK;
#endif
spl0601_get_calib_param();
// sampling rate = 1Hz; Pressure oversample = 2;
// 验证气压计是否初始化完成
#if 0
sig = spl0601_read(SPL0601_IIC_ADR, 0x08);
while ((sig&0xC0)==0)
{
delay_ms(10);
sig = spl0601_read(SPL0601_IIC_ADR, 0x08);
}
#endif
/* Now apply ADC Temperature gain settings*/
/* First write valid signature on 0x0e and 0x0f
* to unlock address 0x62 */
spl0601_write(0x0e, 0xa5);
spl0601_write(0x0f, 0x96);
/*Then update high gain value for Temperature*/
spl0601_write(0x62, 0x02);
/*Finally lock back the location 0x62*/
spl0601_write(0x0e, 0x00);
spl0601_write(0x0f, 0x00);
//spl0601_rateset(PRESSURE_SENSOR,32, 16);
spl0601.i32kP = 253952;
spl0601_write(0x06, 0xA4);
//if(u8OverSmpl > 8)
//{
reg = spl0601_read(0x09);
spl0601_write(0x09, reg | 0x04);
//}
// sampling rate = 1Hz; Temperature oversample = 1;
//spl0601_rateset(TEMPERATURE_SENSOR,32, 4); //32/4
spl0601.i32kT = 3670016;
spl0601_write(0x07, 0xA2|0x80); //Using mems temperature
//if(u8OverSmpl > 8)
//{
// reg = spl0601_read(0x09);
// spl0601_write(0x09, reg | 0x08);
//}
//Start background measurement
//spl0601_start_continuous(CONTINUOUS_P_AND_T);
}
/*****************************************************************************
函 数 名 : spl0601_rateset
功能描述 : 设置温度传感器的每秒采样次数以及过采样率
输入参数 : uint8_t u8OverSmpl 过采样率 Maximal = 128
uint8_t u8SmplRate 每秒采样次数(Hz) Maximal = 128
uint8_t iSensor 0: Pressure; 1: Temperature
输出参数 : 无
返 回 值 : 无
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2015年11月24日
作 者 : WL
修改内容 : 新生成函数
*****************************************************************************/
void spl0601_rateset(uint8_t iSensor, uint8_t u8SmplRate, uint8_t u8OverSmpl)
{
uint8_t reg = 0;
int32_t i32kPkT = 0;
switch(u8SmplRate)
{
case 2:
reg |= (1<<5);
break;
case 4:
reg |= (2<<5);
break;
case 8:
reg |= (3<<5);
break;
case 16:
reg |= (4<<5);
break;
case 32:
reg |= (5<<5);
break;
case 64:
reg |= (6<<5);
break;
case 128:
reg |= (7<<5);
break;
case 1:
default:
break;
}
switch(u8OverSmpl)
{
case 2:
reg |= 1;
i32kPkT = 1572864;
break;
case 4:
reg |= 2;
i32kPkT = 3670016;
break;
case 8:
reg |= 3;
i32kPkT = 7864320;
break;
case 16:
i32kPkT = 253952;
reg |= 4;
break;
case 32:
i32kPkT = 516096;
reg |= 5;
break;
case 64:
i32kPkT = 1040384;
reg |= 6;
break;
case 128:
i32kPkT = 2088960;
reg |= 7;
break;
case 1:
default:
i32kPkT = 524288;
break;
}
if(iSensor == 0)
{
spl0601.i32kP = i32kPkT;
spl0601_write(0x06, reg);
if(u8OverSmpl > 8)
{
reg = spl0601_read(0x09);
spl0601_write(0x09, reg | 0x04);
}
}
if(iSensor == 1)
{
spl0601.i32kT = i32kPkT;
spl0601_write(0x07, reg|0x80); //Using mems temperature
if(u8OverSmpl > 8)
{
reg = spl0601_read(0x09);
spl0601_write(0x09, reg | 0x08);
}
}
}
/*****************************************************************************
函 数 名 : spl0601_get_calib_param
功能描述 : 获取校准参数
输入参数 : void
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2015年11月30日
作 者 : WL
修改内容 : 新生成函数
*****************************************************************************/
void spl0601_get_calib_param(void)
{
uint32_t h;
uint32_t m;
uint32_t l;
h = spl0601_read(0x10);
l = spl0601_read(0x11);
spl0601.calib_param.c0 = (int16_t)h<<4 | l>>4;
spl0601.calib_param.c0 = (spl0601.calib_param.c0&0x0800)?(0xF000|spl0601.calib_param.c0):spl0601.calib_param.c0;
h = spl0601_read(0x11);
l = spl0601_read(0x12);
spl0601.calib_param.c1 = (int16_t)(h&0x0F)<<8 | l;
spl0601.calib_param.c1 = (spl0601.calib_param.c1&0x0800)?(0xF000|spl0601.calib_param.c1):spl0601.calib_param.c1;
h = spl0601_read(0x13);
m = spl0601_read(0x14);
l = spl0601_read(0x15);
spl0601.calib_param.c00 = (int32_t)h<<12 | (int32_t)m<<4 | (int32_t)l>>4;
spl0601.calib_param.c00 = (spl0601.calib_param.c00&0x080000)?(0xFFF00000|spl0601.calib_param.c00):spl0601.calib_param.c00;
h = spl0601_read(0x15);
m = spl0601_read(0x16);
l = spl0601_read(0x17);
spl0601.calib_param.c10 = (int32_t)h<<16 | (int32_t)m<<8 | l;
spl0601.calib_param.c10 = (spl0601.calib_param.c10&0x080000)?(0xFFF00000|spl0601.calib_param.c10):spl0601.calib_param.c10;
h = spl0601_read(0x18);
l = spl0601_read(0x19);
spl0601.calib_param.c01 = (int16_t)h<<8 | l;
h = spl0601_read(0x1A);
l = spl0601_read(0x1B);
spl0601.calib_param.c11 = (int16_t)h<<8 | l;
h = spl0601_read(0x1C);
l = spl0601_read(0x1D);
spl0601.calib_param.c20 = (int16_t)h<<8 | l;
h = spl0601_read(0x1E);
l = spl0601_read(0x1F);
spl0601.calib_param.c21 = (int16_t)h<<8 | l;
h = spl0601_read(0x20);
l = spl0601_read(0x21);
spl0601.calib_param.c30 = (int16_t)h<<8 | l;
}
void Baro_Read_End(void);
/*****************************************************************************
函 数 名 : spl0601_start_temperature
功能描述 : 发起一次温度测量
输入参数 : void
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2015年11月30日
作 者 : WL
修改内容 : 新生成函数
*****************************************************************************/
void spl0601_start_temperature(void)
{
iic_start_send_1byte(SPL0601_IIC_ADR,0x08,0x02,NULL,NULL);
}
/*****************************************************************************
函 数 名 : spl0601_start_pressure
功能描述 : 发起一次压力值测量
输入参数 : void
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2015年11月30日
作 者 : WL
修改内容 : 新生成函数
*****************************************************************************/
void spl0601_start_pressure(void)
{
iic_start_send_1byte(SPL0601_IIC_ADR,0x08,0x01,NULL,NULL);
}
/*****************************************************************************
函 数 名 : spl0601_start_continuous
功能描述 : Select node for the continuously measurement
输入参数 : uint8_t mode 1: pressure; 2: temperature; 3: pressure and temperature
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2015年11月25日
作 者 : WL
修改内容 : 新生成函数
*****************************************************************************/
void spl0601_start_continuous(uint8_t mode)
{
spl0601_write(0x08, mode+4);
}
void baro_read_finish_handle(void);
void spl0601_get_raw_data(void)
{
iic_start_read_bytes(SPL0601_IIC_ADR,0x00,&baro_raw_buf[0],6,baro_read_finish_handle,NULL);
}
void spl0601_get_raw_temp(void)
{
iic_start_read_bytes(SPL0601_IIC_ADR,0x03,&baro_raw_buf[3],3,baro_read_finish_handle,NULL);
}
void spl0601_get_raw_baro(void)
{
iic_start_read_bytes(SPL0601_IIC_ADR,0x00,&baro_raw_buf[0],3,NULL,NULL);
}
/*****************************************************************************
函 数 名 : spl0601_get_temperature
功能描述 : 在获取原始值的基础上,返回浮点校准后的温度值
输入参数 : void
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2015年11月30日
作 者 : WL
修改内容 : 新生成函数
*****************************************************************************/
float spl0601_get_temperature(void)
{
float fTCompensate;
float fTsc;
fTsc = spl0601.i32rawTemperature / (float)spl0601.i32kT;
fTCompensate = spl0601.calib_param.c0 * 0.5 + spl0601.calib_param.c1 * fTsc;
return fTCompensate;
}
/*****************************************************************************
函 数 名 : spl0601_get_pressure
功能描述 : 在获取原始值的基础上,返回浮点校准后的压力值
输入参数 : void
输出参数 : 无
返 回 值 :
调用函数 :
被调函数 :
修改历史 :
1.日 期 : 2015年11月30日
作 者 : WL
修改内容 : 新生成函数
*****************************************************************************/
float fPCompensate;
float spl0601_get_pressure(void)
{
float fTsc, fPsc;
float qua2, qua3;
fTsc = spl0601.i32rawTemperature / (float)spl0601.i32kT;
fPsc = spl0601.i32rawPressure / (float)spl0601.i32kP;
qua2 = spl0601.calib_param.c10 + fPsc * (spl0601.calib_param.c20 + fPsc* spl0601.calib_param.c30);
qua3 = fTsc * fPsc * (spl0601.calib_param.c11 + fPsc * spl0601.calib_param.c21);
fPCompensate = spl0601.calib_param.c00 + fPsc * qua2 + fTsc * spl0601.calib_param.c01 + qua3;
return fPCompensate;
}
void baro_read_finish_handle(void)
{
spl0601.i32rawTemperature = (int32_t)baro_raw_buf[3]<<16 | (int32_t)baro_raw_buf[4]<<8 | (int32_t)baro_raw_buf[5];
spl0601.i32rawTemperature = (spl0601.i32rawTemperature&0x800000) ? (0xFF000000|spl0601.i32rawTemperature) : spl0601.i32rawTemperature;
spl0601.i32rawPressure = (int32_t)baro_raw_buf[0]<<16 | (int32_t)baro_raw_buf[1]<<8 | (int32_t)baro_raw_buf[2];
spl0601.i32rawPressure= (spl0601.i32rawPressure&0x800000) ? (0xFF000000|spl0601.i32rawPressure) : spl0601.i32rawPressure;
barometerStatus = BARO_READOK;
}
uint32_t spl0601_time = 0;
void spl0601_Access(uint32_t cyc)
{
static uint8_t step = 0;
if(barometerStatus > BARO_UNINIT)
{
//if (barometerStatus == BARO_UNINIT)
// if (barometerStatus == BARO_READY)
// return ;
if(step>3) step = 0;
spl0601_time += cyc;
switch (step)
{
case START_TEMP_CONVERT:
spl0601_time = 0;
step ++;
barometerStatus = BARO_READING;
spl0601_start_temperature();
break;
case READ_TEMP_DATA:
if (spl0601_time >= READ_TEMP_TIME)
{
spl0601_time = 0;
step ++;
spl0601_get_raw_temp();
}
break;
case START_PRESS_CONVERT:
spl0601_time = 0;
step ++;
spl0601_start_pressure();
break;
case READ_PRESS_DATA:
if (spl0601_time >= READ_PRESS_TIME)
{
spl0601_time = 0;
step ++;
spl0601_get_raw_baro();
}
break;
}
}
}
E_BAROMETERSTATUS getBarometerSta(void)
{
return barometerStatus;
}
void setBarometerSta(E_BAROMETERSTATUS sta)
{
barometerStatus = sta;
}
#endif
#ifndef SPL06_01_H
#define SPL06_01_H
#include "main.h"
#if (BAROMETER_MODEL == SPL0601)
#define barometerInit spl0601_init
#define barometer_get_pressure spl0601_get_pressure
#define barometer_Access spl0601_Access
typedef enum
{
BARO_UNINIT = 0,
BARO_INITOK = 1,
BARO_INITFAIL = 2,
BARO_READY = 3,
BARO_READING = 4,
BARO_READOK = 5,
BARO_ERROR = 6
} E_BAROMETERSTATUS;
E_BAROMETERSTATUS getBarometerSta(void);
void setBarometerSta(E_BAROMETERSTATUS sta);
#define TEMP_OVERSAMP_NUM 4 //2/4
#if (TEMP_OVERSAMP_NUM == 2)
#define READ_TEMP_TIME 6000
#define READ_PRESS_TIME 28000
#else //4
#define READ_TEMP_TIME 9000
#define READ_PRESS_TIME 28000
#endif
//#define SPL0601_IIC_ADR (0x77<<1)
//#define SPL0601_IIC_ADR (0x76<<1)
//#define SPL0601_IIC_ADR 0x77
#define SPL0601_IIC_ADR 0x76
void spl0601_init(void);
float spl0601_get_temperature(void);
float spl0601_get_pressure(void);
void spl0601_Access(uint32_t cyc);
#endif
#endif