IIC通讯读取MPU6050

江科大自化协学习记录,本实验利用IIC读取MPU6050数值,并且在OLED屏上显示

代码在最后面,笔者水平一般,各位凑合着看。

首先是OLED显示的代码,底层驱动来自江科大自化协。

链接就放在这里了,喜欢的自取啦:

江科大自化协资料下载:

https://pan.baidu.com/s/1SqKyKr5Fsl_9gBJi8aVxTw

提取码:8kzh,链接里压缩包的解压密码:32

1.IIC通讯

1.1物理层

I2C(同步半双工)通讯协议(Inter-Integrated Circuit)是由 Phiilps(飞利浦) 公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要 USART、 CAN 等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC)间的通讯。

MPU6050固定ID为0x68

为避免被控IC的SDA线和CPU同时输出时电源线短路的问题,统一采用弱上拉电阻配开漏输出的模式。输出低电平时开关MOS导通,处于强下拉的状态,当输出高电平时管脚属于浮空输出的状态,取代了高电平的强上拉输出。为避免这一情况,在VDD接4.1k电阻,处于弱上拉模式。

一个 I2C 总线只使用两条总线线路,一条双向串行数据线(SDA) ,一条串行时钟线(SCL)。数据线即用来表示数据,时钟线用于数据收发同步。

1.2协议层

上图是IIC通讯的基本时序单元。从机捕获到SCL高电平,SDA下降沿时,处于复位状态,等待主机召唤。终止条件时SCL和SDA均处于高电平状态。(释放SDA就是拉高SDA)

高八位发送。

I2C 的数据和地址传输都带响应。响应包括“应答(ACK)”和“非应答(NACK)”两种信号。作为数据接收端时,当设备(无论主从机)接收到 I2C 传输的一个字节数据或地址后,若希望对方继续发送数据,则需要向对方发送“应答(ACK)”信号,发送方会继续发送下一个数据;若接收端希望结束数据传输,则向对方发送“非应答(NACK)”信号,发送方接收到该信号后会产生一个停止信号,结束信号传输。

读写顺序,一般是1位地址和10位地址。

从机地址+读写位,确定哪台设备写入还是读出。send byte:操作地址寄存器。后续是从机应答。

要切换读写方向,只能重置起始位。

1.3MPU6050

1.3.1基本数据

加速度计测量加速度,陀螺仪测量角度。

所有寄存器商店都默认00,除101默认0x40,111默认0x68(ID号0x68),电源管理寄存器1,默认睡眠模式。

1.3.2寄存器

IIC通讯格式:

开始+地址+写+应答+重置+应答+数据段+应答。写同理

第一列和第二列均为寄存器地址,第一列十六进制,第二列十进制。rw代表可读可写,r代表只读。

1.3.2.1SMPLRT_DIV:采样分频寄存器

时钟为内部晶振,外部晶振,外部引脚的方波。本文档以陀螺仪晶振为例。不使用8KHz外部晶振,使用1kHz的晶振。

1.3.2.2CONFIG:配置寄存器

外部同步设置和低通滤波器设置,主要考虑低通滤a波器设置部分。

1.3.2.3GYRO_CONFIG:陀螺仪配置寄存器

高三位为陀螺仪的XYZ轴的使能位。中间是满量程选择位。

自测响应=自测使能数据-自测失能数据

下面是自测响应表,上电时,先使能自测数据,再失能自测读取数据,二者相减得到自测响应。

1.3.2.4ACCEL_CONFIG:加速度计配置寄存器

前两位基本相同,后两位为配置高通滤波器。

数据寄存器,包括加速度计寄存器,温度计寄存器,陀螺仪寄存器。

其余数据均是一样的操作方法,以一个十六位无符号整型的补码变量存在。

1.4根据IIC时序读写MPU6050数值

1.4.1软件IIC底层驱动代码:

代码如下:

在初始化完成后,基本上就可以写IIC通讯的底层驱动了:

起始

按照通讯时序的要求,在开始时先把SCL和SDA都拉高。但是在结束的时候,以SCL时钟线为参考,SDA数据并不总是低电平,为重复起始条件发送时操作成功,需手动把SDA线先拉低到低电平,再操作SCL线。

终止

终止时以时钟线为参考,SDA不总是低电平,需先将SDA拉低,再将其拉高完成终止操作。总结一下就是,在SCL时钟线高电平的期间,SDA数据线不能有任何电平的翻转,若SCL时钟线高电平的期间SDA从低电平拉到高电平则重复开始,从高电平拉到低电平则会认为此时发送数据已结束。

发送八字节数据

按高八位的顺序持续写入数据,直到八个字节的时钟走完。移位运算加括号保证优先级。除终止时序SCL以高电平结束,其他我们都会让他以低电平结束。

接收一个字节的数据:

此时IIC_W_SDA写1是为了释放SDA。因为IIC通信,引脚配置的是开漏输出,且写了1主机依然可以对它进行更改。

发送接收ACK:

测试代码和测试实验现象如下:

读取MPU6050的ID,看是否能读取到,验证代码有没有写错。因为在IIC_Recive_ACK()这个函数中,我们先释放了(IIC_W_SDA(1)),如果收到应答,返回值应该是000,将返回值在OLED屏幕上显示出来如下:

我们的程序没有问题,可以进行下一步的操作。

1.4.2读写MPU6050寄存器

将MPU6050的寄存器都用宏定义封装如下,各变量定义查看1.3.2

写寄存器的具体过程是:起始—>主机发送MPU6050地址_—>收到应答位—>发送寄存器地址—>收到应答位—>发送数据—>收到应答位—>结束

读寄存器过程大致相同,区别只是在于刚开始时要写一下MPU设备地址,叫一下MPU,让他知道我们要和它进行通讯了。

代码如下:

对着手册地址和定义,先使能MPU6050:

再读取它们的值,在OLED屏上显示:

在main函数的主循环中,调用OLED显示函数显示值:

  • 22
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值