SCL3300倾角传感器使用心得

最近一个项目需要用到SCL3300倾角传感器, 在网上买了两个传感器,打了一个小板,就开始测试了。板子焊好,本想一天内解决代码的问题,结果也花了两三天才搞定,现在把调试结果和心得总结一下,希望有朋友用到时不要走弯路。
1) SCL3300传感器资料
特性
3轴测量
带加速度输出和角度输出
-40℃~125℃
3.0V~3.6V工作电压
SPI接口
0.001°/√Hz的噪声
其它的资料可以查看PDF文档

  1. SCL3300与微处理器的接口
    网上查了很多资料,提供的例程都是基于STM32系列处理器,为了降低成本,我采用了STM8S003处理器来作为主控制器和SCL3300通信。STM8S003提供了一个SPI接口
    用于和SCL3300通信,电路于下图所示

3: 参考代码
1) IO口以及SPI接口设置

#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

/* 定义GPIO端口 */
#define PORT_SCK	GPIOC
#define PIN_SCK		GPIO_PIN_5

#define PORT_DIN	GPIOC
#define PIN_DIN		GPIO_PIN_6

#define PORT_CS		GPIOD
#define PIN_CS		GPIO_PIN_3

#define PORT_DRDY	GPIOD
#define PIN_DRDY	GPIO_PIN_2

#define PORT_DOUT	GPIOC
#define PIN_DOUT	GPIO_PIN_7

/* 定义口线置0和置1的宏 */
#define CS_0()		GPIO_WriteLow(PORT_CS, (GPIO_Pin_TypeDef)PIN_CS)
#define CS_1()		GPIO_WriteHigh(PORT_CS, (GPIO_Pin_TypeDef)PIN_CS)

void bsp_InitSCL3300(void)
{
/* 初始化GPIO,配置为推挽输出 /
GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_FAST); /
设置推挽输出 CS = 1 /
GPIO_Init (GPIOB, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST);
GPIO_Init(PORT_CS, (GPIO_Pin_TypeDef)PIN_CS, GPIO_MODE_OUT_PP_HIGH_FAST); /
设置推挽输出 CS = 1 /
GPIO_Init(PORT_SCK, (GPIO_Pin_TypeDef)PIN_SCK, GPIO_MODE_OUT_PP_HIGH_FAST); /
设置推挽输出 SCK = 0 /
GPIO_Init(PORT_DIN, (GPIO_Pin_TypeDef)PIN_DIN, GPIO_MODE_OUT_PP_HIGH_FAST); /
设置推挽输出 DI = 1 /
GPIO_Init(PORT_DOUT, (GPIO_Pin_TypeDef)PIN_DOUT, GPIO_MODE_IN_FL_NO_IT);/
无上拉,无中断 */
CS_1();
}

void SPI_init(void)
{
SPI_DeInit();
CLK_PeripheralClockConfig(CLK_PERIPHERAL_SPI,ENABLE);
SPI_Init(SPI_FIRSTBIT_MSB, SPI_BAUDRATEPRESCALER_32, SPI_MODE_MASTER, SPI_CLOCKPOLARITY_LOW, SPI_CLOCKPHASE_1EDGE, SPI_DATADIRECTION_2LINES_FULLDUPLEX, SPI_NSS_SOFT, 8);

 SPI_Cmd(ENABLE);

}

//SPI发送及接受数据
u8 SPI_Send_Recv_Byte(u8 sen_data)
{
u8 recv_data;
while(SPI_GetFlagStatus(SPI_FLAG_TXE)== RESET); //while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //等待发送缓冲为空,发送数据
SPI_SendData(sen_data); //SPI_I2S_SendData(SPI1, sen_data);

while(SPI_GetFlagStatus(SPI_FLAG_RXNE)== RESET); //while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //等待接收缓冲非空,接受数据
recv_data = SPI_ReceiveData();
return recv_data;
}

void SPI_SCL3300_SendCmd(u32 cmd)
{
unsigned char cmdT1,cmdT2,cmdT3,cmdT4;
cmdT1=(unsigned char)(cmd >> 24);
cmdT2=(unsigned char)(cmd >> 16);
cmdT3=(unsigned char)(cmd >> 8);
cmdT4=(unsigned char)(cmd );
retemp[0] = SPI_Send_Recv_Byte(cmdT1);//SPI_SCL3300_SendByte((cmd >> 24) & 0xFF);
retemp[1] = SPI_Send_Recv_Byte(cmdT2);
retemp[2] = SPI_Send_Recv_Byte(cmdT3);
retemp[3] = SPI_Send_Recv_Byte(cmdT4);

rs = retemp[0] & 0x03;

// rs
//if(rs != 0x01) return -1;
}

