SCL3300高精度三轴倾角计驱动代码

已邀请:

laoguo - 微信:17764509575

基于STM32f1标准库,SPI接口,分辨率0.0055°,实测最大数据波动为0.015°。

这款加速度计使用时需要注意,主机发送命令同时接收到的是SCL3300接收上一次命令的反馈,所以需要重复读两次才能接收到想要的数据。

以下是代码请参考,最后一张图片是倾角转换公式:

/*scl3300.c*/
#include scl3300.h;
#include Delay.h
static __IO uint32_t SPITimeout = SPIT_LONG_TIMEOUT;

static uint16_t SPI_TIMEOUT_UserCallback(uint8_t errorCode);

static uint16_t SPI_TIMEOUT_UserCallback(uint8_t errorCode)

{

  return 0;

}





u8 SPI_SCL3300_SendByte(u8 byte)


{


  SPITimeout = SPIT_FLAG_TIMEOUT;


  /* 等待发送缓冲区为空,TXE事件 */


  while (SPI_I2S_GetFlagStatus(SCL3300_SPIx, SPI_I2S_FLAG_TXE) == RESET)


  {


    if ((SPITimeout--) == 0)


      return SPI_TIMEOUT_UserCallback(0);


  }





  /* 写入数据寄存器,把要写入的数据写入发送缓冲区 */


  SPI_I2S_SendData(SCL3300_SPIx, byte);





  SPITimeout = SPIT_FLAG_TIMEOUT;


  /* 等待接收缓冲区非空,RXNE事件 */


  while (SPI_I2S_GetFlagStatus(SCL3300_SPIx, SPI_I2S_FLAG_RXNE) == RESET)


  {


    if ((SPITimeout--) == 0)


      return SPI_TIMEOUT_UserCallback(1);


  }





  /* 读取数据寄存器,获取接收缓冲区数据 */


  return SPI_I2S_ReceiveData(SCL3300_SPIx);


}





void SPI_SCL3300_SendCmd(u32 cmd)


{


  retemp[0] = SPI_SCL3300_SendByte((cmd  24)&0xFF);


  retemp[1] = SPI_SCL3300_SendByte((cmd  16)&0xFF);


  retemp[2] = SPI_SCL3300_SendByte((cmd  8) &0xFF);


  retemp[3] = SPI_SCL3300_SendByte((cmd  0)&0xFF);


}





void SCL3300_Init(void)


{


  SPI_SCL3300_CS_HIGH();


  delay_ms(10);


  SPI_SCL3300_CMD(CHANGE_TO_MODE3);


  delay_ms(5);


  SPI_SCL3300_CMD(READ_STATUS_SUMMARY);


  SPI_SCL3300_CMD(READ_STATUS_SUMMARY);


  SPI_SCL3300_CMD(READ_STATUS_SUMMARY);


  SPI_SCL3300_CMD(ENABLE_ANGLE_OUTPUTS);


}


void SET_SPI(void)


{


  SPI_InitTypeDef SPI_InitStructure;


  GPIO_InitTypeDef GPIO_InitStructure;





  SCL3300_SPI_APBxClock_FUN(SCL3300_SPI_CLK, ENABLE);


  SCL3300_SPI_CS_APBxClock_FUN(SCL3300_SPI_CS_CLK | SCL3300_SPI_SCK_CLK |


                                   SCL3300_SPI_MISO_PIN | SCL3300_SPI_MOSI_PIN,ENABLE);





  /* 配置CS引脚,stm32f1的SPI硬件CS有BUG,需要单独设置 */


  GPIO_InitStructure.GPIO_Pin = SCL3300_SPI_CS_PIN;


  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;


  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;


  GPIO_Init(SCL3300_SPI_CS_PORT, GPIO_InitStructure);





  /* 配置SPI的 SCK引脚*/


  GPIO_InitStructure.GPIO_Pin = SCL3300_SPI_SCK_PIN;


  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;


  GPIO_Init(SCL3300_SPI_SCK_PORT, GPIO_InitStructure);





  /* 配置SPI的 MISO引脚*/


  GPIO_InitStructure.GPIO_Pin = SCL3300_SPI_MISO_PIN;


  GPIO_Init(SCL3300_SPI_MISO_PORT, GPIO_InitStructure);





  /* 配置SPI的 MOSI引脚*/


  GPIO_InitStructure.GPIO_Pin = SCL3300_SPI_MOSI_PIN;


  GPIO_Init(SCL3300_SPI_MOSI_PORT, GPIO_InitStructure);





  SPI_SCL3300_CS_HIGH();





  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;


  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;


  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;


  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;


  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;


  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;


  //正常2M,最大8M 此处设置为4.5M


  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;


  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;


  SPI_InitStructure.SPI_CRCPolynomial = 7;


  SPI_Init(SCL3300_SPIx, SPI_InitStructure);



 SPI_Cmd(SCL3300_SPIx, ENABLE);



  SCL3300_Init();


}





u32 SPI_SCL3300_CMD(u32 cmd)


