士兰微SC7A20H三轴加速度计介绍和应用

      SC7A20H 是一款高精度数字三轴加速度传感器芯片,内置功能更丰富,功耗更低,体积更小,测量更精确。芯片通过 I²C/SPI 接口与 MCU 通信,加速度测量数据以中断方式或 查询方式获取。INT1 INT2 中断管脚提供多种内部自动检测的中断信号,适应多种运动检测场合,中断源包括 6D/4D 方向检测中断信号、自由落体检测中断信号、睡眠和唤醒检测中断信号、单击和双击检测中断信号。
      芯片内置高精度校准模块,对传感器的失调误差和增益误差进行精确补偿。±2G 、± 4G 、± 8G 和± 16G 四种可调整的全量程测量范围,灵活测量外部加速度,输出数据率 1.56HZ 4.27kHz 间可选。芯片内置自测试功能允许客户系统测试时检测系统功能,省去复杂的转台测试。
主要特点:
宽电压范围 1.71V-3.6V
1.8V 兼容数字 IO
低功耗模式下电源电流低至 2µA@1.8V@1.56Hz
± 2G/ ± 4G/ ± 8G/ ± 16G 动态全量程范围
12bit 数据输出
  I²C/SPI 数字输出接口
  6D/4D 方向检测
自由落体检测
单击多击检测及运动检测
可编程中断生成电路
内嵌自测试功能
内嵌 FIFO
10000g G 抗击能力
应用:
手机平板
室内导航
图像旋转
运动激活用户接口
游戏
程序例程和晃动和角度检测算法

#include "SL_SC7A20H_Watch_Algorithm_driver.h"
#include "I2C.h"


#if SL_Sensor_Algo_Release_Enable==0x00
#include "usart.h"
#endif


//I2C SPI
#define SL_SC7A20H_SPI_EN_I2C_DISABLE  0x00
//
#define SL_SC7A20H_RAWDATA_HPF_ENABLE  0x00
//
#define SL_SC7A20H_INT_DEFAULT_LEVEL   0x01

#define SL_SC7A20H_FIFO_ENABLE   0x00  //0x00-FIFO-DISABLE  0x01-FIFO ENABLE

static void sl_delay(unsigned char sl_i)
{
    unsigned int sl_j = 10;

	sl_j = sl_j*1000*sl_i;
    while(sl_j--);
}


unsigned char SL_SC7A20H_Check(void)
{
	unsigned char reg_value1=0;
	unsigned char reg_value2=0;
	
	SL_SC7A20H_I2c_Spi_Read(1, SC7A20H_WHO_AM_I, 1, &reg_value1);
	SL_SC7A20H_I2c_Spi_Read(1, SC7A20H_VERSION, 1, &reg_value2);
	if((reg_value1==0x11)&&(reg_value2==0x28))	
		return 0x01;//SC7A20H
	else
		return 0x00;//others
}


