【学习记录】IIC驱动ICM42670+卡尔曼滤波+四元数姿态角解算

手把手教你将ICM42670姿态数据接入匿名上位机V7:从串口打印到3D模型实时显示 本文详细介绍了如何将ICM42670姿态数据通过51单片机接入匿名上位机V7,实现从串口打印到3D模型实时显示的完整流程。重点讲解了数据流设计、协议解析、串口传输优化及上位机调试技巧,帮助开发者解决资源受限环境下的工程实践问题,提升姿态数据可视化效果。 阅读详情
AI摘要

该博客记录了使用IIC驱动ICM42670陀螺仪的过程,单片机平台采用GD32f305VE。介绍了iic初始化代码、驱动ICM42670的iic时序,配置好量程、频率和低噪声模式可查实时数据。还提及姿态解算和滤波算法,测试功能正常,但偏航角因无磁力计矫正数据较差。

ICM42670陀螺仪可以使用iic驱动,单片机平台使用GD32f305VE。
在这里插入图片描述

iic初始化代码如下 .c文件

#include "M_IIC.h"
#include <stdio.h>
#include "systick.h"

/*!
    \brief      configure the GPIO ports
    \param[in]  none
    \param[out] none
    \retval     none
*/
void iic_gpio_config(void)
{
   
   
    /* enable GPIOB clock */
	//  gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);
    rcu_periph_clock_enable(RCU_GPIO_I2C);
   // rcu_periph_clock_enable(RCU_AF);
    /* connect PB6 to I2C_SCL */
    /* connect PB7 to I2C_SDA */
    gpio_init(I2C_SCL_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN);
    gpio_init(I2C_SDA_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
}

/*!
    \brief      configure the I2C interfaces
    \param[in]  none
    \param[out] none
    \retval     none
*/
void i2c_config(void)
{
   
   
	  iic_gpio_config();
    /* enable I2C clock */
    rcu_periph_clock_enable(RCU_I2C);
    /* configure I2C clock */
    i2c_clock_config(I2CX, I2C_SPEED, I2C_DTCY_2);
    /* configure I2C address */
    i2c_mode_addr_config(I2CX, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2CX_SLAVE_ADDRESS7);
    /* enable I2CX */
    i2c_enable(I2CX);
    /* enable acknowledge */
    i2c_ack_config(I2CX, I2C_ACK_ENABLE);
}

/*!
    \brief      reset i2c bus
    \param[in]  none
    \param[out] none
    \retval     none
*/
void i2c_bus_reset()
{
   
   
    i2c_deinit(I2CX);
    /* configure SDA/SCL for GPIO */
    GPIO_BC(I2C_SCL_PORT) |= I2C_SCL_PIN;
    GPIO_BC(I2C_SDA_PORT) |= I2C_SDA_PIN;
    gpio_init(I2C_SCL_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, I2C_SCL_PIN);
    gpio_init(I2C_SDA_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    GPIO_BOP(I2C_SCL_PORT) |= I2C_SCL_PIN;
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    __NOP();
    GPIO_BOP(I2C_SDA_PORT) |= I2C_SDA_PIN;
    /* connect I2C_SCL_PIN to I2C_SCL */
    /* connect I2C_SDA_PIN to I2C_SDA */
    gpio_init(I2C_SCL_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN);
    gpio_init(I2C_SDA_PORT, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN);
    /* configure the I2CX interface */
        /* enable I2C clock */
    rcu_periph_clock_enable(RCU_I2C);
    /* configure I2C clock */
    i2c_clock_config(I2CX, I2C_SPEED, I2C_DTCY_2);
    /* configure I2C address */
    i2c_mode_addr_config(I2CX, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2CX_SLAVE_ADDRESS7);
    /* enable I2CX */
    i2c_enable(I2CX);
    /* enable acknowledge */
    i2c_ack_config(I2CX, I2C_ACK_ENABLE);
}

.h文件

#ifndef _CAN
#define _CAN
#include "gd32f30x.h"


#define I2C_SPEED               400000
#define I2CX_SLAVE_ADDRESS7     0xD0
#define I2C_PAGE_SIZE           8

#define I2CX                    I2C1
#define RCU_GPIO_I2C            RCU_GPIOB
#define RCU_I2C                 RCU_I2C1
#define I2C_SCL_PORT            GPIOB
#define I2C_SDA_PORT            GPIOB
#define I2C_SCL_PIN             GPIO_PIN_10
#define I2C_SDA_PIN             GPIO_PIN_11

/* configure the GPIO ports */
//void gpio_config(void);
/* configure the I2C interfaces */
void i2c_config(void);
/* reset i2c bus */
void i2c_bus_reset(void);

#endif

驱动ICM42670的iic时序如下:
在这里插入图片描述
所以开始写ICM42670的驱动
配置的寄存器主要有
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
配置好量程,频率和低噪声模式就可在寄存器中查到实时的数据,读取数据前首先要读取INT_STATUS_DRDY寄存器
确认数据已经准备好,然后是 .c如下:

#include "ICM42670.h"
#include <stdio.h>
#include "systick.h"
//在iic总线上发送起始位
uint8_t iic_start(void){
   
   
    uint16_t timeout=0;
		while(i2c_flag_get(I2CX, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) {
   
   
				timeout++;
		}
		if(timeout < I2C_TIME_OUT) {
   
   
				i2c_start_on_bus(I2CX);
				return 1;
		} else {
   
   
				return 0;
		}
}

//在iic总线上发送从机地址并清除ADDSEND
uint8_t iic_slave_address(uint8_t addr,uint32_t trandirection){
   
   
	 uint16_t timeout=0;
	 while((!i2c_flag_get(I2CX, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) {
   
   
       timeout++;
   }
		if(timeout < I2C_TIME_OUT) {
   
   
			i2c_master_addressing(I2CX,addr, trandirection);
			timeout=0;
			while((!i2c_flag_get(I2CX, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) {
   
   
					timeout++;
			}
			if(timeout < I2C_TIME_OUT) {
   
   
					i2c_flag_clear(I2CX, I2C_FLAG_ADDSEND);//根据要求清除ADDSEND位
        return 1;
			} else {
   
   
				return 0;
			}
		} else {
   
   
			return 0;
		}
}
//查询TBE的方式写入数据,适用与前n-2个数据
uint8_t iic_datasendTBE(uint8_t iic_data){
   
   
	  uint16_t timeout=0;
		while((! i2c_flag_get(I2CX, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
   
   
				timeout++;
		}
		if(timeout < I2C_TIME_OUT) {
   
   
				i2c_data_transmit(I2CX, iic_data);
			return 1;
		} else {
   
   
      return 0;
		}
}
//检测TBC发送
uint8_t iic_datasendTBC(uint8_t iic_data){
   
   
	  uint16_t timeout=0;
		/* wait until BTC bit is set */
		while((!i2c_flag_get(I2CX, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
   
   
				timeout++;
		}
		if(timeout < I2C_TIME_OUT) {
   
   
			i2c_data_transmit(I2CX, iic_data);
			return 1;
		} else return 0;
}
//最后一位数据读取时调用
uint8_t iic_dataread_N_2(uint8_t* p_buffer){
   
   
	  uint16_t timeout=0;
		/* wait until BTC bit is set */
	//	while(!i2c_flag_get(I2CX, I2C_FLAG_BTC));
		/* disable acknowledge */
		i2c_ack_config(I2CX, I2C_ACK_DISABLE);

		/* wait until BTC bit is set */
	//	while(!i2c_flag_get(I2CX, I2C_FLAG_BTC));
		/* send a stop condition to I2C bus */
		i2c_stop_on_bus(I2CX);
		while(timeout<I2C_TIME_OUT) {
   
   
			timeout++;
						/* wait until RBNE bit is set */
			if(i2c_flag_get(I2CX, I2C_FLAG_RBNE)) {
   
   
					/* read a byte from the EEPROM */
					*p_buffer = i2c_data_receive(I2CX);
				  return 1;
					/* point to the next location where the byte read will be saved */
			}
		
		}

		return 0;
}
//前0-N-2个数据调用
uint8_t iic_dataread_N(uint8_t* p_buffer){
   
   
	  uint16_t timeout=0;
		while(timeout<I2C_TIME_OUT) {
   
   
			timeout++;
						/* wait until RBNE bit is set */
			if(i2c_flag_get(I2CX, I2C_FLAG_RBNE)) {
   
   
					/* read a byte from the EEPROM */
					*p_buffer = i2c_data_receive(I2CX);
				  return 1;
					/* point to the next location where the byte read will be saved */
			}
		
MTK 安卓11 传感器兼容 陀螺仪42607-p 处于成本或多样性考虑,经常需要新增传感器进行兼容,本次以陀螺仪icm42607-p型号进行分析 1.如果平台或项目首次使用该传感器,需要添加传感器驱动文件(FAE提供),如果已经存在,直接进行下一步: 文件存放路径: vendor\mediatek\proprietary\tinysys\freertos\source\middleware\contexthub\MEMS_Driver\accGyro\icm4n607.c 2.新增陀螺仪i2c接口、方向、地址及中断号进行配置; mt6771:项目 阅读详情

相关推荐

ICM42670-P嵌入式开发实战:从寄存器配置到姿态解算全解析

本文全面解析ICM42670-P高性能6轴MEMS运动传感器的嵌入式开发实战,涵盖寄存器配置、数据采集滤波、低功耗优化及姿态解算算法。通过详细代码示例和应用案例,帮助开发者快速掌握从硬件对接到姿态跟踪系统的完整开发流程,适用于可穿戴设备和智能家居等低功耗应用场景。

gold的博客 1064

基于STM32L4XX、HAL库的ICM-42670-P姿态传感器驱动程序设计

sprintf(buffer, "温度: %.1f °C\r\n\r\n", sensor_data.temperature);sprintf(buffer, "陀螺仪: X=%.2f Y=%.2f Z=%.2f rad/s\r\n",sprintf(buffer, "加速度: X=%.2f Y=%.2f Z=%.2f m/s²\r\n",sprintf(buffer, "开始校准IMU,请保持传感器静止...\r\n");sprintf(buffer, "读取传感器数据失败\r\n");

zhusl6688的博客 636

姿态传感器/陀螺仪之ICM-42670-P应用原理图设计

ICM-42670-P采用LGA-14封装,尺寸为2.5x3x0.76毫米,工作电压范围为1.71V至3.6V,支持I3CSM、I2C和SPI串行通信接口。其设计目标是提供高精度、低功耗和小型化的解决方案,以满足消费类和工业应用的需求。ICM-42670-P是一款由TDK InvenSense推出的高性能六轴MEMS运动追踪传感器,集成了3轴陀螺仪和3轴加速度计,适用于多种应用场景,包括可穿戴设备、游戏控制器、无人机、AR/VR设备等。

corlin6688的博客 1198

基于STM32、HAL库、I2C接口的姿态传感器/陀螺仪之ICM-42670-P驱动 C语言程序设计

/ 设置加速度计和陀螺仪的工作模式。// 读取加速度计和陀螺仪数据。

corlin6688的博客 1179

ICM-42670-P.pdf

ICM-42670-P数据手册

适用于ICM-42670/ICM-42680等陀螺仪

基于Android/linux平台的专属驱动,适用于ICM-42670/ICM-42680/ICM-42607等型号。 Components ---------- * hardware/invensense/linux-icm20xxx: Linux driver for kernel 3.18/4.4/4.9/4.14/5.4 version 9.2.2-test1 * hardware/invensense/sensors: Android Sensors HAL version icm20xxx-9.3.0-simple-android-linux-test1 * hardware/invensense/firmware: icm4x6xx board config * hardware/invensense/tools: test applications to stream sensor data Linux kernel driver integration ------------------------------- For integration linux

陀螺仪传感器ICM-42607

The ICM-42607-P is a high performance 6-axis MEMS MotionTracking device that combines a 3-axis gyroscope and a 3-axis accelerometer. It has a configurable host interface that supports I3CSM, I2C, and SPI serial communication, features up to 2.25 Kbytes FIFO and 2 programmable interrupts with ultra-low-power wake-on-motion support to minimize system power consumption.

ICM42670驱动与姿态解算[代码]

本文详细介绍了如何使用IIC驱动ICM42670陀螺仪,并在GD32f305VE单片机平台上实现卡尔曼滤波和四元数姿态角解算。内容包括IIC初始化代码、ICM42670驱动时序、寄存器配置以及姿态解算算法的实现。通过卡尔曼滤波对加速度计和陀螺仪数据进行处理,结合四元数微分方程解算姿态角,最终得到稳定的姿态数据。测试结果表明功能正常,但偏航角因缺乏磁力计矫正而精度较差。参考资料包括AT32F421C8T7读取ICM42670数据、Arduino库和哔站教程等。

DSSAT模型建模教程

随着数字农业和智慧农业的发展,基于过程的作物生长模型(Process-based Crop Growth Simulation Model)在模拟作物对气候变化的响应与适应、农田管理优化、作物品种和株型筛选、农业碳中和、农田固碳减排等领域扮演着越来越重要的作用。现有版本V4.7能模拟27种主要农作物的生长发育和产量形成过程,被广泛应用于精细农业、水肥管理、气候变化、粮食安全、土壤碳周转、环境影响、农业可持续性、农业生态等诸多与农业生产和科研有关的领域。如果你是个模型入门者,这次将让你体验一键模拟的乐趣。

weixin_55561616的博客 1413

YooAsset可寻址模式避坑指南:从路径加载到Addressable的完整迁移方案

本文详细介绍了将Unity项目从传统路径加载迁移到YooAsset可寻址模式的完整方案。针对中大型项目在迁移过程中遇到的路径耦合、依赖管理、热更新等痛点,提供了从架构设计、环境配置、代码迁移到性能优化的实战指南,并分享了实际项目的改造案例与避坑经验,帮助团队高效完成资源管理系统的重构。

weixin_28304023的博客 494

LabVIEW电压信号采集系统:从零搭建到科研实战

本文详细介绍了如何从零开始搭建一个基于LabVIEW的电压信号采集系统。内容涵盖硬件选型(如NI USB-6002数据采集卡)、软件环境配置、核心程序开发(包括多通道同步采集、数据自动保存)以及高级功能优化。系统支持自定义采样率与时长,并提供了完整的LabVIEW程序框图和配套的Python数据分析脚本,旨在帮助科研人员和工程师快速构建稳定、高效的专属数据采集方案,提升实验自动化水平。

gold8的专栏 460

正负数据如何归一化_生信干货 | LC-MS代谢组学QI软件下机数据代谢物筛选和归一化如何做?...

上海·2019第一届多层组学前言技术发展华东区客户研讨会倒计时1天LC-MS非靶向代谢组学数据下机啦~~拿到一堆数据怎么办?不会高端代码,也不会自己写脚本,我怎么处理数据?​本期小编带来了LC-MS非靶向代谢组学下机数据处理实用干货,包括:下机定性结果表格的解析、代谢物筛选如何做?以及定量数据如何做归一化?实用干货,赶紧来抢~~话不多说,赶紧来学习吧~~非靶向LC-MS代谢组学的分析流程LC-MS...

weixin_36441329的博客 2982

电子元器件-接口电路篇:RS-232、RS485/422、I2C、SPI、USB、网口

以上规定说明了RS-232C 标准对逻辑电平的定义。对于数据(信息码):逻辑“1”的传输的电平为-3V~-15V,逻辑“0”传输的电平为+3V~+15V;对于控制信号;接通状态(ON)即信号有效的电平为+3V~+15V,断开状态(OFF)即信号无效的电平为-3V~-15V,也就是当传输电平的绝对值大于3V 时,电路可以有效地检查出来;

qq_60226558的博客 887

【CanMV K210】AI 视觉 MNIST 手写数字识别与分类推理

本文介绍了基于CanMV K210开发板的MNIST手写数字识别实验。实验通过摄像头采集图像,经过开窗、灰度化、缩放、反色等预处理后,使用KPU神经网络加速器运行MNIST分类模型,最终在LCD上显示识别结果。重点讲解了分类模型与检测模型的区别、图像预处理流程以及KPU推理结果的解析方法。实验帮助理解从图像采集到分类输出的完整AI视觉处理链路,并提供了调试思路和硬件连接说明。

Mr数据杨 363

WIFI和BT测试(射频工程师)

买不了吃亏买不了上当,我卖的是技能,你收获的是经验。

m0_58834499的博客 599

OpenClaw Windows 安装指南

好的,我来一步一步带你在 Windows 上安装 OpenClaw。

m0_60605453的博客 548

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

上一篇: 【学习记录】嵌入式操作系统中内存分配及任务切换
下一篇: 【学习记录】内存管理之分块内存管理
liarsup
博客等级 码龄6年 251粉丝 33原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值