路溱微TCBP001TA-Y数字式气压计说明书和应用介绍

      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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值