歌尔SPA06-003气压传感器介绍和应用

The SPA06-003 is a miniaturized Digital Barometric Air Pressure Sensor with a high accuracy and a low current consumption. The SPA06-003 is both a pressure and a temperature sensor. The pressure sensor element is based on a capacitive sensing principle which guarantees a high precision during temperature changes. The small package makes the SPA06-003 ideal for mobile applications and wearable devices.
The SPA06-003‘s internal signal processor converts the output from the pressure and temperature sensor elements to 24-bit results. Each pressure sensor has been calibrated individually and contains calibration coefficients. The coefficients are used in the application to convert the measurement results to true pressure and temperature values.
The SPA06-003 has a FIFO that can store the latest 32 measurements. By using the FIFO, the host processor can remain in a sleep mode for a longer period of time between readouts. This can reduce the overall system power consumption. Sensor measurements and calibration coefficients are available through the serial I2C or SPI interface.

Key features
 Pressure range: 300 ... 1100hPa (+9000m ... -500m relating to sea level)
 Temperature Range: -40…+85°C
 Supply voltage: 1.7 ... 3.6V (VDD), 1.08... 3.6V (VDDIO)
 Package: LGA package with metal lid

Small footprint: 2.0mm x 2.5mm; Super-flat:0.95mm
 Relative accuracy: typ.±0.03hPa, equiv. to ±0.25 m
 Absolute accuracy: typ. ±0.3hPa (300 … 1100hPa)
 Temperature accuracy: typ. ± 1°C.
 Pressure temperature sensitivity: typ. 0.5Pa/K
 Measurement time: 3.6ms for low precision mode
 Average current consumption: 1.7 μA for pressure measurement,1.5 μA for temperature

measurement at 1Hz sampling rate, 1x oversampling rate, Standby: 0.5 μA
 I2C and SPI interface, Embedded 24-bit ADC
 FIFO: Stores latest 32 pressure or temperature measurements
 Pb-free, halogen-free and RoHS compliant
 MSL 1

Typical applications
 Enhancement of GPS navigation (dead-reckoning, slope detection, etc.)
 In-door and out-door navigation
 Leisure and sports
 Weather forecast
 Vertical velocity indication (rise/sink speed)

Specific notes
Particles can influence the performance of the pressure sensor, we strongly recommend you to introduce special measures to avoid deposition of particles on the MEMS membrane or screen particles after assembly as the assembly process is considered to be the main root cause for particle generation.

/*******************************************************************************
* Copyright (C), 2000-2016,  Electronic Technology Co., Ltd.
* FileName: SPL07_01.c
* Author: Li.wen
* Version:
* Date: 2015-11-30     
* Description:Define the operation interface of SPL07-01
* History:
*    1. Date: 2015-11-30
*       Author: Li.wen
*       Modification: create
*    2. Date:2016-10-12
		Author:lan.xing
		Modification:modified the calibrate coefficient
* Others:           
*******************************************************************************/
#ifndef SPL07_003_C
#define SPL07_003_C

#include "spl07_003.h"
#include "SoftwareI2C.h"

static struct spl07_003_t spl07_003;
static struct spl07_003_t *p_spl07_003;

void spl07_003_write(uint8 hwadr, uint8 regadr, uint8 val);
uint8 spl07_003_read(uint8 hwadr, uint8 regadr);
void spl07_003_get_calib_param(void);

/*****************************************************************************
 Function: spl07_003_write
 Description: this function will write data to specofic register through software I2C bus
 Input:  uint8 hwadr   hardware I2C address
         uint8 regadr  register address
         uint8 val     write-in value          
 Output: 
 Return: 
 Calls: 
 Called By: 
*****************************************************************************/
void spl07_003_write(uint8 hwadr, uint8 regadr, uint8 val)
{
    SoftI2C_start();
    SoftI2C_write_byte(hwadr << 1);
    SoftI2C_write_byte(regadr);
    SoftI2C_write_byte(val);
    SoftI2C_stop();
}

/*****************************************************************************
 Function: spl07_003_read
 Description: this function will read register data through software I2C bus
 Input: uint8 hwadr   hardware I2C address
        uint8 regadr  register address        
 Output: 
 Return: uint8 readout value
 Calls: 
 Called By: 
*****************************************************************************/
uint8 spl07_003_read(uint8 hwadr, uint8 regadr)
{
    uint8 val = 0;
    SoftI2C_start();
    SoftI2C_write_byte(hwadr << 1);
    SoftI2C_write_byte(regadr);
    SoftI2C_start();
    SoftI2C_write_byte((hwadr << 1)|0x01);
    val = SoftI2C_read_byte(1);
    SoftI2C_stop();
    return val;
}

