IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 村田 IMU SCC2000系列芯片驱动 -> 正文阅读

[嵌入式]村田 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;
}
  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:44:59  更:2022-03-15 22:46:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:31:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码