村田 IMU SCC2000系列芯片驱动

村田 IMU SCC2000系列芯片驱动

一、总体特点

1、本次具体的型号是村田SCC2130系,IMU有1轴(x)陀螺仪、三轴加速度计和温度计,测量范围陀螺仪±125°/s,加速度±6,温度-50到150。

image-20220313125718602

2、高稳定性,广泛的自诊断等安全保护,因此主要应用都是在一些汽车工业级的场景。

3、32位四线SPI,最大8MHZ通信速度,有CRC校验。

4、硬件针脚图如下,实际上硬件IMU比较大针脚太多,成本高。

image-20220313125128526

二、启动时序和逻辑

1、启动时序也就是驱动IMU初始化,主要是根据状态机的图来实现整个IMU的驱动,本次MCU是采用国产芯片

2、硬件上电复位或者软件复位IO引脚上拉后需要等待20ms后在总状态寄存器设置输出滤波,接着根据两种不同的滤波等待不同的时间,然后需要清除所有的状态寄存器状态,读总状态寄存器看RS位返回状态。正常状态后才可以正常读取IMU数据。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TALJ1CQP-1647160100539)(C:/Users/曾伟荣/AppData/Roaming/Typora/typora-user-images/image-20220313130839320.png)]

3、RS的状态

image-20220313131640775

4、驱动代码

uint16_t HW_MURATA_INIT_TIM_Cnt_u16 = 0;
uint8_t HW_MURATA_INIT_OK_Flag_u8 = 0xEE;
uint8_t HW_MURATA_INIT_TIM_stopFlag_u8 = 0xEE;
void FUN_HW_Murata_IMU_Init()
{
	uint8_t S_agspi_rsdata_u8;
	if(HW_MURATA_INIT_TIM_stopFlag_u8 == 0xEE)
	{
		HW_MURATA_INIT_TIM_Cnt_u16 ++;   // 10ms计数周期
	}
	if(HW_MURATA_INIT_TIM_Cnt_u16 < 2)
	{
		Murata_IMU_SendAndRead(Murata_IMU_HARD_RST);
	}
	else if(HW_MURATA_INIT_TIM_Cnt_u16 < 5)
	{
		Murata_IMU_SendAndRead(Murata_IMU_Status_Summary_10HZ);
	}
	else if(HW_MURATA_INIT_TIM_Cnt_u16 < 10)
	{
		if(HW_MURATA_INIT_OK_Flag_u8 == 0xEE)
		{
			Murata_IMU_SendAndRead(Murata_IMU_RATE_STATUS1);
			Murata_IMU_SendAndRead(Murata_IMU_RATE_STATUS2);
			Murata_IMU_SendAndRead(Murata_IMU_ACC_STATUS);
			Murata_IMU_SendAndRead(Murata_IMU_Common_Status);
			Murata_IMU_SendAndRead(Murata_IMU_Status_Summary);
			StartupOK = TRUE;
			Response_StatSum = 	Murata_IMU_SendAndRead(Murata_IMU_Status_Summary);
			S_agspi_rsdata_u8 = (uint8_t)((Response_StatSum & Murata_IMU_STATUS_MASK) >> 24);
			if(S_agspi_rsdata_u8 != 1)
			{
				StartupOK = FALSE;
			}
			if(!StartupOK)
			{
				Response_RateState1 =Murata_IMU_SendAndRead(Murata_IMU_RATE_STATUS1);
				Response_RateState2 = Murata_IMU_SendAndRead(Murata_IMU_RATE_STATUS2);
				Response_AccStat = Murata_IMU_SendAndRead(Murata_IMU_ACC_STATUS);
				Response_ComStat1 = Murata_IMU_SendAndRead(Murata_IMU_Common_Status);
			}
			HW_MURATA_INIT_OK_Flag_u8 = 0xAA;
		}
	}
	else
	{
		HW_MURATA_INIT_TIM_Cnt_u16 = 0xEEEB;
		HW_MURATA_INIT_TIM_stopFlag_u8 = 0xAA;
	}
}

三、SPI通信和数据读取

1、32位SPI,还是OUT-OFF模式,下一帧返回上一帧的结果,而我是直接连着发两帧相同的命令这样回传处理就很方便。

