STM32F407 —— 硬件 I2C 驱动的步骤与应用

      最后更新:2022-01-29 22:32

      STM32F407 —— 硬件 I2C 驱动的步骤与应用

      • 一、I2C相关知识
        • 1、物理层
          • (1) 定义
          • (2) 通信方式
        • 2、协议层
          • (1) 空闲状态
          • (2) 起始信号与停止信号的定义
          • (3) 应答信号
          • (4) 数据传输
          • (5) 数据有效性
        • 3、I2C 基本读写过程
          • (1) 主机写数据到从机
          • (2) 主机读从机数据
      • 二、实战应用
        • 1、I2C 驱动 4线 0.96寸 OLED 显示屏
        • 2、I2C 驱动 MS5837 压力传感器

      此篇文章将从理论到实践,对 I2C 通信方式进行理论介绍与实际应用。理论部分主要讲述 I2C 总线的物理结构与其协议中的相关规定及几种不同的通信过程。实践部分将以我们各种开发场合常用到的一个显示模块——4线 0.96寸 OLED 显示屏和本人正在进行的大创项目中用到的 MS5837 压力传感器为例,对在 STM32F407 上如何用 I2C 协议驱动模块进行介绍。这是本人(仅仅是一位刚入门嵌入式的平平无奇的大学生)在 CSDN 的第一篇博文,旨在自己总结相关知识,如有错误,欢迎各位技术大牛批评指正!本人VX:Cyy15880234628。如果能帮到他人,那再好不过啦!

      一、I2C相关知识

      1、物理层

      (1) 定义

      IIC 是 Inter-Integrated Circuit 的缩写,即两线式串行总线,有数据线 SDA 和时钟线 SCL 构成的串行总线,可进行数据的收发。总线结构如图所示:
      在这里插入图片描述

      (2) 通信方式

      由定义可知,其数据线只有一条,所以 I2C 通信采用的是半双工通信,即数据在数据线上可以进行双向传输,但是不能同时收发。(可以想象成一根水管,水可以从左端流向右端,也可以从右端流向左端,但不能同时即从左流向右,又从右流向左,不可兼得哦!)

      2、协议层

      在协议层中,我们先对通信过程中所用到的几个名词所对应的相关规定做个了解。
      (我也只懂这么多,哈哈哈哈,毕竟 I2C 协议不是一天两天读得完的。)

      (1) 空闲状态

      SDA 与 SCL 两条信号线同时处于高电平,这时规定总线处于空闲状态。

      (2) 起始信号与停止信号的定义

      起始信号: SCL 为高电平时,SDA 由高电平跳变为低电平;
      停止信号: SCL 为高电平时,SDA 由低电平跳变为高电平。
      光看文字解释似乎很抽象,来,咱们直接上图(本人自己画的丑图)!
      在这里插入图片描述
      start 表示起始信号,stop 表示停止信号,其实起始信号与停止信号的定义就是用 SDA 与 SCL 的不同组成来表示罢了。(当然,我对这俩规定的理解是,可以把SDA 想象成一个开关的刀,下,即合上,开始传输;上,即断开,停止传输。)

      (3) 应答信号

      发送器发生一个字节,在第九个时钟脉冲期间释放总线,接收器反馈一个应答信号。而应答信号又可分为两种,①有效应答(ACK):应答信号为低电平;②无效应答(NACK):应答信号为高电平。

      (4) 数据传输

      每位数据都有一个时钟脉冲来同步控制,即在 SCL 串行时钟配合下,SDA 逐位地串行传送每一位数据,传输是边沿出发的。

      (5) 数据有效性

      怎样的数据在传输过程中才算有效呢?在时钟信号高电平期间,数据线上的数据保持稳定。(或许又不好理解,那再上图!)
      在这里插入图片描述

      3、I2C 基本读写过程

      主要包括三种通信过程:主机写数据到从机、主机读取从机数据、复合通信(既读又写)。在应用中,主要是前两种通信过程,复合通信很少见,这里我也只介绍前两种,后面驱动实战部分也是对这两种分别举例展示。

      (1) 主机写数据到从机

      通信过程如下图所示:
      在这里插入图片描述
      (有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送。A 表示应答,A 非表示非应答(高电平)。S 表示起始信号,P 表示终止信号。)
      首先,主机产生一个起始信号,开始传输数据。接着,主机向从机发送地址位和读写位(0),确定是哪个从机要接收主机发送的数据。之后就开始从主机向从机发送有效数据,从机根据接收到的数据返回有效应答或无效应答。最后主机产生一个停止信号,表示此次传输结束。
      整个过程就是这样的,我不知道自己是否表述清楚,其实大家也可以类比送快递的一个过程,要知道送去谁家,送什么东西,签收时给一个反馈,在淘宝确认收货表示派送成功,过程终止。这样可能形象一点。

      (2) 主机读从机数据

      通信过程如下图所示:在这里插入图片描述(有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送。A 表示应答,A 非表示非应答(高电平)。S 表示起始信号,P 表示终止信号。)
      大体过程与主机写数据到从机上差不多,大家自行类比理解哈,要注意的点就是数据和应答信号是谁发给谁。

      二、实战应用

      1、I2C 驱动 4线 0.96寸 OLED 显示屏

      这个模块相信大家并不陌生,小型而又低功耗,运用范围十分广泛。现在关于这个模块在STM32F1系列上的实现源码很多,但在STM32F4系列上的实现源码很少,还是有很多人不懂得移植或者移植不成功,也当作是一个半开源了吧。
      话不多说,开始讲思路!
      其实就是按照前面所讲的对应的通信过程和相关协议规定来配置,再配合OLED的数据手册,编写移植显示的函数即可。
      驱动该模块的流程图就是主机写数据到从机的通信过程,再放一遍图吧(把良心打在公屏上)
      在这里插入图片描述
      通信过程的配置就按照下面这部分代码配置即可,注释个人觉得挺清楚的了。

      起始信号的定义:

      停止信号的定义:

      等待应答信号:

      有效应答与无效应答的定义:

      根据数据手册又可编写一些显示函数,如下:

      当然,要使用该模块之前要记得对其进行初始化哦!初始化函数如下:

      这样,OLED 显示屏就配置好了,我调试过了,亲测可用。

      2、I2C 驱动 MS5837 压力传感器

      由于大创需要,这个传感器可是我找了半天才找到符合需求的模块。也许大家用不到,但其驱动原理与其他模块是一样的。
      该模块的驱动与OLED类似,只需要改写下地址位和读写位即可。

      关于 I2C 相关内容我就介绍这么多,也许文中有很多表述不清楚,还请大家指出或者联系我,大家一起进步,一起向嵌入式攻城狮迈进!!!

      本文由 在线网速测试 整理编辑,转载请注明出处。

          热门文章

          文章分类