void read_chip_id(void)
{
	p_spl07_003->chip_id =	spl07_003_read(HW_ADR, 0x0D);
	printf("check chip id =0x%x\n",p_spl07_003->chip_id);
}

uint8 is_spl07_003(void)
{ 
	if(p_spl07_003->chip_id == 0x11)
		return 1;
	else
		return 0;			
}

/*****************************************************************************
 Function: spl07_003_init
 Description: initialization
 Input: void             
 Output: 
 Return: void 
 Calls: 
 Called By: 
*****************************************************************************/
void spl07_003_init(void)
{
    p_spl07_003 = &spl07_003; /* read Chip Id */
    p_spl07_003->i32rawPressure = 0;
    p_spl07_003->i32rawTemperature = 0;
   // p_spl07_003->chip_id = 0x11;
	read_chip_id();

    spl07_003_get_calib_param();
    // sampling rate = 1Hz; Pressure oversample = 2;
    spl07_003_rateset(PRESSURE_SENSOR,32, 8);   
    // sampling rate = 1Hz; Temperature oversample = 1; 
    spl07_003_rateset(TEMPERATURE_SENSOR,32, 8);
    //Start background measurement
    
}

/*****************************************************************************
 Function: spl07_003_rateset
 Description: set sample rate and over sample rate per second for specific sensor
 Input:     uint8 u8OverSmpl  oversample rate         Maximal = 128
            uint8 u8SmplRate  sample rate(Hz) Maximal = 128
            uint8 iSensor     0: Pressure; 1: Temperature 
 Output: 
 Return: void
 Calls: 
 Called By: 
*****************************************************************************/
void spl07_003_rateset(uint8 iSensor, uint8 u8SmplRate, uint8 u8OverSmpl)
{
    uint8 reg = 0;
    int32 i32kPkT = 0;
    switch(u8SmplRate)
    {
        case 2:
            reg |= (1<<4);
            break;
        case 4:
            reg |= (2<<4);
            break;
        case 8:
            reg |= (3<<4);
            break;
        case 16:
            reg |= (4<<4);
            break;
        case 32:
            reg |= (5<<4);
            break;
        case 64:
            reg |= (6<<4);
            break;
        case 128:
            reg |= (7<<4);
            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 == PRESSURE_SENSOR)
    {
        p_spl07_003->i32kP = i32kPkT;
        spl07_003_write(HW_ADR, 0x06, reg);
        if(u8OverSmpl > 8)
        {
            reg = spl07_003_read(HW_ADR, 0x09);
            spl07_003_write(HW_ADR, 0x09, reg | 0x04);
        }
        else
        {
            reg = spl07_003_read(HW_ADR, 0x09);
            spl07_003_write(HW_ADR, 0x09, reg & (~0x04));
        }
    }
    if(iSensor == TEMPERATURE_SENSOR)
    {
        p_spl07_003->i32kT = i32kPkT;
		if(is_spl07_003())
        	spl07_003_write(HW_ADR, 0x07, reg); 
		else
			spl07_003_write(HW_ADR, 0x07, reg|0x80);  //Using mems temperature	
        if(u8OverSmpl > 8)
        {
            reg = spl07_003_read(HW_ADR, 0x09);
            spl07_003_write(HW_ADR, 0x09, reg | 0x08);
        }
        else
        {
            reg = spl07_003_read(HW_ADR, 0x09);
            spl07_003_write(HW_ADR, 0x09, reg & (~0x08));
        }
    }

}

