笔记(七)IIC

1、IIC协议介绍

1.物理层

串行同步全双工

它的物理层有如下特点:

(1) 它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯总线中,可连接多个 I2C 通讯设备,支持多个通讯主机及多个通讯从机。

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

(3) 每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问。

(4) 总线通过上拉电阻接到电源。当 I2C 设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。

这里是线与的特性,线与功能主要用于有多个电路对同一信号进行拉低操作的场合,如果本电路不想拉低,就输出高电平,因为OPEN-DRAIN上面的管子被拿掉,高电平是靠外接的上拉电阻实现的。 (而正常的CMOS输出级,如果出现一个输出为高另外一个为低时,等于电源短路。

线与可以避免下面这种电源短路的情况,线与只要有一个低电平,总线就会被拉低,其余设备即使是高阻态,也不会形成回路,总线依旧是低电平。

线与这块可以看下GPIO那块,GPIO那块理解了,这里就差不多。

(5) 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。

空闲时设备输出高阻态,当与主机通信时,会将总线拉低,这时候当在有别的设备想与主机进行通信时,就会先检测总线的状态,如果为低,则需要等待当前设备通信完成才能通信

(6) 具有三种传输模式:标准模式传输速率为 100kbit/s ,快速模式为 400kbit/s ,高速模式下可达 3.4Mbit/s,但目前大多 I2C 设备尚不支持高速模式。

(7) 连接到相同总线的 IC 数量受到总线的最大电容 400pF 限制 。

2.协议层

2.1基本读写过程

先由主机的 I2C 接口发送的传输起始信号,I2C 总线上所有从机都会接收到这个信号,起始信号产生后所有从机就开始等待主机紧接下来广播 的从机地址信号,在 I2C 总线上,每个设备的地址都是唯一的, 当主机广播的地址与某个设备地址相同时,这个设备就被选中了,没被选中的设备将会忽略之后的数据信号。根据 I2C 协议,这个从机地址可以是 7 位或 10 位。地址之后,就是读写位,0代表写,主机向从机写数据;1代表读,数据传输方向是由主机传输至从机,这里选择0,一般一个字节是8位,所以有时候读写位会和7位地址放到一起,需要注意一下。从机接收到地址后,会返回给主机一个应答信号,ACK是应答,NACK是非应答,只有接收到应答信号后从机才能将数据发送给主机,应答信号以后就是数据数据包大小为8位,当主机接收到了数据以后,会给从机一个应答,每发完一个数据都要等待应答信号,可以发送N个数据。当传输结束时,主机会发送一个结束信号,表示不再传输数据。注意起始信号和终止信号都由主机发送。

主机发送起始信号,接着发送从机地址,选定从机,发送读写位为0,传输方向是主机向从机写数据,从机给主机一个应答,主机收到应答以后就可以向从机传输数据,每传一个数据就要等待从机的应答,最后主机发送终止信号表示传输完成。

复合模式需要先向从机写地址,在读里面的数据,有两个起始信号,第一个起始信号后的从机地址选定从机设备,是eeprom还是触摸屏,还是传感器这些从及设备,紧接着会发送一段数据,这个数据表示去到对应从机内部的寄存器或存储器,举个例子,我们想知道班里小明的数学成绩,slave address就代表你选中了小明这个人,那么到底是要知道小明的哪科成绩呢,这里的这段数据就代表数学,如果我们要读取EEPROM里0x78这个地址的数据,EEPROM就是小明,0x78这段地址的寄存器就是数学,选定好要读取的位置以后,就可以对具体的数据进行读写了,这时候再由主机发送起始信号开始对具体位置进行读取写操作。这里要重点理解从机地址和从机内部的存储器或存储器地址的区别。

2.2通讯的起始信号和停止信号

当 SCL 线是高电平时 SDA 线从高电平向低电平切换,这个情况表示通讯的起始。当 SCL 是高电平时 SDA线由低电平向高电平切换,表示通讯的停止。起始和停止信号由主机产生。

起始和停止都需要在时钟线高电平时产生,SDA下降沿表示起始,SDA上升沿表示停止。这样好记一点

2.3数据的有效性

SCL高电平时,SDA的数据才有效,黄色区域SDA的两条线表示,SDA既可以是高电平,也可以是低电平,高电平就是1,低电平就是0。蓝色区域表示SDA的数据无效,可以在这段时间进行数据变化。

2.4地址及数据方向

I2C 总线上的每个设备都有自己的独立地址,主机发起通讯时,通过 SDA 信号线发送设备地址(SLAVE_ADDRESS)来查找从机。 I2C 协议规定设备地址可以是 7 位或 10 位,实际中 7 位的地址应用比较广泛。紧跟设备地址的一个数据位用来表示数据传输方向,它是数据方向位(R/W),第 8 位或第 11 位。数据方向位为“ 1”时表示主机由从机读数据,该位为“ 0”时表示主机向从机写数据。

读数据方向时,主机会释放对 SDA 信号线的控制,由从机控制 SDA 信号线,主机接收信号,写数据方向时, SDA 由主机控制, 从机接收信号。

2.5响应

传输时主机产生时钟,在第 9 个时钟时,数据发送端会释放 SDA 的控制权,由数据接收端控制 SDA,若 SDA 为高电平,表示非应答信号(NACK),低电平表示应答信号(ACK)。

2、STM32 的 I2C 特性及架构

1.架构剖析

1.1通讯引脚

STM32 芯片有多个 I2C 外设,它们的 I2C 通讯信号引出到不同的 GPIO 引脚上,使用时必须配置到这些指定的引脚,引脚定义在STM32F103xCDE中文手册这个文档里

1.2时钟控制逻辑

SCL线的时钟信号,由I2C接口根据时钟控制寄存器(CCR)控制,控制的参数主要为时钟频率。

模式选择在第15位F/S,“标准/快速”模式分别 I2C 对应 100/400Kbit/s 的通讯速率。

位14DUTY占空比的选择要在F/S是快速模式下,可选 Tlow/Thigh=2 或 Tlow/Thigh=16/9 模式,对于传感器来说,16/8和16/9都差不多。 Tlow/Thigh就是在一个时钟周期内,低电平和高电平的比值

时钟周期实际上是12位的配置因子CCR控制的

TPCLK1=APB1的时钟,IIC是挂载到APB1总线上的,所以时钟周期是36MHz

如果在快速模式下,选择占空比为2,时钟为400Kbit/s那么SCL线时钟=2*CCR*TPCLK1=400Kbit/s,还需要进行单位换算,36MHz=36000000Hz,400Kbit/s=400000Hz

1.3数据控制逻辑

I2C 的 SDA 信号主要连接到数据移位寄存器上,数据移位寄存器的数据来源及目标是数据寄存器(DR)、地址寄存器(OAR)、 PEC 寄存器以及 SDA 数据线。当向外发送数据的时候,数据移位寄存器以“数据寄存器”为数据源,把数据一位一位地通过 SDA 信号线发送出去,且高位先行;当从外部接收数据的时候,数据移位寄存器把 SDA 信号线采样到的数据一位一位地存储到“数据寄存器”中。

当 STM32 的 I2C 工作在从机模式的时候,接收到设备地址信号时,数据移位寄存器会把接收到的地址与 STM32 的自身的“ I2C 地址寄存器”的值作比较,以便响应主机的寻址。 STM32 的自身 I2C 地址可通过修改“自身地址寄存器”修改,支持同时使用两个 I2C 设备地址,两个地址分别存储在 OAR1 和 OAR2 中。PEC不讲

1.4整体控制逻辑

整体控制这里,掌握寄存器相应位的意义就好,下面会详细说

2.通讯过程

IIC慢,stm32快,stm32每完成一次任务后,都要读取SR1寄存器的相应位,以确保每一个任务完成,stm32作为IIC的主设备,所以只介绍了主发送器和主接收器

下面是通讯会用到的SR1寄存器

2.1主发送器

(1)首先产生起始信号S,当起始信号发出后,会产生EV5,EV5是SR1寄存器里的第0位SB位,此时SB=1,表示起始信号以发送。

(2)主设备等待读SR1寄存器,紧接着发送地址和应答信号,如果有从机应答,则产生事件 EV6和 EV8,

此时EV6,EV8都为1,EV6是ADDR位,在收到ACK位以后被置一,表示地址发送完成;EV8表示数据寄存器为空,接下来就可以发送数据1了。

(3)清除ADDR位后, 向数据寄存器DR写入数据,此时TXE位为0(TxE清除方法),表示数据寄存器非空;I2C 外设通过SDA 信号线一位位把数据发送出去,此时产生EV8事件,TXE=1,因为数据发完了,数据寄存器此时又为空。重复这个步骤,即可传输多个数据。

(4)数据完成后,不仅触发EV8事件,还有EV8_2,EV8检测数据寄存器是否为空,EV8_2是BTF位,BTF=1表示字节发送完成,因为数据寄存器为空了,但是数据移位寄存器里可能还在一位一位的传输数据,所以要检测一下数据移位寄存器是否为空,为空则表示数据传输完成了,这时产生一个停止信号,表示通讯结束。

假如我们使能了 I2C 中断,以上所有事件产生时,都会产生 I2C 中断信号,进入同一个中断服务函数,到 I2C 中断服务程序后,再通过检查寄存器位来了解是哪一个事件。

2.2主接收器

(1)首先还是主机产生起始信号S,当起始信号发出后,会产生EV5,EV5是SR1寄存器里的第0位SB位,此时SB=1,表示起始信号以发送。

(2)紧接着发送地址和应答信号,如果有从机应答,则产生事件 EV6,此时EV6为1,EV6是ADDR位,在收到ACK位以后被置一,表示地址发送完成。

(3)清除ADDR位后, 接收从从机发来的数据,等到主机的应答以后,产生事件EV7,此时RXNE=1,表述数据寄存器非空,意味着数据在SDA线上,经过数据移位寄存器到达数据寄存器。这一步,我们可以控制 I2C 发送应答信号(ACK)或非应答信号(NACK),ACK在CR1寄存器的第10位配置。若应答,则重复以上步骤接收数据,若非应答,则停止传输

(4)为了在收到最后一个字节后产生一个NACK脉冲,在读倒数第二个数据字节之后(在倒数第二个RxNE事件之后)必须清除ACK位。同时为了产生一个停止/重起始条件,软件必须在读倒数第二个数据字节之后(在倒数第二个RxNE事件之后)设置STOP/START位。为了达到这两个目的,在倒数第二个数据字节后产生EV7_1事件,EV7_1表示RxNE=1,读DR寄存器清除该事件。并且设置ACK=0和STOP=1。发送非应答信号后,还会产生EV7,表示最后一个信号也接受到数据寄存器里,再把最后一个数据接收到内存,产生停止信号(P),结束传输。

标志位用完之后记得清除,以便影响下一次通讯。

3、I2C 初始化结构体

(1) I2C_ClockSpeed

设置I2C传输速率,数值小于400都没问题,实际上由于 CCR 寄存器不能写入小数类型的时钟因子,影响到 SCL 的实际频率可能会低于本成员设置的参数值,这时除了通讯稍慢一点以外,不会对 I2C 的标准通讯造成其它影响。,标准快速模式直接通过数值选好了

(2) I2C_Mode

这里的模式不是标准模式和快速模式,而是I2C或SMBus模式的选择,有以下四种模式可以选择stm32f10x_i2c.h可以看到,因为这里用I2C所以选择第一个。I2C不需要在此处区分主从模式,直接设置 I2C_Mode_I2C 即可。

(3) I2C_DutyCycle

这里设置I2C 的 SCL 线时钟的占空比。该配置有两个选择,分别为低电平时间比高电平时间为 2: 1 ( I2C_DutyCycle_2)和 16: 9 (I2C_DutyCycle_16_9)。其实这两个模式的比例差别并不大,一般要求都不会如此严格,这里随便选就可以了。

(4) I2C_OwnAddress1

这里配置的是 STM32 的 I2C 设备自己的地址,每个连接到 I2C 总线上的设备都要有

一个自己的地址,作为主机也不例外。 地址可设置为 7 位或 10 位(受下面I2C_AcknowledgeAddress 成员决定),只要该地址是 I2C 总线上唯一的即可。STM32 的 I2C 外设可同时使用两个地址,即同时对两个地址作出响应,这个结构成员I2C_OwnAddress1 配置的是默认的、 OAR1 寄存器存储的地址,若需要设置第二个地址寄存器 OAR2,可使用 I2C_OwnAddress2Config 函数来配置, OAR2 不支持 10 位地址。

(5) I2C_Ack_Enable

这里设置I2C 的应答,设置为使能则可以发送响应信号。 该成员值一般配置为允许应答(I2C_Ack_Enable),这是绝大多数遵循 I2C 标准的设备的通讯要求,改为禁止应答(I2C_Ack_Disable)往往会导致通讯错误。

(6) I2C_AcknowledgeAddress

这里设置I2C 的寻址模式是 7 位还是 10 位地址。这需要根据实际连接到 I2C 总线上设备的地址进行选择,这个成员的配置也影响到 I2C_OwnAddress1 成员,只有这里设置成10 位模式时,I2C_OwnAddress1 才支持 10 位地址。I2C总线上的数据长度要一样,不一样会出错。

4、EEPROM简介

在笔记一里简单说过EEPROM是什么,这里介绍一下指南者上的EEPROM

上图是指南者EEPROM的原理图,图在A盘的原理图里,关于芯片的描述在AT24C02.pdf里

先来看芯片的整体描述

01A/02A/04A/08A/16A对应存储大小,对应128/256/512/1024/2048个字节,指南者用的是C02,那么容量就是256字节,可以使用这么大容量的EEPROM保存数据,并且这些数据掉电不会丢失。

下面说一下芯片的具体引脚

表里写的很清楚,每个引脚什么功能,这里说几个之前不知道的,

A0-A2:是地址,设备地址一共有 7 位,其中高 4 位固定为: 1010 b,低 3 位则由 A0/A1/A2信号线的电平决定,见图 23-13,图中的 R/W 是读写方向位,与地址无关。根据原理图可以看见我们这里把A0A1A2全部接地了,所以七位地址就是1010000b,即0x50(b代表二进制,这个二进制数实际上是01010000)

WP:是写保护,此引脚为高电平的时候不能写入数据,低电平的时候可以写入数据,指南者这个芯片用不到,需要的话可以接到GPIO引脚(我估摸着应该用推挽输出,有高电平有低电平嘛)

NC:这个芯片没有,也没有多余的解释,应该就是不连接这个芯片吧

简单说一下EEPROM的架构,就像前面stm32的架构一样

第一部分是地址比较器,用来和主机发出的设备地址作比较,如果是自己,则进行后续操作

第二部分书计数器,每传输一个数据计数一次,下面会说,顺序写入一次最多可以写八个

第三部分就是EEPROM的地址,可以看出是有x坐标和y坐标的,下面以excel表为例就是因为这个

4.1写数据

其实写入数据这部分,重点在于搞懂这个device address和word address的区别,搞懂了这里,其余的就简单了

4.1.1单字节写入

首先主机(MCU)发出的起始位,然后是设备地址(也就是EEPROM的地址),选择写方向(主机向EEPROM里写入数据),主机在接收到从机给的应答以后,在选定具体写入EEPROM的地址(EEPROM也是有存储空间的,那么具体写入存储空间的哪一部分,就由word address指定),主机接收到响应以后就可以开始写入输数据了。

EEPROM内部就像这个excel表格一样,每个位置是有编号的,word address就是指定写入的具体地址

4.1.2顺序写入

与之前唯一的不同是,可以连续写入多个数据。

前面说了EEPROM的内部结构,当想在第五行第二列连续写入多个数据,就可以采用page write的方式

主机(MCU)发出的起始位,然后是设备地址(也就是EEPROM的地址),选择写方向(主机向EEPROM里写入数据),主机在接收到从机给的应答以后,在选定写入数据的起始地址EEPROM的地址(EEPROM也是有存储空间的,那么具体写入存储空间的哪一部分,就由word address指定),主机接收到响应以后就可以顺序写入数据了(最多可以写入八个字节)。但有个问题是此方法必须连续写入,不可以跳着写。

4.2读数据

4.2.1当前地址读取

一般很少用,就是读取当前刚操作完的地址,很难确定当前地址是哪里,所以很少用

4.2.2随即地址读取(单个字节)

主机发送起始信号,发送从机设备地址,这里是需要把要读的位置告诉EEPROM所以方向要选择写方向,然后写入要读的具体位置,同时为了区分不是像EEPROM写入数据而是读取数据,所以要有主机再次产生一个起始信号,这次设备地址就选择读方向了。

4.2.3顺序读取(多个字节)

前面和随即地址读取一样,后面就是读取的多个数据,读取的数据没有范围,可以读到EEPROM结束的256,需要注意的是,当地址超过256以后,可能会出现"roll over"的现象,有可能又从0位置开始读取。

5、代码

5.1思路

1.初始化IIC:仿照串口的写,串口不要中断,用写好的收发的那个GPIO,SCL,SDA

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值