{


  u32 Temp = 0;


  SPI_SCL3300_CS_LOW();


  SPI_SCL3300_SendCmd(cmd);


  Temp = (u32)(retemp[0] << 24) + (u32)(retemp[1] << 16) + (u32)(retemp[2] << 8) + (u32)retemp[3];


  SPI_SCL3300_CS_HIGH();


  delay_us(10);


  return Temp;


}





scl3300.h


#ifndef __SPI_SCL3300_H


#define __SPI_SCL3300_H





#include stm32f10x.h


#include stm32f10x_conf.h


#include <stdio.h>





/*SPI接口定义-开头****************************/


#define SCL3300_SPIx SPI1


#define SCL3300_SPI_APBxClock_FUN RCC_APB2PeriphClockCmd


#define SCL3300_SPI_CLK RCC_APB2Periph_SPI1





//CS(NSS)引脚 片选选普通GPIO即可


#define SCL3300_SPI_CS_APBxClock_FUN RCC_APB2PeriphClockCmd


#define SCL3300_SPI_CS_CLK RCC_APB2Periph_GPIOA


#define SCL3300_SPI_CS_PORT GPIOA


#define SCL3300_SPI_CS_PIN GPIO_Pin_4





//SCK引脚


#define SCL3300_SPI_SCK_APBxClock_FUN RCC_APB2PeriphClockCmd


#define SCL3300_SPI_SCK_CLK RCC_APB2Periph_GPIOA


#define SCL3300_SPI_SCK_PORT GPIOA


#define SCL3300_SPI_SCK_PIN GPIO_Pin_5


//MISO引脚


#define SCL3300_SPI_MISO_APBxClock_FUN RCC_APB2PeriphClockCmd


#define SCL3300_SPI_MISO_CLK RCC_APB2Periph_GPIOA


#define SCL3300_SPI_MISO_PORT GPIOA


#define SCL3300_SPI_MISO_PIN GPIO_Pin_6


//MOSI引脚


#define SCL3300_SPI_MOSI_APBxClock_FUN RCC_APB2PeriphClockCmd


#define SCL3300_SPI_MOSI_CLK RCC_APB2Periph_GPIOA


#define SCL3300_SPI_MOSI_PORT GPIOA


#define SCL3300_SPI_MOSI_PIN GPIO_Pin_7





#define SPI_SCL3300_CS_LOW() GPIO_ResetBits(SCL3300_SPI_CS_PORT, SCL3300_SPI_CS_PIN)


#define SPI_SCL3300_CS_HIGH() GPIO_SetBits(SCL3300_SPI_CS_PORT, SCL3300_SPI_CS_PIN)





/*等待超时时间*/


#define SPIT_FLAG_TIMEOUT ((uint32_t)0x1000)


#define SPIT_LONG_TIMEOUT ((uint32_t)(10 * SPIT_FLAG_TIMEOUT))





#define READ_ACC_X 0x040000F7


#define READ_ACC_Y 0x080000FD


#define READ_ACC_Z 0x0C0000FB


#define READ_STO 0x100000E9


#define ENABLE_ANGLE_OUTPUTS 0xB0001F6F


#define READ_ANG_X 0x240000C7


#define READ_ANG_Y 0x280000CD


#define READ_ANG_Z 0x2C0000CB


#define READ_TEMPERATURE 0x140000EF


#define READ_STATUS_SUMMARY 0x180000E5


#define READ_ERR_FLAG1 0x1C0000E3


#define READ_ERR_FLAG2 0x200000C1


#define READ_CMD 0x340000DF


#define CHANGE_TO_MODE1 0xB400001F //默认模式,1.8g full-scale 40 Hz 1st order low pass filter


#define CHANGE_TO_MODE2 0xB4000102 //23.6g full-scale 70 Hz 1st order low pass filter


#define CHANGE_TO_MODE3 0xB4000225 //Inclination mode 13 Hz 1st order low pass filter


#define CHANGE_TO_MODE4 0xB4000338 //Inclination mode 13 Hz 1st order low pass filter Low noise mode


#define SET_POWER_DOWN_MODE 0xB400046B


#define WAKE_UP 0xB400001F


#define SW_RESET 0xB4002098


#define READ_ID 0x40000091


#define READ_SERIAL1 0x640000A7


#define READ_SERIAL2 0x680000AD


#define READ_CURRENT_BANK 0x7C0000B3


#define SWITCH_TO_BANK_0 0xFC000073 //默认,读bank1后自动返回


#define SWITCH_TO_BANK_1 0xFC00016E





// 一次发送的数据量


#define SENDBUFF_SIZE 4


static u8 retemp[SENDBUFF_SIZE];





u8 SPI_SCL3300_SendByte(u8 byte);





void SET_SPI(void);


void SCL3300_Init(void);


u32 SPI_SCL3300_CMD(u32 cmd);


#endif /* __SPI_SCL3300_H */

/uploads/files_user1/answer/5f0b236a866a2878473.png

要回复问题请先登录注册