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();
函数命名有点乱!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/70441.html