你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32驱动MPU6050基于IIC协议

[复制链接]
STMCU小助手 发布时间:2022-8-19 16:32
一. 简介
MPU6050是一款六轴陀螺仪,可以通过IIC协议输出三个方向上的加速度和角速度,在平衡车和飞控中较为常见。一般情况下,模块有用的引脚只有四个(其它的不常用),即VCC,GND,SDA和SCL。操作它的第一步,即编写IIC协议。

二. IIC协议
作为三大常用协议之一,掌握它是非常有必要的。IIC为主从协议,分为主机和从机。IIC协议要比SPI要简单那么一点,没有像SPI那样还有模式的配置。下面就简单说说IIC协议。
SDA: IIC的数据线
SCL:IIC的时钟线

1.空闲态: SDA和SCL都为高电平。
2.起始态: 主机将SDA拉低
3.数据传输: 在SCL为低电平的时候,将数据输出,在SCL为高电平的时候,将数据输入。
4.应答态:在SCL为高电平的时候,检测到SDA为低电平。
5.非应答态:在SCL为高电平的时候,检测到SDA为高电平。
6.停止态:在SCL为高电平的时候,将SDA由低拉高。
IIC协议一共可以分为这六种状态,接下来将简要说明如何将这六种状态组成一个完整的IIC协议,来驱动MPU6050。

(1). IIC写
数据输出是以一个byte为单位的,从机地址一般为七位,与读写标志一起组成一个byte。0为写,1为读。
开始 -》 从机地址 + 0 -》 应答 -》发送寄存器地址 -》 应答 -》 写入数据 -》 非应答(应答) -》 停止

058e22e6615e4634b3cf0bf068e78eb0.png

(2). IIC读
IIC读数据要比IIC写数据要复杂一点,主要是步骤上多了几步,但是状态什么的都完全一样。

开始 -》 从机地址 + 0 -》 应答 -》发送读取寄存器地址 -》 应答 -》开始 -》 从机地址 + 1 -》 读取数据 -》应答 -》 停止

可以看到,只要将这几个状态实现了,按照这个流程就可以很容易实现IIC的读和写。大概的时序图如下。

e33b4e2ddaad4111a83bb7effb127c60.png

三. 代码实现
根据上面的六个状态,定义出对应的六个函数,对应的只有五个,空闲态忽略,因为经过Stop后,IIC的时钟线和数据线都已经为高了。delay时间需要根据从机所能接受的最大速率来决定,不然的话,会出错,下面就来详细说明这几个函数。

7782271f917c44fbb10144c37894ab26.png

(1) MPU6050IICDelay(void)
这就不用说明什么了

  1. void MPU6050IICDelay(void)
  2. {
  3.     uint16_t i = 250;
  4.     while(i--);
  5. }
复制代码

(2) MPU6050IICStart(void)
将SDA配置为输出模式。然后将SCL和SDA全部拉高,dealy后,将SDA拉低,就ok了。

  1. void MPU6050IICStart(void)
  2. {
  3.     SetSDAOut();
  4.     SCLHigh();
  5.     SDAHigh();
  6.     MPU6050IICDelay();
  7.     SDALow();
  8.     MPU6050IICDelay();
  9. }
复制代码

(3) MPU6050IICACK(void)
这里只包含了从机应答。
  1. void MPU6050IICACK(void)
  2. {   
  3.     SCLLow();
  4.     MPU6050IICDelay();
  5.     SetSDAIn();
  6.     MPU6050IICDelay();
  7.     SCLHigh();
  8.     MPU6050IICDelay();
  9.     SDARead();
  10.     MPU6050IICDelay();
  11.     SCLLow();
  12. }
复制代码

(4) MPU6050IICStop(void)
停止位这里,需要先将SCL和SDA都拉低,然后先将SCL拉高,后将SDA拉高,

  1. void MPU6050IICStop(void)
  2. {
  3.     SetSDAOut();
  4.     MPU6050IICDelay();
  5.     SCLLow();
  6.     MPU6050IICDelay();
  7.     SDALow();
  8.     MPU6050IICDelay();
  9.     SCLHigh();
  10.     MPU6050IICDelay();
  11.     SDAHigh();
  12.     MPU6050IICDelay();
  13. }
复制代码

