• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

村田 IMU SCC2000系列芯片驱动

武飞扬头像
好活懒人
帮助1

村田 IMU SCC2000系列芯片驱动

一、总体特点

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

学新通

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

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

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

学新通

二、启动时序和逻辑

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的状态

学新通

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模式,下一帧返回上一帧的结果,而我是直接连着发两帧相同的命令这样回传处理就很方便。

学新通

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

学新通

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

学新通

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。

学新通

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;
}

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgjbaai
系列文章
更多 icon
同类精品
更多 icon
继续加载