image-20220313151231223

2、MOSI的读写命令前8位为寄存器地址中间16位为数据,最后八位为CRC校验。

image-20220313151518819

3、官方手册已经给了具体的相关寄存器读写命令可以直接用

image-20220313151945201

4、读取数据代码,本次MCU是国产的芯片上海芯旺微的KF系列,环境啥都还挺好搭建,上手也挺容易。

uint32_t Murata_IMU_SendAndRead(uint32_t data)
{
	uint32_t receive_data;
	SPI_I2S_SendData32(SPI0_COM,data);
	delay_us(2);
	SPI_I2S_SendData32(SPI0_COM,data);
	delay_us(2);
	receive_data = SPI_I2S_ReceiveData(SPI0_COM);

	return receive_data;
}
/*原始数据读取,读取到的数据是补码形式*/
/*x轴角速度*/
x_rate = Murata_IMU_SendAndRead(Murata_IMU_X_RATE);
/*x轴加速度*/
x_acc = Murata_IMU_SendAndRead(Murata_IMU_X_ACC);
/*y轴加速度*/
y_acc = Murata_IMU_SendAndRead(Murata_IMU_Y_ACC);
/*z轴加速度*/
z_acc = Murata_IMU_SendAndRead(Murata_IMU_Z_ACC);
/*温度值*/
temp  = Murata_IMU_SendAndRead(Murata_IMU_TEMP);
/*状态读取*/
rate_status1 = Murata_IMU_SendAndRead(Murata_IMU_RATE_STATUS1);
rate_status2 = Murata_IMU_SendAndRead(Murata_IMU_RATE_STATUS2);
acc_status = Murata_IMU_SendAndRead(Murata_IMU_ACC_STATUS);
common_status = Murata_IMU_SendAndRead(Murata_IMU_Common_Status);
summary_status = Murata_IMU_SendAndRead(Murata_IMU_Status_Summary);

四、数据处理

1、SPI读取到的数据是一个二进制补码,需要我们对数据处理转化为原码。手册上也有处理方法。

2、博世SMI810一样也是原始数据转化为原码后除以sensitivity。

image-20220313161706765

3、数据处理代码

/*数据处理*/
/*x轴角速度处理*/
x_rate_origin = (int32_t)(Murata_IMU_DataProcess(x_rate,x_rate));
S_SPI_yawrate_s16 =(int32_t)(x_rate_origin*2);
/*x,y,z轴加速度处理*/
x_acc_origin = (int32_t)(Murata_IMU_DataProcess(x_acc,x_acc));
S_SPI_accx_s16 = (int32_t)(x_acc_origin*100/1962);

y_acc_origin = (int32_t)(Murata_IMU_DataProcess(y_acc,y_acc));
S_SPI_accy_s16 = (int32_t)(y_acc_origin*100/1962);

z_acc_origin = (int32_t)(Murata_IMU_DataProcess(z_acc,z_acc));
S_SPI_accz_s16 = (int32_t)(z_acc_origin*100/1962);
/*温度处理*/
S_SPI_temperture_s16_last =(int32_t)(Murata_IMU_DataProcess(temp,temp));
S_SPI_temperture_s16 = (int32_t)((S_SPI_temperture_s16_last * 10/ 147 + 60));
uint16_t Murata_IMU_DataProcess(uint32_t input_data,uint32_t input_status)
{
	uint16_t output_data;
	uint16_t output_status;
	uint16_t output_first;
	/*数据处理*/
	output_data = (uint16_t)((input_data & Murata_IMU_DATA_MASK ) >> 8);
	output_first = output_data >> 15;
	if(output_first == 1)
	{
		/*为负数,取反加+1到原码,但输出的uint型仍为正数*/
		output_data = (~output_data) + 1;
		/*转化为负数*/
		output_data = (int16_t)(output_data & 0xFFFF);
		output_data *= -1;
	}
	else
	{
		/*为正数,直接取反码为原码*/
		output_data = output_data;
	}
	/*状态冗余有效性判断*/
	output_status = (uint8_t)((input_status & Murata_IMU_STATUS_MASK)>>24);
	if (output_status != 1)
	{
		spi_imu_status_flag = 1;
		output_data = 0xFFFF;
	}
	return output_data;
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值