惯导系列(一):STM232 IIC读取MPU数据

本文介绍了STM32使用模拟IIC与MPU6050和MPU9250进行通讯的过程,包括IIC通讯的基本概念、模拟IIC的实现函数以及MPU外设的介绍。作者强调了模拟IIC的注意事项,如端口配置和连线正确性,并提到了可能遇到的bug和解决建议。此外,文章还概述了代码实现和调试方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

消失了几天的我在哪?对,没错,就在实验室默默的调试代码。
折磨我几天的MPU终于弄好了(虽然只是弄好一半,但是也是值得令人开心的)


本节介绍

本节主要介绍关于stm32使用IIC来读取mpu数据的过程,准确来说是模拟IIC读取mpu6050以及9250的相关过程


一、IIC通讯

1.1 IIC通讯简介

简单来说IIC是一种通讯方式,一般的连线方式是这样的。

 也就是说IIC需要三根线对外设进行通讯。SCL、SDA以及GND。在使用模块的时候可能会有其他的要求,比方说接5V,或者接地,这部分在开发的时候再进一步叙述。因为版权问题,IIC在STM32中设计的比较复杂(这部分看杨桃的IIC代码就明白了),最然说直接用就行了,但是还需要稍微懂一些。所以我们一般使用模拟IIC实现IIC的通讯功能。模拟IIC这里不给出代码,但是会解释有哪些步骤

1.2 模拟IIC

void IIC_Init(void);                //初始化IIC的IO口				 
void IIC_Start(void);				//发送IIC开始信号
void IIC_Stop(void);	  			//发送IIC停止信号
void IIC_Send_Byte(u8 txd);			//IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); 				//IIC等待ACK信号
void IIC_Ack(void);					//IIC发送ACK信号
void IIC_NAck(void);				//IIC不发送ACK信号

这是模拟IIC实现函数,有些代码中可能有一些延时,没得关系。
实际使用的使用还有一些坑:

  • 1模拟IIC虽然不是真正的IIC,但是仍然也需要在原来的IIC端口上面才能开模拟IIC(我是这样觉得的)
  • 2一定要注意你的芯片IIC端口,和你代码的IIC端口要一致(比方说下面的代码就是PC12、PC11端口)连线更不能错。
//IO方向设置
#define SDA_IN()  {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}
#define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}

//IO操作函数	 
#define IIC_SCL    PCout(12) //SCL
#define IIC_SDA    PCout(11) //SDA	 
#define READ_SDA   PCin(11)  //输入SDA 

关于IO端口方向问题,建议看这位博主的介绍:(59条消息) GPIOB->CRH&=0XFFFF0FFF;GPIOB->CRH|=(u32)8<<12;(学习笔记)_gpiob->crh_浦子哥的博客-优快云博客

1.3 mpu外设

这一块直接介绍两个外设:mpu6050以及9250,因为还不做开发,所以先说一下模块:

IIC连接上面四根线就行了(9250连线也是这样)

6050主要是三轴陀螺仪与三轴加速度计组成
9250是6500(类似6050)结合磁力计组成

在设计过程中6050可以使用IIC,9250不仅可以使用IIC还可以使用spi(通讯方式)

DMP是MPU模块中官方设计的一个固件装置,这个装置对于新手比较友好,比方说能够固件滤波。9250固件库甚至有直接换成算四元素的封装函数。但是,即使优点那么多,我们还是需要使用原始数据的。(因为我们要实现更加准确的滤波算法)后面会实现位姿准换以及滤波实现。

模拟IIC对于MPU设定的ID和实际地址:

9250:
#define MPU9250_ADDR            0X68    //MPU6500的器件IIC地址
磁力计的ID地址比较复杂
6050:
//如果AD0脚(9脚)接地,IIC地址为0X68(不包含最低位).
//如果接V3.3,则IIC地址为0X69(不包含最低位).
#define MPU_ADDR				0X68

 二、实现

实现模拟IIC读取MPU的逻辑:
STM32采用IIC对MPU建立通讯,然后使用USART串口实现调试(也可以使用LCD显示屏)

2.1 代码实现

实际代码初始化MPU以及模拟IIC(模拟IIC可以放在MPU中初始化)然后在mpu的驱动函数中直接找出读取的数据然后放在主函数定义的数据里面就行了,具体说就是

MPU_Get_Accelerometer()
MPU_Get_Gyroscope()

printf()打印给串口调试工具就行了

2.2 BUG

可能出现的bug问题:

  • 一定要注意:你是否成功初始化了MPU以及模拟IIC两部分,是否能够运行到while(1)循环(因为你器件的问题就不会初始化结束卡住了),建议在while里面放一个LED0=!LED0来提示系统正在运行。
  • 你的模拟IIC定义的引脚还有MPU模块连线是否有问题,很大有可能复制别人模块忘记调端口了,导致芯片的IIC端口不对,或者设置的端口就不是你连接的端口
  • 你的器件模块一旦AD0接线了那你的MPU的ID地址就不对了
  • IIC端口设置为开漏输出(不一定有用)。正点官方是推挽输出。之前看了别人的博客说是需要设定为开漏输出,也就是这里:
    void IIC_Init(void)
    {					     
    	GPIO_InitTypeDef GPIO_InitStructure;
    	//RCC->APB2ENR|=1<<4;//先使能外设IO PORTC时钟 
    	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOC, ENABLE );	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_11;
    	//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//开漏输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOC, &GPIO_InitStructure);
    	IIC_SCL=1;
    	IIC_SDA=1;
    }

 上述是仅仅从模拟IIC与MPU建立通讯的角度来谈的,后面博客还会进一步就滤波还有频率问题仔细的研究。代码因为涉及版权就不放出来了。

三、感谢

感谢这些博主还有官网的支持
正点原子
杨桃电子
(59条消息) STM32 软件模拟IIC_stm32模拟iic_一个旅者的博客-优快云博客
【快速入门】MPU6050工作原理及应用_哔哩哔哩_bilibili

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值