u32 SPI_SCL3300_CMD(u32 cmd)
{

u32 Temp1=0;
u32 Temp2=0;
u32 Temp3=0;
u32 Temp4=0;
CS_0();                    //SPI_SCL3300_CS_LOW();
Delay_us(200);
SPI_SCL3300_SendCmd(cmd);
Temp4=(u32)retemp[0];
Temp1=retemp[1];
Temp2=retemp[2];
Temp3=retemp[3];
TempReturn=(Temp4<<24)|(Temp1<<16)|(Temp2<<8)|Temp3; 
CS_1();              
Delay_us(200);
return TempReturn;

}

//===========================================
static uint8_t CRC8(uint8_t BitValue, uint8_t CRC)
{
uint8_t Temp;
Temp = (uint8_t)(CRC & 0x80);
if (BitValue == 0x01)
{
Temp ^= 0x80;
}
CRC <<= 1;
if (Temp > 0)
{
CRC ^= 0x1D;
}
return CRC;
}
//===================================================
uint8_t CalculateCRC(uint32_t Data)
{
uint8_t BitIndex;
uint8_t BitValue;
uint8_t CRC;
CRC = 0xFF;
for (BitIndex = 31; BitIndex > 7; BitIndex–)
{
BitValue = (uint8_t)((Data >> BitIndex) & 0x01);
CRC = CRC8(BitValue, CRC);
}
CRC = (uint8_t)~CRC;
return CRC;
}
//---------------------------------------------------------
void SCL3300_Init(void)
{
CS_1(); //SPI_SCL3300_CS_HIGH();
Delay_ms(20);
SPI_SCL3300_CMD(SW_RESET); //复位
Delay_ms(5);
SPI_SCL3300_CMD(CHANGE_TO_MODE4); //设置工作模式4
Delay_ms(20);
do
{
StatSensor=SPI_SCL3300_CMD(ENABLE_ANGLE_OUTPUTS); //允许角度输出
Delay_ms(50);
StatSensor=SPI_SCL3300_CMD(READ_STATUS_SUMMARY);
StatSensor=SPI_SCL3300_CMD(READ_STATUS_SUMMARY);
StatSensor=SPI_SCL3300_CMD(READ_STATUS_SUMMARY);
Delay_ms(50);
}
while((retemp[0]&0x03)==0x03);
whoami = SPI_SCL3300_CMD(READ_ID);
whoami = SPI_SCL3300_CMD(READ_ID);
Delay_ms(20);
//whoami=0x4100c136;
whoami= (whoami&0xffffff00);//读whoami寄存器后,CRC判断数据对错。
crcDAT=CalculateCRC(whoami);//0xFFFFC136
Delay_ms(20);
}

while (1)
{
    z= SPI_SCL3300_CMD(READ_TEMPERATURE);
	t = SPI_SCL3300_CMD(READ_ANG_X);
	x = SPI_SCL3300_CMD(READ_ANG_Y);
	y = SPI_SCL3300_CMD(READ_ANG_Z);
    temperature.f = (float)((t >> 8) & 0xffff) / 18.9 - 273;
	x_angle.f = (float)((x>>8 ) & 0xffff) * 90 / 16384;
	y_angle.f = (float)((y>>8 ) & 0xffff) * 90 / 16384;
	z_angle.f = (float)((z>>8)  & 0xffff) * 90 / 16384;
    Delay_ms(600);
}







SCL3300采用SPI协议,但是和普通的SPI协议有所不同,这一次的结果来自上一次的SPI指令。采用OFF-FRAME的协议格式,即对本次请求的响应要在下次请求时才能发送。

SPI传输实在CSB片选下降沿开始的。数据位采样在SCK的上升沿进行。相当于SPI模式0

每次通过SPI向SCL3300发送指令的时候,SCL3300会将上一次指令的处理结果传上来,
上传的数据包括读写标志,地址,RS,数据,以及CRC
我们可通过RS判断状态是否对错,即!=0x03,可进一步读状态寄存器。status summary.

心得,
我们可以先读取WHOami寄存器,来判读到的序列号是否为0XC1, 如果序列号正确,可以初步判断SPI硬件没有问题
第二步可以读取温度寄存器,通过温度和判断数据是否正确
第三步,通过CRC来判断每次的数据格式是否正确
第四步,读取倾角寄存器。

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值