/*****************************************************************************
 Function: spl07_003_get_calib_param
 Description: obtain the calibrated coefficient
 Input: void     
 Output: 
 Return: void
 Calls: 
 Called By: 
*****************************************************************************/
void spl07_003_get_calib_param(void)
{
    uint8 h;
    uint8 m;
    uint8 l;
    h =  spl07_003_read(HW_ADR, 0x10);
    l  =  spl07_003_read(HW_ADR, 0x11);
    p_spl07_003->calib_param.c0 = (int16)h<<4 | l>>4;
    p_spl07_003->calib_param.c0 = (p_spl07_003->calib_param.c0&0x0800)?(0xF000|p_spl07_003->calib_param.c0):p_spl07_003->calib_param.c0;
    h =  spl07_003_read(HW_ADR, 0x11);
    l  =  spl07_003_read(HW_ADR, 0x12);
    p_spl07_003->calib_param.c1 = (int16)(h&0x0F)<<8 | l;
    p_spl07_003->calib_param.c1 = (p_spl07_003->calib_param.c1&0x0800)?(0xF000|p_spl07_003->calib_param.c1):p_spl07_003->calib_param.c1;
    h =  spl07_003_read(HW_ADR, 0x13);
    m =  spl07_003_read(HW_ADR, 0x14);
    l =  spl07_003_read(HW_ADR, 0x15);
    p_spl07_003->calib_param.c00 = (int32)h<<12 | (int32)m<<4 | (int32)l>>4;
    p_spl07_003->calib_param.c00 = (p_spl07_003->calib_param.c00&0x080000)?(0xFFF00000|p_spl07_003->calib_param.c00):p_spl07_003->calib_param.c00;
    h =  spl07_003_read(HW_ADR, 0x15);
    m =  spl07_003_read(HW_ADR, 0x16);
    l =  spl07_003_read(HW_ADR, 0x17);
    p_spl07_003->calib_param.c10 = (int32)(h&0x0F)<<16 | (int32)m<<8 | l;
    p_spl07_003->calib_param.c10 = (p_spl07_003->calib_param.c10&0x080000)?(0xFFF00000|p_spl07_003->calib_param.c10):p_spl07_003->calib_param.c10;
    h =  spl07_003_read(HW_ADR, 0x18);
    l  =  spl07_003_read(HW_ADR, 0x19);
    p_spl07_003->calib_param.c01 = (int16)h<<8 | l;
    h =  spl07_003_read(HW_ADR, 0x1A);
    l  =  spl07_003_read(HW_ADR, 0x1B);
    p_spl07_003->calib_param.c11 = (int16)h<<8 | l;
    h =  spl07_003_read(HW_ADR, 0x1C);
    l  =  spl07_003_read(HW_ADR, 0x1D);
    p_spl07_003->calib_param.c20 = (int16)h<<8 | l;
    h =  spl07_003_read(HW_ADR, 0x1E);
    l  =  spl07_003_read(HW_ADR, 0x1F);
    p_spl07_003->calib_param.c21 = (int16)h<<8 | l;
    h =  spl07_003_read(HW_ADR, 0x20);
    l  =  spl07_003_read(HW_ADR, 0x21);
    p_spl07_003->calib_param.c30 = (int16)h<<8 | l;
	if(is_spl07_003())
	{
	    h = spl07_003_read(HW_ADR, 0x22);
	    l = spl07_003_read(HW_ADR, 0x23);
	    p_spl07_003->calib_param.c31 = (int16)h << 4 | l >> 4;
	    p_spl07_003->calib_param.c31 = (p_spl07_003->calib_param.c31 & 0x0800) ? (0xF000 | p_spl07_003->calib_param.c31) : p_spl07_003->calib_param.c31;
	    h = spl07_003_read(HW_ADR, 0x23);
	    l = spl07_003_read(HW_ADR, 0x24);
	    p_spl07_003->calib_param.c40 = (int16)(h & 0x0F) << 8 | l;
	    p_spl07_003->calib_param.c40 = (p_spl07_003->calib_param.c40 & 0x0800) ? (0xF000 | p_spl07_003->calib_param.c40) : p_spl07_003->calib_param.c40;
	}
}

/*****************************************************************************
 Function: spl07_003_start_temperature
 Description: start one measurement for temperature
 Input: void    
 Output: 
 Return: void
 Calls: 
 Called By: 
*****************************************************************************/
void spl07_003_start_temperature(void)
{
    spl07_003_write(HW_ADR, 0x08, 0x02);
}

/*****************************************************************************
 Function: spl07_003_start_pressure
 Description: start one measurement for pressure
 Input: void       
 Output: 
 Return: void
 Calls: 
 Called By: 
*****************************************************************************/

void spl07_003_start_pressure(void)
{
    spl07_003_write(HW_ADR, 0x08, 0x01);
}
/*****************************************************************************
 Function: spl07_003_start_continuous
 Description: Select mode for the continuously measurement
 Input: uint8 mode  1: pressure; 2: temperature; 3: pressure and temperature        
 Output: 
 Return: void
 Calls: 
 Called By: 
*****************************************************************************/
void spl07_003_start_continuous(uint8 mode)
{
    spl07_003_write(HW_ADR, 0x08, mode+4);
}

void spl07_003_stop(void)
{
    spl07_003_write(HW_ADR, 0x08, 0);
}

/*****************************************************************************
 Function: spl07_003_get_raw_temp
 Description:obtain the original temperature value and turn them into 32bits-integer 
 Input: void          
 Output: 
 Return: void
 Calls: 
 Called By: 
*****************************************************************************/
void spl07_003_get_raw_temp(void)
{
    uint8 h,m,l;
    SoftI2C_start();
    SoftI2C_write_byte(HW_ADR << 1);
    SoftI2C_write_byte(0x03);
    SoftI2C_start();
    SoftI2C_write_byte((HW_ADR << 1)|0x01);
    h = SoftI2C_read_byte(0);
    m = SoftI2C_read_byte(0);
    l = SoftI2C_read_byte(1);
    SoftI2C_stop();
    p_spl07_003->i32rawTemperature = (int32)h<<16 | (int32)m<<8 | (int32)l;
    p_spl07_003->i32rawTemperature= (p_spl07_003->i32rawTemperature&0x800000) ? (0xFF000000|p_spl07_003->i32rawTemperature) : p_spl07_003->i32rawTemperature;
}