unsigned char SL_SC7A20H_Config(void)
{
	unsigned char Check_Flag=0;

	Check_Flag=SL_SC7A20H_Check();
//	Check_Flag=1;//SC7A20H
	if(Check_Flag==1)
	{
		Check_Flag= SL_SC7A20H_POWER_DOWN();
	}
	if(Check_Flag==1)
	{
		Check_Flag= SL_SC7A20H_SOFT_RESET();
	}
	if(Check_Flag==1)
	{

		SL_SC7A20H_I2c_Spi_Write(1, 0x1F, 0x01);//hi-pwr mode
		SL_SC7A20H_I2c_Spi_Write(1, 0x23, 0x90);//±4g  high byte in lower addr DLPF open
		SL_SC7A20H_I2c_Spi_Write(1, 0x2E, 0x00);//BY-PASS MODE

#if SL_SC7A20H_RAWDATA_HPF_ENABLE ==0x01	
		SL_SC7A20H_I2c_Spi_Write(1, 0x21, 0x68);//rawdata hpf
#else
		SL_SC7A20H_I2c_Spi_Write(1, 0x21, 0x01);// rawdata hpf
#endif
 #if    SL_SC7A20H_FIFO_ENABLE ==0x00
		SL_SC7A20H_I2c_Spi_Write(1, 0x24, 0x80);//FIFO DISABLE
#else
		SL_SC7A20H_I2c_Spi_Write(1, 0x24, 0xC0);//FIFO ENABLE
#endif		
		SL_SC7A20H_I2c_Spi_Write(1, 0x22, 0x40);//AOI1-INT1
		SL_SC7A20H_I2c_Spi_Write(1, 0x30, 0x2A);//XYZ ENABLE
		SL_SC7A20H_I2c_Spi_Write(1, 0x32, 0x0A);//>32mg*10 碰撞检测幅度阈值
		SL_SC7A20H_I2c_Spi_Write(1, 0x33, 0x03);//>T*3 碰撞检测时间阈值
		
#if SL_SC7A20H_INT_DEFAULT_LEVEL ==0x01
		SL_SC7A20H_I2c_Spi_Write(1, 0x25, 0x02);//defalut high level&& push-pull
#else
		SL_SC7A20H_I2c_Spi_Write(1, 0x25, 0x00);//defalut low  level&& push-pull	
#endif

		
#if SL_SC7A20H_FIFO_MODE_ENABLE ==0x00
		SL_SC7A20H_I2c_Spi_Write(1, 0x2E, 0x9F);//stream mode and fth=0x0F
#endif
		sl_delay(1);
		SL_SC7A20H_I2c_Spi_Write(1, 0x20, 0x57);//100Hz hi-pwr mode
		sl_delay(10);

		SL_SC7A20H_I2c_Spi_Write(1,0x57, 0x00);//
		
		
		return 1;
	}
	else
		return 0;
}




// READ DATA
void SL_SC7A20H_RawData_Read(signed short *acc_data)
{
	unsigned char  raw_data[6];


	SL_SC7A20H_I2c_Spi_Read(1, 0xA8, 6, &raw_data[0]);

	acc_data[0] =(signed short)((raw_data[1] << 8) + raw_data[0]) >> 4;//12bit
	acc_data[1] =(signed short)((raw_data[3] << 8) + raw_data[2]) >> 4;//12bit
	acc_data[2] =(signed short)((raw_data[5] << 8) + raw_data[4]) >> 4;//12bit
}


// READ Angle
void SL_SC7A20H_RawAngle_Read(float* angle_data)
{
	signed short data[3];
	SL_SC7A20H_RawData_Read(data); 
	angle_data[0] = (float)data[0] / 1024;
	angle_data[1] = (float)data[1] / 1024;
	angle_data[2] = (float)data[2] / 1024;
	if (angle_data[0] > 1.0)    angle_data[0] = 1.0;
	if (angle_data[0] < -1.0)   angle_data[0] = -1.0;
	if (angle_data[1] > 1.0)    angle_data[1] = 1.0;
	if (angle_data[1] < -1.0)   angle_data[1] = -1.0;
	if (angle_data[2] > 1.0)    angle_data[2] = 1.0;
	if (angle_data[2] < -1.0)   angle_data[2] = -1.0;

	if (angle_data[2] != 0)
		roll = atanf(angle_data[1] / angle_data[2]) * 57.32484;
	else
		roll = 90;
	if (angle_data[1] != 0 || angle_data[2] != 0)
		pitch = -atanf(angle_data[0] / sqrt(angle_data[2] * angle_data[2] + angle_data[1] * angle_data[1])) * 57.32484;
	else
		pitch = 90;

	angle_data[0] = pitch;
	angle_data[1] = roll;

}

