SL_Sc7a20_Angle_Driver.c
其中需要注意的地方:
要改的地方就是SCL,SDA引脚的初始化,都配置为开漏输出,我这边用的复旦微芯片。SCL,SDA引脚做输出时配置为开漏输出。SDA引脚存在输入输出切换,在set_scI2cSDAIO函数中切换输出或者输入
#include "SL_Sc7a20_Angle_Driver.h"
#include <math.h>
#include "main.h"
// 7位地址 8位地址
//PC9 i2c地址选择 拉高 0x19 0x32(W) 0x33(R)
//PC9 i2c地址选择 拉低 0x18 0x30(W) 0x31(R)
//PD12 SDA
//PB15 SCL
#define scI2C_SCLH FL_GPIO_SetOutputPin(GPIOB,FL_GPIO_PIN_15)
#define scI2C_SCLL FL_GPIO_ResetOutputPin(GPIOB,FL_GPIO_PIN_15)
#define scI2C_SDAH FL_GPIO_SetOutputPin(GPIOD,FL_GPIO_PIN_12)
#define scI2C_SDAL FL_GPIO_ResetOutputPin(GPIOD,FL_GPIO_PIN_12)
#define scI2C_SDARead (FL_GPIO_GetInputPin(GPIOD,FL_GPIO_PIN_12)?1:0)
#define scI2CDEVAddr_W 0x30
#define scI2CDEVAddr_R 0x31
void sl_spi_Init(void){
FL_GPIO_InitTypeDef GPIO_InitStruct;
FL_NVIC_ConfigTypeDef InterruptConfigStruct;
#if(SL_SC7A20_SPI_IIC_MODE==1) //i2c
GPIO_InitStruct.pin = FL_GPIO_PIN_15; //B SCL
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.pull = FL_DISABLE;
GPIO_InitStruct.remapPin = FL_DISABLE;
GPIO_InitStruct.analogSwitch = FL_DISABLE;
FL_GPIO_Init( GPIOB, &GPIO_InitStruct );
GPIO_InitStruct.pin = FL_GPIO_PIN_12; //D SDA
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.pull = FL_DISABLE;
GPIO_InitStruct.remapPin = FL_DISABLE;
GPIO_InitStruct.analogSwitch = FL_DISABLE;
FL_GPIO_Init( GPIOD, &GPIO_InitStruct );
scI2C_SCLH;
scI2C_SDAH;
MF_EXTI_Line8_Init();
InterruptConfigStruct.preemptPriority = 0x02;
FL_NVIC_Init(&InterruptConfigStruct, GPIO_IRQn);
FL_CMU_EnableEXTIOnSleep();//休眠使能外部中断采样
#else
FL_SPI_InitTypeDef defaultInitStruct;
GPIO_InitStruct.pin = FL_GPIO_PIN_7;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = DISABLE;
GPIO_InitStruct.remapPin = DISABLE;
FL_GPIO_Init( GPIOC, &GPIO_InitStruct );
GPIO_InitStruct.pin = FL_GPIO_PIN_8;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = DISABLE;
GPIO_InitStruct.remapPin = DISABLE;
FL_GPIO_Init( GPIOC, &GPIO_InitStruct );
GPIO_InitStruct.pin = FL_GPIO_PIN_9;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = DISABLE;
GPIO_InitStruct.remapPin = DISABLE;
FL_GPIO_Init( GPIOC, &GPIO_InitStruct );
GPIO_InitStruct.pin = FL_GPIO_PIN_10;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = DISABLE;
GPIO_InitStruct.remapPin = DISABLE;
FL_GPIO_Init( GPIOC, &GPIO_InitStruct );
defaultInitStruct.transferMode = FL_SPI_TRANSFER_MODE_FULL_DUPLEX;
defaultInitStruct.mode = FL_SPI_WORK_MODE_MASTER;
defaultInitStruct.dataWidth = FL_SPI_DATA_WIDTH_8B;
defaultInitStruct.clockPolarity = FL_SPI_POLARITY_INVERT;
defaultInitStruct.clockPhase = FL_SPI_PHASE_EDGE2;
defaultInitStruct.softControl = ENABLE;
defaultInitStruct.baudRate = FL_SPI_BAUDRATE_DIV8;
defaultInitStruct.bitOrder = FL_SPI_BIT_ORDER_MSB_FIRST;
FL_SPI_Init(SPI2,&defaultInitStruct );
#endif
}
static void sci2c_Delay(void){
u16 i;
for(i=0;i<10;i++);
}
void set_scI2cSDAIO(u8 ui){
FL_GPIO_InitTypeDef GPIO_InitStruct;
if(ui==1){ //input
GPIO_InitStruct.pin = FL_GPIO_PIN_12; //D
GPIO_InitStruct.mode = FL_GPIO_MODE_INPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = FL_DISABLE;
GPIO_InitStruct.remapPin = FL_DISABLE;
GPIO_InitStruct.analogSwitch = FL_DISABLE;
FL_GPIO_Init( GPIOD, &GPIO_InitStruct );
}
else{ //output
GPIO_InitStruct.pin = FL_GPIO_PIN_12; //D
GPIO_InitStruct.mode = FL_GPIO_MODE_OUTPUT;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_OPENDRAIN;
GPIO_InitStruct.pull = FL_DISABLE;
GPIO_InitStruct.remapPin = FL_DISABLE;
GPIO_InitStruct.analogSwitch = FL_DISABLE;
FL_GPIO_Init( GPIOD, &GPIO_InitStruct );
}
}
void sci2c_Start(void){
scI2C_SDAH;
sci2c_Delay();
scI2C_SCLH;
sci2c_Delay();
scI2C_SDAL;
sci2c_Delay();
scI2C_SCLL;
sci2c_Delay();
}
void sci2c_Stop(void){
scI2C_SDAL;
sci2c_Delay();
scI2C_SCLH;
sci2c_Delay();
scI2C_SDAH;
sci2c_Delay();
}
void sci2c_SendByte(u8 _ucByte){
u8 i;
/*first bit7 */
for(i=0;i<8;i++){
if(_ucByte & 0x80){
scI2C_SDAH;
}
else{
scI2C_SDAL;
}
sci2c_Delay();
scI2C_SCLH;
sci2c_Delay();
scI2C_SCLL;
if(i == 7){
sci2c_Delay();
scI2C_SDAH; // ????
}
_ucByte <<= 1; /* ????bit */
sci2c_Delay();
}
}
u8 sci2c_ReadByte(void){
u8 i;
u8 value;
/*first bit7 */
value = 0;
set_scI2cSDAIO(1);//改为输入模式
for(i=0;i<8;i++){
value <<= 1;
scI2C_SCLH;
sci2c_Delay();
if(scI2C_SDARead){
value++;
}
scI2C_SCLL;
sci2c_Delay();
}
set_scI2cSDAIO(0);//改为输出模式
return value;
}
u8 sci2c_WaitAck(void){
u8 re;
u8 count=2;
scI2C_SDAH;
sci2c_Delay();
scI2C_SCLH;
sci2c_Delay();
set_scI2cSDAIO(1);//改为输入模式
do{
count--;
if (scI2C_SDARead){
re = 1;
}
else{
re = 0;
break;
}
sci2c_Delay();
}while(count>0);
set_scI2cSDAIO(0);//改为输入模式
scI2C_SCLL;
sci2c_Delay();
return re;
}
void sci2c_Ack(void){
scI2C_SDAL;
sci2c_Delay();
scI2C_SCLH;
sci2c_Delay();
scI2C_SCLL;
sci2c_Delay();
scI2C_SDAH;
}
void sci2c_NAck(void){
scI2C_SDAH;
sci2c_Delay();
scI2C_SCLH;
sci2c_Delay();
scI2C_SCLL;
sci2c_Delay();
}
void scI2C_WriteByte(u8 uData,u8 uWriteAddress){
sci2c_Start();
sci2c_SendByte(scI2CDEVAddr_W);
sci2c_WaitAck();
sci2c_SendByte((uWriteAddress) & 0xFF);
sci2c_WaitAck();
sci2c_SendByte(uData);
sci2c_WaitAck();
sci2c_Stop();
}
u8 scI2C_ReadByte(u8 uReadAddress,u8 *dat){
sci2c_Start();
sci2c_SendByte(scI2CDEVAddr_W);
if(1==sci2c_WaitAck()){ //ERROR
return 0;
}
sci2c_SendByte(uReadAddress);
if(1==sci2c_WaitAck()){ //ERROR
return 0;
}
sci2c_Start();
sci2c_SendByte(scI2CDEVAddr_R);
if(1==sci2c_WaitAck()){ //ERROR
return 0;
}
*dat = sci2c_ReadByte();
sci2c_Stop();
return 1;//正常返回
}
void SST25_CS_LOW(void){
FL_SPI_SetSSNPin(SPI2, FL_SPI_SSN_LOW);
}
void SST25_CS_HIGH(void){
FL_SPI_SetSSNPin(SPI2, FL_SPI_SSN_HIGH);
}
void sl_spi_IO_CLOSE(void)
{
#if(SL_SC7A20_SPI_IIC_MODE==1) //i2c
#else
FL_GPIO_DeInit(GPIOB,FL_GPIO_PIN_9|FL_GPIO_PIN_10|FL_GPIO_PIN_8);
#endif
}
void sl_spi_IO_OPEN(void)
{
#if(SL_SC7A20_SPI_IIC_MODE==1) //i2c
#else
FL_GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.pin = FL_GPIO_PIN_9|FL_GPIO_PIN_10|FL_GPIO_PIN_8;
GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
GPIO_InitStruct.pull = DISABLE;
GPIO_InitStruct.remapPin = DISABLE;
FL_GPIO_Init( GPIOC, &GPIO_InitStruct );
#endif
}
u8 SST25_Send_Byte(u8 byte){
FL_SPI_WriteTXBuff(SPI2, byte);
while (!(FL_SPI_IsActiveFlag_TXBuffEmpty(SPI2)));
while (!(FL_SPI_IsActiveFlag_RXBuffFull(SPI2)));
return (FL_SPI_ReadRXBuff(SPI2));
}
u8 SL_SC7A20_I2c_Spi_Write(u8 sl_spi_iic,u8 reg,u8 data){
#if(SL_SC7A20_SPI_IIC_MODE==1) //i2c
scI2C_WriteByte(data,reg);
#else
SST25_CS_LOW();
SST25_Send_Byte(reg);
SST25_Send_Byte(data);
SST25_CS_HIGH();
#endif
return 1;
}
u8 SL_SC7A20_I2c_Spi_Read(u8 sl_spi_iic,u8 reg,u8 len,u8 *buf){
u8 i=0,tmpdata;
#if(SL_SC7A20_SPI_IIC_MODE==1) //i2c
for(i=0;i<len;i++){
scI2C_ReadByte(reg+i,&tmpdata);
*buf++=tmpdata;
}
#else
SST25_CS_LOW();
SST25_Send_Byte(0xC0|reg);
for(i=0;i<len;i++){
*buf++=SST25_Send_Byte(0);
}
SST25_CS_HIGH();
#endif
return 1;
}
/***************在线测试**********************/
signed char SL_SC7A20_Online_Test(void)
{
unsigned char SL_Read_Reg=0xff;
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SC7A20_CHIP_ID_ADDRESS,1, &SL_Read_Reg);
if(SL_Read_Reg==SC7A20_CHIP_ID_VALUE)
return 1;
else
return -1;
}
/***************BOOT 重载内部寄存器值*********************/
signed char SL_SC7A20_BOOT(void)
{
unsigned char SL_Read_Reg=0xff;
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG5,1, &SL_Read_Reg);
SL_Read_Reg=SL_SC7A20_BOOT_ENABLE|SL_Read_Reg;
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG5, SL_Read_Reg);
return 1;
}
/***************传感器量程设置**********************/
signed char SL_SC7A20_FS_Config(unsigned char Sc7a20_FS_Reg)
{
unsigned char SL_Read_Reg=0xff,SL_Write_Reg;
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG4,1, &SL_Read_Reg);
SL_Write_Reg=0x80|Sc7a20_FS_Reg|SL_SC7A20_HR_ENABLE;
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG4, SL_Write_Reg);
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG4,1, &SL_Read_Reg);
if(SL_Read_Reg==SL_Write_Reg) return 1;
else return -1;
}
//AOI2_INT1 位置检测,检测是否离开Y+位置 1D位置识别
/***************中断设置*************/
signed char SL_SC7A20_INT_Config(void)
{
unsigned char SL_Read_Reg;
//---------- 中断1配置 ------------
SL_Read_Reg=0x00; //0xC8
SL_Read_Reg=SL_Read_Reg|0x20;//Z轴高
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_AOI1_CFG, SL_Read_Reg);
//中断阈值设置
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_AOI1_THS, SL_SC7A20_INT_THS_20PERCENT);
//大于阈值多少时间触发中断
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_AOI1_DURATION, SL_SC7A20_INT_DURATION_5CLK);
//---------- 中断2配置 ------------
SL_Read_Reg=0x00; //0xC8
//SL_Read_Reg=SL_Read_Reg|0x40;//方向位置识别模式
//修改08即可切换到任意轴朝上的情况
SL_Read_Reg=SL_Read_Reg|0x20;//Z轴高
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_AOI2_CFG, SL_Read_Reg);
//中断阈值设置
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_AOI2_THS, SL_SC7A20_INT_THS_80PERCENT);
//大于阈值多少时间触发中断
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_AOI2_DURATION, SL_SC7A20_INT_DURATION_10CLK);
//-----------
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG5,1, &SL_Read_Reg);
SL_Read_Reg=SL_Read_Reg&0xFD;//AOI2 NO LATCH
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG5, SL_Read_Reg);
//H_LACTIVE SET AOI2 TO INT2
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG6,1, &SL_Read_Reg);
SL_Read_Reg=SL_SC7A20_INT_ACTIVE_LOWER_LEVEL|SL_Read_Reg|0x20;
//interrupt happen,int pin output lower level
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG6, SL_Read_Reg);
//HPF SET
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG2,1, &SL_Read_Reg);
SL_Read_Reg=SL_Read_Reg&0xFD;//NO HPF TO AOI2
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG2, SL_Read_Reg);
//AOI1 TO INT1
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG3,1, &SL_Read_Reg);
SL_Read_Reg=SL_Read_Reg|0x40; //AOI2 TO INT1
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG3, SL_Read_Reg);
return 1;
}
/******外部中断处理函数中需要调用该函数*******/
//retrun_value&0x20=0x20 ZH Z轴高事件
//retrun_value&0x20=0x10 ZL Z轴低事件
//retrun_value&0x20=0x08 YH Y轴高事件
//retrun_value&0x20=0x04 YL Y轴低事件
//retrun_value&0x20=0x02 XH X轴高事件
//retrun_value&0x20=0x01 XL X轴低事件
signed char SL_SC7A20_INT_RESET(void)
{
unsigned char SL_Read_Reg1;
unsigned char SL_Read_Reg2;
/*****为了避免读取数据过程中又产生中断,可以暂时关闭中断*****/
//SL_Read_Reg1 display the int1 type
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_AOI1_SRC,1, &SL_Read_Reg1);
//SL_Read_Reg2 display the int2 type
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_AOI2_SRC,1, &SL_Read_Reg2);
//close INT1
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_AOI1_CFG, 0x00);
//close INT2
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_AOI2_CFG, 0x00);
if(SL_Read_Reg1!=0||SL_Read_Reg2!=0)
{
return 1;
}
else
{
return 0;
}
}
/***************数据更新速率**加速度计使能**********/
signed char SL_SC7A20_Power_Config(unsigned char Power_Config_Reg)
{
unsigned char SL_Read_Reg;
#if SL_SC7A20_MTP_ENABLE == 0X01
SL_Read_Reg = 0x00;
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_MTP_CFG, SL_SC7A20_MTP_VALUE);
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_SDOI2C_PU_CFG,1, &SL_Read_Reg);
SL_Read_Reg=SL_Read_Reg|SL_SC7A20_SDO_PU_MSK|SL_SC7A20_I2C_PU_MSK;
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_SDOI2C_PU_CFG, SL_Read_Reg);
#endif
SL_Read_Reg = 0xff;
SL_SC7A20_I2c_Spi_Write(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG1, Power_Config_Reg);
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_CTRL_REG1,1, &SL_Read_Reg);
if(SL_Read_Reg==Power_Config_Reg) return 1;
else return -1;
}
#if SL_SC7A20_16BIT_8BIT==0
/***************加速度计数据读取*8bits*********/
signed char SL_SC7A20_Read_XYZ_Data(signed char *SL_SC7A20_Data_XYZ_Buf)
{
unsigned char SL_Read_Buf[7];
float SL_Angle[3];
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_STATUS_REG,1, &SL_Read_Buf[0]);
if((SL_Read_Buf[0]&0x0f)==0x0f)
{
#if SL_SC7A20_SPI_IIC_MODE ==1//IIC
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_DATA_OUT,6, &SL_Read_Buf[1]);
#elif SL_SC7A20_SPI_IIC_MODE ==0//SPI
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_STATUS_REG,7, &SL_Read_Buf[0]);
#endif
SL_SC7A20_Data_XYZ_Buf[0]=(signed char)SL_Read_Buf[2];
SL_SC7A20_Data_XYZ_Buf[1]=(signed char)SL_Read_Buf[4];
SL_SC7A20_Data_XYZ_Buf[2]=(signed char)SL_Read_Buf[6];
#if 0
SL_Angle[0]=(float)SL_SC7A20_Data_XYZ_Buf[0]/64;
SL_Angle[1]=(float)SL_SC7A20_Data_XYZ_Buf[1]/64;
SL_Angle[2]=(float)SL_SC7A20_Data_XYZ_Buf[2]/64;
if(SL_Angle[0]>1.0) SL_Angle[0]= 1.0;
if(SL_Angle[0]<-1.0) SL_Angle[0]=-1.0;
if(SL_Angle[1]>1.0) SL_Angle[1]= 1.0;
if(SL_Angle[1]<-1.0) SL_Angle[1]=-1.0;
if(SL_Angle[2]>1.0) SL_Angle[2]= 1.0;
if(SL_Angle[2]<-1.0) SL_Angle[2]=-1.0;
SL_Angle[0] = asinf(SL_Angle[0])*57.32484;
SL_Angle[1] = asinf(SL_Angle[1])*57.32484;//y angle
SL_Angle[2] = asinf(SL_Angle[2])*57.32484;
SL_SC7A20_Data_XYZ_Buf[2]=SL_Angle[1];
#endif
return 1;
}
else
{
return 0;
}
}
#elif SL_SC7A20_16BIT_8BIT==1
/***************加速度计数据读取*16bits*********/
#define SL_SC7A20EE_POS_SEL 5
//??SC7A22??????????
const signed char accel_pos_change[8][3][3]=
{//x y z
{{1,0,0}, {0,0,-1},{0,1,0}},//0???????
{{0,1,0},{0,0,-1},{-1,0,0}},
{{-1,0,0},{0,0,-1},{0,-1,0}},
{{0,-1,0}, {0,0,-1},{1,0,0}},
{{-1,0,0}, {0,0,1}, {0,1,0}},//4???????
{{0,1,0}, {0,0,1},{1,0,0}},
{{1,0,0},{0,0,1},{0,-1,0}},
{{0,-1,0},{0,0,1},{-1,0,0}}
};
#define SL_Filter_Order 16
static signed short SL_Filter_BUF[3][SL_Filter_Order]={{0},{0},{0}};
static unsigned char SL_Filter_i =0;
/**used to solid signal**/
static signed short SL_XYZ_AVG[3] ={0,0,0};
static void SL_SC7A20E_Filter(signed short *Input1_s16,signed short *Output1_s16,unsigned char axis)
{
SL_XYZ_AVG[axis]=SL_XYZ_AVG[axis]+Input1_s16[axis]-SL_Filter_BUF[axis][SL_Filter_i];
SL_Filter_BUF[axis][SL_Filter_i]=Input1_s16[axis];
Output1_s16[axis]=SL_XYZ_AVG[axis];
}
signed char SL_SC7A20_Read_XYZ_Data(signed short *SL_SC7A20_Data_XYZ_Buf)
{
unsigned char SL_Read_Buf[7];
float SL_Angle[3];
float roll,pitch;
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_STATUS_REG,1, &SL_Read_Buf[0]);
if((SL_Read_Buf[0]&0x0f)==0x0f)
{
#if SL_SC7A20_SPI_IIC_MODE ==1//IIC
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_DATA_OUT,6, &SL_Read_Buf[1]);
#elif SL_SC7A20_SPI_IIC_MODE ==0//SPI
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_STATUS_REG,7, &SL_Read_Buf[0]);
#endif
SL_SC7A20_Data_XYZ_Buf[0]=(signed short)((SL_Read_Buf[2]<<8) + SL_Read_Buf[1]);
SL_SC7A20_Data_XYZ_Buf[1]=(signed short)((SL_Read_Buf[4]<<8) + SL_Read_Buf[3]);
SL_SC7A20_Data_XYZ_Buf[2]=(signed short)((SL_Read_Buf[6]<<8) + SL_Read_Buf[5]);
#if 1
SL_SC7A20E_Filter(&SL_SC7A20_Data_XYZ_Buf[0],&SL_SC7A20_Data_XYZ_Buf[0],0);
SL_SC7A20E_Filter(&SL_SC7A20_Data_XYZ_Buf[1],&SL_SC7A20_Data_XYZ_Buf[1],1);
SL_SC7A20E_Filter(&SL_SC7A20_Data_XYZ_Buf[2],&SL_SC7A20_Data_XYZ_Buf[2],2);
SL_Angle[0]=SL_SC7A20_Data_XYZ_Buf[0];
SL_Angle[1]=SL_SC7A20_Data_XYZ_Buf[1];
SL_Angle[2]=SL_SC7A20_Data_XYZ_Buf[2];
SL_Angle[0]=(float)SL_Angle[0]/16384;
SL_Angle[1]=(float)SL_Angle[1]/16384;
SL_Angle[2]=(float)SL_Angle[2]/16384;
if(SL_Angle[0]>1.0) SL_Angle[0]= 1.0;
if(SL_Angle[0]<-1.0) SL_Angle[0]=-1.0;
if(SL_Angle[1]>1.0) SL_Angle[1]= 1.0;
if(SL_Angle[1]<-1.0) SL_Angle[1]=-1.0;
if(SL_Angle[2]>1.0) SL_Angle[2]= 1.0;
if(SL_Angle[2]<-1.0) SL_Angle[2]=-1.0;
//z轴朝上
if(SL_Angle[2]!=0)
pitch= atanf(SL_Angle[1]/SL_Angle[2])*57.32484;
else
pitch= 90;
if(SL_Angle[1]!=0||SL_Angle[2]!=0)
roll = -atanf(SL_Angle[0]/sqrt(SL_Angle[2]*SL_Angle[2]+SL_Angle[1]*SL_Angle[1]))*57.32484;
else
roll = 90;
//x轴朝上
// if(SL_Angle[0]!=0)
// pitch= atanf(SL_Angle[2]/SL_Angle[0])*57.32484;
// else
// pitch= 90;
// if(SL_Angle[0]!=0||SL_Angle[2]!=0)
// roll = -atanf(SL_Angle[1]/sqrt(SL_Angle[0]*SL_Angle[0]+SL_Angle[2]*SL_Angle[2]))*57.32484;
// else
// roll = 90;
//y轴朝上
// if(SL_Angle[1]!=0)
// pitch= atanf(SL_Angle[0]/SL_Angle[1])*57.32484;
// else
// pitch= 90;
// if(SL_Angle[0]!=0||SL_Angle[1]!=0)
// roll = -atanf(SL_Angle[2]/sqrt(SL_Angle[0]*SL_Angle[0]+SL_Angle[1]*SL_Angle[1]))*57.32484;
// else
// roll = 90;
SL_SC7A20_Data_XYZ_Buf[0]=(signed short)roll;
SL_SC7A20_Data_XYZ_Buf[1]=(signed short)pitch;
#endif
return 1;
}
else
{
return 0;
}
}
signed char SL_SC7A20_Read_XYZ_Data1(signed short *SL_SC7A20_Data_XYZ_Buf)
{
unsigned char SL_Read_Buf[7],sl_i=0;
float SL_Angle[3];
float roll,pitch;
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_STATUS_REG,1, &SL_Read_Buf[0]);
if((SL_Read_Buf[0]&0x0f)==0x0f)
{
#if SL_SC7A20_SPI_IIC_MODE ==1//IIC
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_DATA_OUT,6, &SL_Read_Buf[1]);
#elif SL_SC7A20_SPI_IIC_MODE ==0//SPI
SL_SC7A20_I2c_Spi_Read(SL_SC7A20_SPI_IIC_MODE,SL_SC7A20_STATUS_REG,7, &SL_Read_Buf[0]);
#endif
SL_SC7A20_Data_XYZ_Buf[0]=(signed short)((SL_Read_Buf[2]<<8) + SL_Read_Buf[1]);
SL_SC7A20_Data_XYZ_Buf[1]=(signed short)((SL_Read_Buf[4]<<8) + SL_Read_Buf[3]);
SL_SC7A20_Data_XYZ_Buf[2]=(signed short)((SL_Read_Buf[6]<<8) + SL_Read_Buf[5]);
// mSystem.slbuf[0]=SL_SC7A20_Data_XYZ_Buf[0];
// mSystem.slbuf[1]=SL_SC7A20_Data_XYZ_Buf[1];
// mSystem.slbuf[2]=SL_SC7A20_Data_XYZ_Buf[2];
//原计算方法
// SL_Angle[0]=(float)SL_SC7A20_Data_XYZ_Buf[0]/16384;
// SL_Angle[1]=(float)SL_SC7A20_Data_XYZ_Buf[1]/16384;
// SL_Angle[2]=(float)SL_SC7A20_Data_XYZ_Buf[2]/16384;
// if(SL_Angle[0]>1.0) SL_Angle[0]= 1.0;
// if(SL_Angle[0]<-1.0) SL_Angle[0]=-1.0;
// if(SL_Angle[1]>1.0) SL_Angle[1]= 1.0;
// if(SL_Angle[1]<-1.0) SL_Angle[1]=-1.0;
// if(SL_Angle[2]>1.0) SL_Angle[2]= 1.0;
// if(SL_Angle[2]<-1.0) SL_Angle[2]=-1.0;
//
// SL_Angle[0] = asinf(SL_Angle[0])*57.32484;
// SL_Angle[1] = asinf(SL_Angle[1])*57.32484;//y angle
// SL_Angle[2] = asinf(SL_Angle[2])*57.32484;
// SL_SC7A20_Data_XYZ_Buf[0]=SL_Angle[0];
// SL_SC7A20_Data_XYZ_Buf[1]=SL_Angle[1];
// SL_SC7A20_Data_XYZ_Buf[2]=SL_Angle[2];
//新计算方法
SL_SC7A20_Data_XYZ_Buf[1]=(signed short)((SL_Read_Buf[2]<<8) + SL_Read_Buf[1]);
SL_SC7A20_Data_XYZ_Buf[2]=(signed short)((SL_Read_Buf[4]<<8) + SL_Read_Buf[3]);
SL_SC7A20_Data_XYZ_Buf[0]=(signed short)((SL_Read_Buf[6]<<8) + SL_Read_Buf[5]);
SL_SC7A20_Data_XYZ_Buf[0]=SL_SC7A20_Data_XYZ_Buf[0];
SL_SC7A20_Data_XYZ_Buf[1]=SL_SC7A20_Data_XYZ_Buf[1]+500;
SL_SC7A20_Data_XYZ_Buf[2]=SL_SC7A20_Data_XYZ_Buf[2]+1500;
for(sl_i=0;sl_i<3;sl_i++)
{
SL_Angle[sl_i]=\
accel_pos_change[SL_SC7A20EE_POS_SEL][sl_i][0]*SL_SC7A20_Data_XYZ_Buf[0]+\
accel_pos_change[SL_SC7A20EE_POS_SEL][sl_i][1]*SL_SC7A20_Data_XYZ_Buf[1]+\
accel_pos_change[SL_SC7A20EE_POS_SEL][sl_i][2]*SL_SC7A20_Data_XYZ_Buf[2];
}
SL_SC7A20_Data_XYZ_Buf[0]=SL_Angle[0];
SL_SC7A20_Data_XYZ_Buf[1]=SL_Angle[1];
SL_SC7A20_Data_XYZ_Buf[2]=SL_Angle[2];
SL_SC7A20E_Filter(&SL_SC7A20_Data_XYZ_Buf[0],&SL_SC7A20_Data_XYZ_Buf[0],0);
SL_SC7A20E_Filter(&SL_SC7A20_Data_XYZ_Buf[1],&SL_SC7A20_Data_XYZ_Buf[1],1);
SL_SC7A20E_Filter(&SL_SC7A20_Data_XYZ_Buf[2],&SL_SC7A20_Data_XYZ_Buf[2],2);
SL_Angle[0]=SL_SC7A20_Data_XYZ_Buf[0];
SL_Angle[1]=SL_SC7A20_Data_XYZ_Buf[1];
SL_Angle[2]=SL_SC7A20_Data_XYZ_Buf[2];
#if 1
SL_Angle[0]=(float)SL_Angle[0]/16384;
SL_Angle[1]=(float)SL_Angle[1]/16384;
SL_Angle[2]=(float)SL_Angle[2]/16384;
if(SL_Angle[0]>1.0) SL_Angle[0]= 1.0;
if(SL_Angle[0]<-1.0) SL_Angle[0]=-1.0;
if(SL_Angle[1]>1.0) SL_Angle[1]= 1.0;
if(SL_Angle[1]<-1.0) SL_Angle[1]=-1.0;
if(SL_Angle[2]>1.0) SL_Angle[2]= 1.0;
if(SL_Angle[2]<-1.0) SL_Angle[2]=-1.0;
if(SL_Angle[2]!=0)
pitch= atanf(SL_Angle[1]/SL_Angle[2])*57.32484f;
else
pitch= 90;
if(SL_Angle[1]!=0||SL_Angle[2]!=0)
roll = -atanf(SL_Angle[0]/sqrt(SL_Angle[2]*SL_Angle[2]+SL_Angle[1]*SL_Angle[1]))*57.32484f;
else
roll = 90;
SL_SC7A20_Data_XYZ_Buf[0]=(signed short)roll;
SL_SC7A20_Data_XYZ_Buf[1]=(signed short)pitch;
SL_SC7A20_Data_XYZ_Buf[2]=(signed short)SL_Angle[2];
#endif
return 1;
}
else{
return 0;
}
}
#endif
void Init_sc7a20(void){
SL_SC7A20_BOOT();
SL_SC7A20_Online_Test();
SL_SC7A20_FS_Config(SL_SC7A20_FS_2G);
SL_SC7A20_Power_Config(SL_SC7A20_ODR_25HZ);
SL_SC7A20_INT_Config();
// SL_SC7A20_INT_RESET();
}
void Init_sc7a20_clickFun(void){
SL_SC7A20_I2c_Spi_Write(0,0x20,0x37);//25HZ XYZ轴使能
SL_SC7A20_I2c_Spi_Write(0,0x21,0x04);//单击功能 高通滤波使能
//SL_SC7A20_I2c_Spi_Write(0,0x22,0x80);CLICK中断 INT1
SL_SC7A20_I2c_Spi_Write(0,0x25,0x82);//CLICK中断 INT2
SL_SC7A20_I2c_Spi_Write(0,0x23,0x80);//BDU保持
SL_SC7A20_I2c_Spi_Write(0,0x3A,0x32);//单击 阈值设置
SL_SC7A20_I2c_Spi_Write(0,0x3B,0x10);//阈值判断时间
SL_SC7A20_I2c_Spi_Write(0,0x3C,0x0A);//持续时间
SL_SC7A20_I2c_Spi_Write(0,0x38,0x15);//CLICK中断配置
}
SL_Sc7a20_Angle_Driver.h
#ifndef __SL_SC7A20_ANGLE_DRIVER_H__
#define __SL_SC7A20_ANGLE_DRIVER_H__
/***使用驱动前请根据实际接线情况配置******/
/**SC7A20的SDO 脚接地: 0****************/
/**SC7A20的SDO 脚接电源:1****************/
#define SC7A20_SDO_VDD_GND 1
/*****************************************/
/***使用驱动前请根据实际IIC情况进行配置***/
/**SC7A20的IIC 接口地址类型 7bits: 0****/
/**SC7A20的IIC 接口地址类型 8bits: 1****/
#define SC7A20_IIC_7BITS_8BITS 0
/*****************************************/
#define SL_SC7A20_16BIT_8BIT 1
/**SC7A20的数据位数选择 16bits: 1****/
/**SC7A20的数据位数选择 8bits: 0****/
/*****************************************/
#define SL_SC7A20_SPI_IIC_MODE 1
/**SC7A20 SPI IIC 选择 SPI: 0****/
/**SC7A20 SPI IIC 选择 IIC: 1****/
/*****************************************/
#if SC7A20_SDO_VDD_GND==0
#define SC7A20_IIC_7BITS_ADDR 0x18
#define SC7A20_IIC_8BITS_ADDR 0x30
#else
#define SC7A20_IIC_7BITS_ADDR 0x19
#define SC7A20_IIC_8BITS_ADDR 0x32
#endif
#if SC7A20_IIC_7BITS_8BITS==0
#define SC7A20_IIC_ADDRESS SC7A20_IIC_7BITS_ADDR
#else
#define SC7A20_IIC_ADDRESS SC7A20_IIC_8BITS_ADDR
#endif
#define SC7A20_CHIP_ID_ADDRESS (unsigned char)0x0F
#define SC7A20_CHIP_ID_VALUE (unsigned char)0x11
#define SL_SC7A20_CTRL_REG1 (unsigned char)0x20
#define SL_SC7A20_CTRL_REG2 (unsigned char)0x21
#define SL_SC7A20_CTRL_REG3 (unsigned char)0x22
#define SL_SC7A20_CTRL_REG4 (unsigned char)0x23
#define SL_SC7A20_CTRL_REG5 (unsigned char)0x24
#define SL_SC7A20_CTRL_REG6 (unsigned char)0x25
#define SL_SC7A20_STATUS_REG (unsigned char)0x27
#define SL_SC7A20_OUT_X_L (unsigned char)0x28
#define SL_SC7A20_OUT_X_H (unsigned char)0x29
#define SL_SC7A20_OUT_Y_L (unsigned char)0x2A
#define SL_SC7A20_OUT_Y_H (unsigned char)0x2B
#define SL_SC7A20_OUT_Z_L (unsigned char)0x2C
#define SL_SC7A20_OUT_Z_H (unsigned char)0x2D
#define SL_SC7A20_FIFO_CTRL_REG (unsigned char)0x2E
#define SL_SC7A20_FIFO_SRC_REG (unsigned char)0x2F
#define SL_SC7A20_AOI1_CFG (unsigned char)0x30
#define SL_SC7A20_AOI1_SRC (unsigned char)0x31
#define SL_SC7A20_AOI1_THS (unsigned char)0x32
#define SL_SC7A20_AOI1_DURATION (unsigned char)0x33
#define SL_SC7A20_AOI2_CFG (unsigned char)0x34
#define SL_SC7A20_AOI2_SRC (unsigned char)0x35
#define SL_SC7A20_AOI2_THS (unsigned char)0x36
#define SL_SC7A20_AOI2_DURATION (unsigned char)0x37
#define SL_SC7A20_CLICK_CFG (unsigned char)0x38
#define SL_SC7A20_CLICK_SRC (unsigned char)0x39
#define SL_SC7A20_CLICK_THS (unsigned char)0x3A
#define SL_SC7A20_TIME_LIMIT (unsigned char)0x3B
#define SL_SC7A20_TIME_LATENCY (unsigned char)0x3C
#define SL_SC7A20_TIME_WINDOW (unsigned char)0x3D
#define SL_SC7A20_ACT_THS (unsigned char)0x3E
#define SL_SC7A20_ACT_DURATION (unsigned char)0x3F
/*连续读取数据时的数据寄存器地址*/
#define SL_SC7A20_DATA_OUT (unsigned char)(SL_SC7A20_OUT_X_L|0x80)
/**********特殊功能寄存器**********/
/*非原厂技术人员请勿修改*/
#define SL_SC7A20_MTP_ENABLE 0x00
#define SL_SC7A20_MTP_CFG (unsigned char)0x1E
#define SL_SC7A20_MTP_VALUE (unsigned char)0x05
#define SL_SC7A20_SDOI2C_PU_CFG (unsigned char)0x57
#define SL_SC7A20_SDO_PU_MSK (unsigned char)0x08
#define SL_SC7A20_I2C_PU_MSK (unsigned char)0x04
#define SL_SC7A20_HR_ENABLE (unsigned char)0X08
#define SL_SC7A20_BOOT_ENABLE (unsigned char)0X80
/*非原厂技术人员请勿修改*/
/***************数据更新速率**加速度计使能**********/
#define SL_SC7A20_ODR_POWER_DOWN (unsigned char)0x00
#define SL_SC7A20_ODR_1HZ (unsigned char)0x17
#define SL_SC7A20_ODR_10HZ (unsigned char)0x27
#define SL_SC7A20_ODR_25HZ (unsigned char)0x37
#define SL_SC7A20_ODR_50HZ (unsigned char)0x47
#define SL_SC7A20_ODR_100HZ (unsigned char)0x57
#define SL_SC7A20_ODR_200HZ (unsigned char)0x67
#define SL_SC7A20_ODR_400HZ (unsigned char)0x77
#define SL_SC7A20_ODR_1600HZ (unsigned char)0x87
#define SL_SC7A20_ODR_1250HZ (unsigned char)0x97
#define SL_SC7A20_ODR_5000HZ (unsigned char)0x9F
#define SL_SC7A20_LOWER_POWER_ODR_1HZ (unsigned char)0x1F
#define SL_SC7A20_LOWER_POWER_ODR_10HZ (unsigned char)0x2F
#define SL_SC7A20_LOWER_POWER_ODR_25HZ (unsigned char)0x3F
#define SL_SC7A20_LOWER_POWER_ODR_50HZ (unsigned char)0x4F
#define SL_SC7A20_LOWER_POWER_ODR_100HZ (unsigned char)0x5F
#define SL_SC7A20_LOWER_POWER_ODR_200HZ (unsigned char)0x6F
#define SL_SC7A20_LOWER_POWER_ODR_400HZ (unsigned char)0x7F
/***************数据更新速率**加速度计使能**********/
/***************传感器量程设置**********************/
#define SL_SC7A20_FS_2G (unsigned char)0x00
#define SL_SC7A20_FS_4G (unsigned char)0x10
#define SL_SC7A20_FS_8G (unsigned char)0x20
#define SL_SC7A20_FS_16G (unsigned char)0x30
/***************传感器量程设置**********************/
/***取值在0-127之间,此处仅举例****/
#define SL_SC7A20_INT_THS_5PERCENT (unsigned char)0x06
#define SL_SC7A20_INT_THS_8PERCENT (unsigned char)0x09
#define SL_SC7A20_INT_THS_10PERCENT (unsigned char)0x0C
#define SL_SC7A20_INT_THS_20PERCENT (unsigned char)0x18
#define SL_SC7A20_INT_THS_40PERCENT (unsigned char)0x30
#define SL_SC7A20_INT_THS_80PERCENT (unsigned char)0x60
/***取值在0-127之间,此处仅举例 乘以ODR单位时间****/
#define SL_SC7A20_INT_DURATION_2CLK (unsigned char)0x02
#define SL_SC7A20_INT_DURATION_5CLK (unsigned char)0x05
#define SL_SC7A20_INT_DURATION_10CLK (unsigned char)0x0A
/***中断有效时的电平设置,高电平相当于上升沿,低电平相当于下降沿****/
#define SL_SC7A20_INT_ACTIVE_LOWER_LEVEL 0x02 //0x02:中断时INT1脚输出 低电平
#define SL_SC7A20_INT_ACTIVE_HIGH_LEVEL 0x00 //0x00:中断时INT1脚输出 高电平
/***中断有效时的电平设置,高电平相当于上升沿,低电平相当于下降沿****/
#define SL_SC7A20_INT_AOI1_INT1 0x40 //AOI1 TO INT1
#define SL_SC7A20_INT_AOI2_INT1 0x20 //AOI2 TO INT1
/********客户需要进行的IIC接口封包函数****************/
extern unsigned char SL_SC7A20_I2c_Spi_Write(unsigned char sl_spi_iic,unsigned char reg, unsigned char data);
extern unsigned char SL_SC7A20_I2c_Spi_Read(unsigned char sl_spi_iic,unsigned char reg, unsigned char len, unsigned char *buf);
/**SL_SC7A20_I2c_Spi_Write 函数中, sl_spi_iic:0=spi 1=i2c Reg:寄存器地址 data:寄存器的配置值******************/
/**SL_SC7A20_I2c_Spi_Write 函数 是一个单次写的函数*******************************************************************/
/***SL_SC7A20_I2c_Spi_Read 函数中, sl_spi_iic:0=spi 1=i2c Reg 同上,len:读取数据长度,buf:存储数据首地址(指针)***/
/***SL_SC7A20_I2c_Spi_Read 函数 是可以进行单次读或多次连续读取的函数*************************************************/
/*** 客户IIC函数封装举例
unsigned char SL_MEMS_i2c_spi_Write(unsigned char reg, unsigned char data)
{
i2cWrite(SC7A20_IIC_ADDRESS, reg, data); //由客户的II函数接口决定
return 1;
}
unsigned char SL_MEMS_i2c_spi_Read(unsigned char reg, unsigned char len, unsigned char *buf)
{
i2cRead( SC7A20_IIC_ADDRESS, reg, len, buf);//由客户的II函数接口决定
return 1;
}
***/
signed char SL_SC7A20_Online_Test(void);
signed char SL_SC7A20_BOOT(void);
signed char SL_SC7A20_FS_Config(unsigned char Sc7a20_FS_Reg);
signed char SL_SC7A20_INT_Config(void);
signed char SL_SC7A20_INT_RESET(void);
signed char SL_SC7A20_Power_Config(unsigned char Power_Config_Reg);
#if SL_SC7A20_16BIT_8BIT==0
signed char SL_SC7A20_Read_XYZ_Data(signed char *SL_SC7A20_Data_XYZ_Buf);
#elif SL_SC7A20_16BIT_8BIT==1
signed char SL_SC7A20_Read_XYZ_Data(signed short *SL_SC7A20_Data_XYZ_Buf);
#endif
void sl_spi_Init(void);
void Init_sc7a20(void);
void Init_sc7a20_clickFun(void);
void sl_spi_IO_CLOSE(void);
void sl_spi_IO_OPEN(void);
//步骤如下:
//0.signed char SL_SC7A20_BOOT(void);
//1.signed char SL_SC7A20_Online_Test(void);
//2.signed char SL_SC7A20_FS_Config(unsigned char Sc7a20_FS_Reg);
//3.signed char SL_SC7A20_INT_Config(void);
//4.signed char SL_SC7A20_Power_Config(unsigned char Power_Config_Reg);
//5.signed char SL_SC7A20_INT_RESET(void);
//6.signed char SL_SC7A20_Read_XYZ_Data(signed char *SL_SC7A20_Data_XYZ_Buf);
//6.signed char SL_SC7A20_Read_XYZ_Data(signed short *SL_SC7A20_Data_XYZ_Buf);
#endif /* __SL_SC7A20_DRIVER_H */
main.c
sl_spi_Init();
Init_sc7a20_clickFun();
SL_SC7A20_Online_Test();
函数命名有点乱!