/*****************************************************************************
 Function: spl07_003_get_raw_pressure
 Description: obtain the original pressure value and turn them into 32bits-integer
 Input: void       
 Output: 
 Return: void
 Calls: 
 Called By: 
*****************************************************************************/
void spl07_003_get_raw_pressure(void)
{
    uint8 h,m,l;
    SoftI2C_start();
    SoftI2C_write_byte(HW_ADR << 1);
    SoftI2C_write_byte(0x00);
    SoftI2C_start();
    SoftI2C_write_byte((HW_ADR << 1)|0x01);
    h = SoftI2C_read_byte(0);
    m = SoftI2C_read_byte(0);
    l = SoftI2C_read_byte(1);
    SoftI2C_stop();
    
    p_spl07_003->i32rawPressure = (int32)h<<16 | (int32)m<<8 | (int32)l;
    p_spl07_003->i32rawPressure= (p_spl07_003->i32rawPressure&0x800000) ? (0xFF000000|p_spl07_003->i32rawPressure) : p_spl07_003->i32rawPressure;
}

/*****************************************************************************
 Function: spl07_003_get_temperature
 Description:  return calibrated temperature value base on original value.
 Input: void          
 Output: 
 Return: void
 Calls: 
 Called By: 
*****************************************************************************/
float spl07_003_get_temperature(void)
{
    float fTCompensate;
    float fTsc;

    fTsc = p_spl07_003->i32rawTemperature / (float)p_spl07_003->i32kT;
    fTCompensate =  p_spl07_003->calib_param.c0 * 0.5 + p_spl07_003->calib_param.c1 * fTsc;
    return fTCompensate;
}

/*****************************************************************************
 Function: spl07_003_get_pressure
 Description: return calibrated pressure value base on original value.
 Input: void            
 Output: 
 Return: void
 Calls: 
 Called By: 
*****************************************************************************/

float spl07_003_get_pressure(void)
{
    float fTsc, fPsc;
    float qua2, qua3;
    float fPCompensate;

    fTsc = p_spl07_003->i32rawTemperature / (float)p_spl07_003->i32kT;
    fPsc = p_spl07_003->i32rawPressure / (float)p_spl07_003->i32kP;
    qua2 = p_spl07_003->calib_param.c10 + fPsc * (p_spl07_003->calib_param.c20 + fPsc* (p_spl07_003->calib_param.c30+ fPsc * p_spl07_003->calib_param.c40));
    if(is_spl07_003())
		qua3 = fTsc * fPsc * (p_spl07_003->calib_param.c11 + fPsc * (p_spl07_003->calib_param.c21+ fPsc * p_spl07_003->calib_param.c31));
	else
		qua3 = fTsc * fPsc * (p_spl07_003->calib_param.c11 + fPsc * p_spl07_003->calib_param.c21);
    fPCompensate = p_spl07_003->calib_param.c00 + fPsc * qua2 + fTsc * p_spl07_003->calib_param.c01 + qua3;
    return fPCompensate;
}




#endif
#ifndef SPL07_003_H
#define SPL07_003_H
#include "hal_board_cfg.h"

#define HW_ADR 0x77
#define CONTINUOUS_PRESSURE     1
#define CONTINUOUS_TEMPERATURE  2
#define CONTINUOUS_P_AND_T      3
#define PRESSURE_SENSOR     0
#define TEMPERATURE_SENSOR  1


struct spl07_003_calib_param_t {	
    int16 c0;
    int16 c1;
    int32 c00;
    int32 c10;
    int16 c01;
    int16 c11;
    int16 c20;
    int16 c21;
    int16 c30;
    int16 c31;
    int16 c40;
};

struct spl07_003_t {	
    struct spl07_003_calib_param_t calib_param;/**<calibration data*/	
    uint8 chip_id; /**<chip id*/	
    int32 i32rawPressure;
    int32 i32rawTemperature;
    int32 i32kP;    
    int32 i32kT;
};

void spl07_003_init(void);
void spl07_003_rateset(uint8 iSensor, uint8 u8OverSmpl, uint8 u8SmplRate);
void spl07_003_start_temperature(void);
void spl07_003_start_pressure(void);
void spl07_003_start_continuous(uint8 mode);
void spl07_003_get_raw_temp(void);
void spl07_003_get_raw_pressure(void);
float spl07_003_get_temperature(void);
float spl07_003_get_pressure(void);

#endif

详情私信咨询

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值