unsigned char  SL_SC7A20H_FIFO_DATA[192];
//FIFO READ
unsigned char SL_SC7A20H_FIFO_Read(signed short *x_data_buf,signed short *y_data_buf,signed short *z_data_buf)
{
	unsigned char  raw_data[6];
	unsigned char  fifo_num=0;
	unsigned char  fifo_len=0;
	unsigned char  i,j;
	unsigned short fifo_cnt=0;
#if SL_SC7A20H_FIFO_MODE_ENABLE ==0x00
	SL_SC7A20H_I2c_Spi_Write(1, 0x22, 0x00);
	#else
	SL_SC7A20H_I2c_Spi_Write(1, 0x22, 0x01);
#endif
		SL_SC7A20H_I2c_Spi_Read(1, 0x2F,1,&fifo_num);
  	fifo_num = fifo_num&0x3F;
	
#if SL_SC7A20H_FIFO_MODE_ENABLE ==0x00
	fifo_len=fifo_num*6;//XYZ,*6
	#else
	fifo_len=fifo_num*3;//XYZ,*3
#endif
	


	if(fifo_len>255)
		fifo_len=255;

#if SL_SC7A20H_FIFO_MODE_ENABLE ==0x00
	SL_SC7A20H_I2c_Spi_Read(1, 0x69, fifo_len,SL_SC7A20H_FIFO_DATA);//
	for(j=0;j<fifo_num;j++)
	{
		x_data_buf[j] =(signed short)((SL_SC7A20H_FIFO_DATA[j*6]<<8)+SL_SC7A20H_FIFO_DATA[j*6+1])>>4;//12bit
		y_data_buf[j] =(signed short)((SL_SC7A20H_FIFO_DATA[j*6+2]<<8)+SL_SC7A20H_FIFO_DATA[j*6+3])>>4;//12bit
		z_data_buf[j] =(signed short)((SL_SC7A20H_FIFO_DATA[j*6+4]<<8)+SL_SC7A20H_FIFO_DATA[j*6+5])>>4;//12bit

#else
	SL_SC7A20H_I2c_Spi_Read(1, 0x69, fifo_len,SL_SC7A20H_FIFO_DATA);
	for(j=0;j<fifo_num;j++)
	{
		x_data_buf[j] =(signed char)SL_SC7A20H_FIFO_DATA[0+j*3];//8bit
		y_data_buf[j] =(signed char)SL_SC7A20H_FIFO_DATA[1+j*3];//8bit
		z_data_buf[j] =(signed char)SL_SC7A20H_FIFO_DATA[2+j*3];//8bit
	}
#endif
	SL_SC7A20H_I2c_Spi_Write(1, 0x2E, 0x00);//BY PASS MODE			
	SL_SC7A20H_I2c_Spi_Write(1, 0x2E, 0x9F);//FIFO MODE
	return fifo_num;
}


unsigned char SL_SC7A20H_POWER_DOWN(void)
{
	unsigned char SL_Read_Reg  = 0xff;
	
	SL_SC7A20H_I2c_Spi_Write(1, 0x20, 0x00);//POWER DOWN
	SL_SC7A20H_I2c_Spi_Read(1, 0x20, 1,&SL_Read_Reg);//close aoi1 function
	if(SL_Read_Reg==0x00)   return  1;
	else                    return  0;
}

unsigned char SL_SC7A20H_SOFT_RESET(void)
{
	unsigned char SL_Read_Reg  = 0xff;
	
	SL_SC7A20H_I2c_Spi_Write(1, 0x23, 0x80);//FLAG
	sl_delay(100);
	SL_SC7A20H_I2c_Spi_Write(1, 0x24, 0x80);//BOOT
	SL_SC7A20H_I2c_Spi_Write(1, 0x68, 0xA5);//SOFT_RESET
	sl_delay(200);
	SL_SC7A20H_I2c_Spi_Read(1, 0x23, 1,&SL_Read_Reg);//close aoi1 function
	if(SL_Read_Reg==0x00)   return  1;
	else                    return  0;
}
/* 
Copyright (c) 2022 Silan MEMS. All Rights Reserved.
*/

#ifndef __SL_SC7A20H_Watch_Algorithm_driver__
#define __SL_SC7A20H_Watch_Algorithm_driver__

/***********IIC******************/
//#include "i2c.h"
/***************************************/

//printf
#define SL_Sensor_Algo_Release_Enable 0x01
//0x00: FIFO-12bit;0x01: FIFO-8bit
#define SL_SC7A20H_FIFO_MODE_ENABLE   0x00 


/***????????????????******/
/**SC7A20H SDO :0***************/
/**SC7A20H SDO :1***************/
#define SL_SC7A20H_SDO_VDD_GND            1
/*****************************************/
/***??????????IIC??????***/
/**SC7A20H IIC_Device 7bits:  0****/
/**SC7A20H IIC_Device 8bits:  1****/
#define SL_SC7A20H_IIC_7BITS_8BITS        0
/*****************************************/
#if SL_SC7A20H_SDO_VDD_GND==0
#define SL_SC7A20H_IIC_7BITS_ADDR        0x18
#define SL_SC7A20H_IIC_8BITS_WRITE_ADDR  0x30
#define SL_SC7A20H_IIC_8BITS_READ_ADDR   0x31
#else
#define SL_SC7A20H_IIC_7BITS_ADDR        0x19
#define SL_SC7A20H_IIC_8BITS_WRITE_ADDR  0x32
#define SL_SC7A20H_IIC_8BITS_READ_ADDR   0x33
#endif
#if SL_SC7A20H_IIC_7BITS_8BITS==0
#define SL_SC7A20H_IIC_ADDRESS        SL_SC7A20H_IIC_7BITS_ADDR
#else
#define SL_SC7A20H_IIC_WRITE_ADDRESS  SL_SC7A20H_IIC_8BITS_WRITE_ADDR
#define SL_SC7A20H_IIC_READ_ADDRESS   SL_SC7A20H_IIC_8BITS_READ_ADDR
#endif

/**************IIC/SPI****************/
unsigned char SL_SC7A20H_I2c_Spi_Write(unsigned char sl_spi_iic,unsigned char reg, unsigned char dat);
unsigned char SL_SC7A20H_I2c_Spi_Read(unsigned char sl_spi_iic,unsigned char reg, unsigned char len, unsigned char *buf);
/**SL_SC7A20H_I2c_Spi_Write , sl_spi_iic:0=spi  1=i2c  Reg:寄存器地址  dat:寄存器写入值******************/
/**SL_SC7A20H_I2c_Spi_Write ******************************************************************/
/***SL_SC7A20H_I2c_Spi_Read , sl_spi_iic:0=spi  1=i2c Reg:寄存器地址   len:连读寄存器个数,buf:读取寄存器值***/
/***SL_SC7A20H_I2c_Spi_Read ************************************************/


/*************I2C_Check******************/
unsigned char SL_SC7A20H_Check(void);
/****************************************/
/**return : 1   IIC OK **************/
/**return : 0   IIC ERROR**********/



/*************SC7A20H_INIT*******************/
unsigned char SL_SC7A20H_Config(void);
/*******************************************/
/**return : 1    IIC OK *************/
/**return : 0;   IIC ERROR*********/



/******READ XYZ_DATA******/
void SL_SC7A20H_RawData_Read(signed short* acc_data);
/************* XYZ*****************/
/************* acc_data[0]:    X***********************/
/************* acc_data[1]:    Y***********************/
/************* acc_data[2]:    Z***********************/

void SL_SC7A20H_RawAngle_Read(float* angle_data);
/************* angle_data[0]:    pitch***********************/
/************* angle_data[1]:    roll***********************/


/******READ FIFO_DATA******/
unsigned char SL_SC7A20H_FIFO_Read(signed short *x_data_buf,signed short *y_data_buf,signed short *z_data_buf);
/***********************XYZ**************************/
/*************x_data_buf[0]:    X****************/
/*************x_data_buf[0]:    Y****************/
/*************x_data_buf[0]:    Z****************/
/**x_data_buf : array_number<=32***************************/
/********************************************/
/**return : len    FIFO_LEN*************************/



/*********SC7A20H POWER DOWN*************/
unsigned char SL_SC7A20H_POWER_DOWN(void);
/**0: OK***********************/
/**1: ERROR***********************/

/**reg map***************/
#define SC7A20H_WHO_AM_I         0x0F
#define SC7A20H_VERSION          0x70

/*********SC7A20H RESET***************/
unsigned char SL_SC7A20H_SOFT_RESET(void);
/**0: OK*************************/
/**1: ERROR*************************/

#endif // SC7A20H_H

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值