(5) MPU6050IICWrite(void)
  1. void MPU6050IICWrite(uint8_t data)
  2. {
  3.     uint8_t i;
  4.     SetSDAOut();
  5.     MPU6050IICDelay();
  6.     for(i = 0 ; i < 8; i++)
  7.     {
  8.         SCLLow();
  9.         MPU6050IICDelay();
  10.         if(data & 0x80)
  11.             SDAHigh();
  12.         else
  13.             SDALow();
  14.         data = data << 1;
  15.         MPU6050IICDelay();
  16.         SCLHigh();
  17.         MPU6050IICDelay();
  18.     }
  19. }
复制代码

(6) MPU6050IICRead(void)
  1. uint8_t MPU6050IICRead(void)
  2. {
  3.     uint8_t i;
  4.     uint8_t data = 0;
  5.     SetSDAIn();
  6.     MPU6050IICDelay();
  7.     for(i = 0;i < 8; i++)
  8.     {
  9.         SCLLow();
  10.         MPU6050IICDelay();
  11.         SCLHigh();
  12.         MPU6050IICDelay();
  13.         if(SDARead())
  14.             data = data | 0x01;
  15.         else
  16.             data = data | 0x00;
  17.         data = data << 1;
  18.         MPU6050IICDelay();
  19.     }
  20.     return data;
  21. }
复制代码

读写数据,可以搭配时序图来,都是将SCL为低的时候,将数据送出去。在SCL为高的时候,接收数据。
然后将上面的这几个函数依次组合成读写两个函数

d1195f81776b4ed98491a04c6c6498e4.png

这里IIC驱动编写完成。

四. MPU6050 初始化
初始化的实质就是对寄存器进行配置,这就要查看芯片手册,了解每一个寄存器的作用了,以及初始化的时候寄存器配置的顺序。
这里将重要的寄存器列举出来了

  1. #define MPU6050Addr     0xD0
  2. #define ACCEL_XOUT_H    0x3B
  3. #define ACCEL_XOUT_L    0x3C
  4. #define ACCEL_YOUT_H    0x3D
  5. #define ACCEL_YOUT_L    0x3E
  6. #define ACCEL_ZOUT_H    0x3F
  7. #define ACCEL_ZOUT_L    0x40

  8. #define GYRO_XOUT_H     0x43
  9. #define GYRO_XOUT_L     0x44
  10. #define GYRO_YOUT_H     0x45
  11. #define GYRO_YOUT_L     0x46
  12. #define GYRO_ZOUT_H     0x47
  13. #define GYRO_ZOUT_L     0x48

  14. #define PWR_MGMT_1      0x6B
  15. #define PWR_MGMT_2      0x6C
  16. #define SMPLRT_DIV      0x19
  17. #define MPU_CONFIG      0x1A
  18. #define GYRO_CONFIG     0x1B
  19. #define ACCEL_CONFIG    0x1C

  20. #define MPU6050ID       0x75
复制代码

(1). 初始化
  1. /*MPU6050初始化*/
  2. void MPU6050Init(void)
  3. {
  4.     MPU6050GPIOInit();
  5.     MPU6050IICWriteRegister(MPU6050Addr,PWR_MGMT_1,0x80);
  6.     rt_thread_mdelay(100);
  7.     MPU6050IICWriteRegister(MPU6050Addr,PWR_MGMT_1,0x00);
  8.     MPU6050IICWriteRegister(MPU6050Addr,SMPLRT_DIV,0x00);
  9.     MPU6050IICWriteRegister(MPU6050Addr,MPU_CONFIG,0x03);
  10.     MPU6050IICWriteRegister(MPU6050Addr,GYRO_CONFIG,0x18);// gyro scale  :+-2000°/s
  11.     MPU6050IICWriteRegister(MPU6050Addr,ACCEL_CONFIG,0x10);// Accel scale :+-8g (65536/16=4096 LSB/g)  
  12.     MPU6050IICWriteRegister(MPU6050Addr,0x6B,0x01);
  13. }   
复制代码

(2)验证
通过读取芯片的ID,可以确定IIC是否有问题。
  1. /*读取MPU6050的ID*/
  2. uint8_t MPU6050GetId(void)
  3. {
  4.     return MPU6050IICReadRegister(MPU6050Addr,MPU6050ID);
  5. }
复制代码

分享一个成果图

7b2d581155e545f69d7e143901417356.png



收藏 评论0 发布时间:2022-8-19 16:32

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版