STM32基础回顾——详解I²C(GPIO模拟I2C)

      最后更新:2022-02-22 02:10:16 手机定位技术交流文章

      文章目录

      • 前言
      • IIC协议
          • 数据有效性
          • 开始信号和结束信号
          • 应答信号
          • 完整传输流程
        • EEPROM介绍
          • 结构组成
          • 设备地址
          • 写AT24Cxx
          • 读AT24Cxx
        • IIC模拟硬件设计
        • IIC模拟软件设计
        • 源码解析
      • 运行结果
      • 源码

      前言

      这一篇博客是根据自己的需要,以及为了面试岗位的需求,所以专门来再次学习一遍SPI和IIC两个常用的通信协议。这里使用的开发板是STM32F03_MIN
      也希望这篇博客能对你有一定的帮助!

      IIC协议

      I²C ,通常被读作“I方C”,它是一种多主从架构的串行通信总线。在1980年由飞利浦公司设计,用于让主板,嵌入式系统或手机连接低速周边设别。如今在嵌入式领域是非常常见的通信协议。常用于MPU/MCU与外部设备连接通信,数据传输。

      IIC由两条线组成,一条双向串行数据线SDA,一条串行时钟线SCL。每个连接到总线的设备都有一个独立的地址,主机可以通过这个地址来访问不同的设备。因为IIC协议比较简单,常常用GPIO来模拟IIC时序,这种方法称为模拟IIC。如果使用MCU的IIC控制器,设置好IIC控制器,IIC控制器就自动实现协议时序,这种方式称为硬件IIC。因为IIC设备的速率比较低,通常两种方式都可以,模拟IIC方便移植,硬件IIC工作效率相对较高。

      关于IIC协议,通过老师传学生足球的例子相信大家可以清晰的理解
      在这里插入图片描述把老师看作MCU/MPU,学生看作外设设备。
      首先老师将球踢给某学生,即主机发送数据给从机,步骤如下:

      1. 老师:开始了(start);
      2. 老师: A!我要发球给你! (地址/方向);
      3. 学生A:到! (回应);
      4. 老师把球发出去(传输);
      5. A收到球之后,应该告诉老师一声(回应);
      6. 老师:结束(停止);
        MCU发送数据,需要得到设备的回应,当数据发送完成,MCU自动停止发送,设备也无需回应。

      接着老师让学生把球传给自己,即从机发送数据给主机,步骤如下:

      1. 老师:开始了(start);
      2. 老师: B!把球发给我! (地址/方向);
      3. 学生B:到!
      4. B把球发给老师(传输);
      5. 老师收到球之后,给B说一声,表示收到球了(回应);
      6. 老师:结束(停止)。

      MCU接收外设设备传输的数据时,首先时MCU发送指令让设备发送数据的信号,设备收到后,响应MCU,同时MCU接收到数据时也要回应外设设备。当数据传输完成,MCU自动结束传输。

      从上面的例子可知,都是老师(主机)主导传球,按照规范的流程(通信协议),以保证传球的准确性,收发球的流程总结如下:
      ① 老师说开始了,表示开始信号(start);
      ② 老师提醒某个学生要发球,表示发送地址和方向(address/read/write);
      ③ 该学生回应老师(ack);
      ④ 老师发球/接球,表示数据的传输;
      ⑤ 收到球要回应:回应信号(ACK);
      ⑥ 老师说结束,表示IIC传输结束§。

      数据有效性

      IIC由两条线组成,一条双向串行数据线SDA,一条串行时钟线SCL。SDA线上的数据必须在时钟的高电平周期保持稳定,数据线的高或低电平状态只有在SCL线的时钟信号是低电平时才能改变。换言之,SCL为高电平时表示有效数据,SDA为高电平表示“1”,低电平表示“0”;SCL为低电平时表示五有效数据,此时SDA会进行电平切换,为下一次数据表示做准备。如下图
      在这里插入图片描述

      开始信号和结束信号

      IIC起始信号(S):当SCL高电平时,SDA由高电平向低电平转换;
      IIC停止信号(P):当SCL为高电平时,SDA由低电平向高电平转换;

      在这里插入图片描述

      应答信号

      IIC每次传输的8位数据,每次传输后需要从机反馈一个应答位,以确认从机是否正常接收了数据。当主机发送了8位数据后,会再产生一个时钟,此时主机放开SDA的控制,读取SDA电平,在上拉电阻的影响下,此时SDA默认为高,必须从机拉低,以确认收到数据。
      在这里插入图片描述

      完整传输流程

      IIC完整传输流程如下:

      1. SDA和SCL开始都为高,然后主机将SDA拉低,表示开始信号;
      2. 在接下来的8个时间周期里,主机控制SDA的高低,发送从机地址。其中第8为如果为0,表示接下来是写操作,即主机传输给从机;如果是1,表示接下来是读操作。即从机传输数据给主机(确定传输方向);另外,数据传输是从高位到最低位,因此传输方式位MSB
      3. 总线中对应从机地址的设备,发出应答信号;
      4. 在接下来的8个时间周期里,如果是写操作,则主机控制SDA的高低;如果是读操作,则从机控制SDA的高低;
      5. 每次传输完成,接收数据的设备,都发出应答信号;
      6. 最后SCL为高时,主机由低拉高,整个传输结束。

      EEPROM介绍

      EEPROM的全称是“电可擦除可编程只读寄存器”。通常用于存放用户配置信息数据,比如在开发板首次运行时,需要屏幕校准,校准后的配置信号就可以保存在EEPROM里,开发板断电后不丢失,下次启动,开发板自动读取EEPROM的校准配置信息,就不需要重新校准。

      EEPROM和Flash的本质是一样的,Flash包括MCU内部的Flash和外部扩展的Flash,本开发板就有一个SPI接口的外部Flash,SPI后面会进行介绍。从功能上,Flash通常存放运行代码,运行过程中不会修改,而EEPROM存放用户数据,可能会反复的修改。从结构上,Flash按扇区操作,EEPROM通常按字节操作。两者区别这里就不再过多的讲,理解EEPROM在嵌入式中扮演的角色即可。

      结构组成

      在这里插入图片描述

      设备地址

      IIC设备都会有一个设备地址,不同容量的ATC2402,设备地址定义会有所差异,由数据手册可知

      在这里插入图片描述
      AT24C02的容量为2K,对应上图中的第一行,高四位固定为“ 1010”,中间三位由A2、 A1、 A0引脚的电平决定,比如A2~0引脚全接地,则值为“000”,最后的最低位为读写位, 0代表写命令, 1代表读命令。A2、 A1、 A0引脚电平需要由原理图决定,假设全接电源地,则如果需要向AT24C02写数据,则发送地址“ 1010 0000”,如果需要向AT24C02读数据,则发送地址“ 1010 0001”。
      假设开发板有多个AT24C02挂在同一I²C总线上,通过这个规则,只需设计电路时,让A2、 A1、 A0引脚电平不同,即可区分两个AT24C02。

      对于容量再大一点的AT24Cxx系列,比如AT24C04,器件地址由A2、 A1引脚决定,数据空间有P0决定。比如对AT24C04的02K空间操作,则P0为0,对2K4K空间操作,则P0为1。

      写AT24Cxx

      AT24Cxx支持字节写模式和页写模式。字节写模式是一个地址一个数据的写;页写模式是连续写数据,一个地址多个数据的写,但是页写模式不能自动跨页,如果超出一页,超出的数据会覆盖原先写入的数据。

      如下图为AT24Cxx字节写模式的时序
      在这里插入图片描述在MCU发出开始信号( Start)后,发出8 Bit的设备地址信息(图中读写位为低电平,即写数据),待收到AT24Cxx应答信号后,再发出要写的数据地址,再次等待AT24Cxx应答,最后发出8 Bit数据写数据,待AT24Cxx应答后,发出停止信号( Stop),完成一次单字
      节写数据。

      AT24C02容量为2K。因此数据地址范围为0x00~0xFF,即0 ~ 255,每个数据地址每次写1Byte,即8bit,也就刚好2048bit。对于1K容量的产品,数据地址范围为0x00 ~ 0x7F,最高位不会用到,因此下图中数据地址的最高位用“*”表示,意思就是不用关心,不会用

      在这里插入图片描述

      AT24Cxx的页写模式时序,如下图,与字节写模式的差异在于,不是只发送以Byte数据,而是任意多个,需注意,该模式不能跨页写,遇到跨页时,需要重新发送完整的时序。
      在这里插入图片描述值得一提的是, 《AT24Cxx.pdf》 里提到每次写完之后,再到下次写之前,需要间隔5ms时间, 以确保上次写操作在芯片内部完成
      在这里插入图片描述

      读AT24Cxx

      AT24Cxx支持当前地址读模式、随机地址读模式和顺序地址读模式。
      当前地址读模式:就是在上一次读/写操作之后的最后位置,继续读出数据,比如上次读/写在地址n,接下来可以直接从n+1除读出数据;
      随机地址读模式:是指定数据地址,然后读出数据;
      顺序读模式:是连续读出多个数据。

      在当前地址读模式下,无须发送数据地址,数据地址为上一次读/写操作之后的位置,如下所示
      在这里插入图片描述注意:主机接收到数据后,无需产生应答信号。

      在随机地址读模式下,需要先发送设备地址,待读的数据地址,接着再重新发出信号,设备地址,读出数据
      在这里插入图片描述
      在顺序读模式下,需要先从当前地址读模式或随机地址读模式启动,随后可以连续读多个数据,时序如下
      在这里插入图片描述

      IIC模拟硬件设计

      在这里插入图片描述U6为AT24C02芯片,它的A0、 A1、 A2都接地,因此该设备地址为“ 1010 000X”,当读该设备时, X为1,写该设备时, X为0。

      U4的7脚为写保护引脚( Write Protect, WP),当该引脚为高,则禁止写AT24C02,这里直接拉低WP,任何时候都可直接写AT24C02。

      此外, I2C的两个脚SCL和SDA都进行了上拉处理,从而保证I2C总线空闲时, 两根线都必须为高电平。
      如果没有上拉,在主机发送完数据后,放开SDA,此时SDA的电平状态不确定,可能为高,也可能为低,无法确定是从机拉低给出应答信号。

      IIC模拟软件设计

      通过GPIO模拟I2C总线时序,对EEPROM设备AT24C02进行读写操作。

      1. 引脚初始化: GPIO端口时钟使能、 GPIO引脚设置为输入/输出模式( PB6、 PB7);
      2. 封装I2C每个环节的时序函数:起始信号、响应信号、读写数据、停止信号;
      3. 使用I2C协议函数,实现对AT24C02的读写;
      4. 主函数,每按一次按键,写一次AT24C02,接着读出来验证是否和写的数据一致;

      源码解析

      i2c.h
      在这里插入图片描述
      i2c.c

      eeprom.h

      eerom.c

      timer.h

      timer.c

      main.c

      运行结果

      在这里插入图片描述

      源码

      Git

      本文由 在线网速测试 整理编辑,转载请注明出处,原文链接:https://www.wangsu123.cn/news/18790.html

          热门文章

          文章分类