怎样用STM32 中的 I2C读写EEPROM(一)

I2C协议简介

I2C是一种串行同步通信方式,由一根时钟线和一根数据线组成.由Philips公司发明.由于它引脚少,硬件实现简单,可扩展性强,不需要USART、CAN等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC)间的通讯。

它是一个支持多设备的总线。“总线”指多个设备共用的信号线。在一个I2C通讯总线中,可连接多个I2C通讯设备,支持多个通讯
主机及多个通讯从机。每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备之间的访问。总线通过上拉电阻接到电源。当I2C设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。具有三种传输模式:标准模式传输速率为100kbit/s ,快速模式为400kbit/s ,高速模式下可达 3.4Mbit/s,但目前大多I 2 C设备尚不支持高速模式。连接到相同总线的 IC 数量受到总线的最大电容 400pF 限制.

I2C读写过程

1.主机写数据到从机:

 数据由主机传输至从机

数据由从机传输至主机

S :    传输开始信号
SLAVE_ADDRESS: 从机地址
A/A:应答(ACK)或非应答(NACK)信号

2.主机读取丛机的数据

数据由主机传输至从机

数据由从机传输至主机

S : 传输开始信号
SLAVE_ADDRESS: 从机地址
A/A:应答(ACK)或非应答(NACK)信号

3.读写复合格式

数据由主机传输至从机

数据由从机传输至主机

S : 传输开始信号
SLAVE_ADDRESS: 从机地址
R/W:传输方向选择位,1为读,0为写
A/A:应答(ACK)或非应答(NACK)信号

I2C通讯的起始和停止信号

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

I2C数据的有效性

I2C使用SDA信号线来传输数据,使用SCL信号线进行数据同步。
SDA数据线在SCL的每个时钟周期传输一位数据。

SCL为高电平的时候SDA表示的数据有效,即此时的SDA为高电平时
表示数据“1”,为低电平时表示数据“0”。
当SCL为低电平时,SDA的数据无效,一般在这个时候SDA进行电平
切换,为下一次表示数据做好准备。

I2C地址和数据方向

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

I2C响应

I2C的数据和地址传输都带响应。响应包括“应答(ACK)”和“非应答(NACK)”两种信号。传输时主机产生时钟,在第9个时钟时,数据发送端会释放SDA的控制权,由数据接收端控制SDA,若SDA为高电平,表示非应答信号(NACK),低电平表示应答信号(ACK)。

需要注意的是:
1,SCL一直由Master控制,SDA依照数据传送的方向,读数据时由Slave控制SDA,写数据时由Master控制SDA。当8位数据传送完毕之后,应答位或者否应答位的SDA控制权与数据位传送时相反。
2,开始位“Start”和停止位“Stop”,只能由Master来发出。
3,地址的8位传送完毕后,成功配置地址的Slave设备必须发送“ACK”。否则否则一定时间之后Master视为超时,将放弃数据传送,发送“Stop”。
4,当写数据的时候,Master每发送完8个数据位,Slave设备如果还有空间接受下一个字节应该回答“ACK”,Slave设备如果没有空间接受更多的字节应该回答“NACK”,Master当收到“NACK”或者一定时间之后没收到任何数据将视为超时,此时Master放弃数据传送,发送“Stop”。
5,当读数据的时候,Slave设备每发送完8个数据位,如果Master希望继续读下一个字节,Master应该回答“ACK”以提示Slave准备下一个数据,如果Master不希望读取更多字节,Master应该回答“NACK”以提示Slave设备准备接收Stop信号。
6,当Master速度过快Slave端来不及处理时,Slave设备可以拉低SCL不放(SCL=0将发生“线与”)以阻止Master发送更多的数据。此时Master将视情况减慢或结束数据传送。

在实际应用中,并没有强制规定数据接收方必须对于发送的8位数据做出回应,尤其是在Master和Slave端都是用GPIO软件模拟的方法来实现的情况下,编程者可以事先约定数据传送的长度,slave不检查NACK,有时可以起到减少系统开销的效果。但是如果slave方是硬件i2c要求一定要标准的NACK,master方是GPIO软件模拟i2c并没有正确的发送NACK,就会出现“slave收不到stop”导致i2c挂死。

 在正常情况下,I2C总线协议能够保证总线正常的读写操作。但是,当I2C主设备异常复位时(看门狗动作,板上电源异常导致复位芯片动作,手动按钮复位等等)有可能导致I2C总线死锁产生。下面详细说明一下总线死锁产生的原因。

    在I2C主设备进行读写操作的过程中.主设备在开始信号后控制SCL产生8个时钟脉冲,然后拉低SCL信号为低电平,在这个时候,从设备输出应答信号,将SDA信号拉为低电平。如果这个时候主设备异常复位,SCL就会被释放为高电平。此时,如果从设备没有复位,就会继续I2C的应答,将SDA一直拉为低电平,直到SCL变为低电平,才会结束应答信号。而对于I2C主设备来说.复位后检测SCL和SDA信号,如果发现SDA信号为低电平,则会认为I2C总线被占用,会一直等待SCL和SDA信号变为高电平。这样,I2C主设备等待从设备释放SDA信号,而同时I2C从设备又在等待主设备将SCL信号拉低以释放应答信号,两者相互等待,I2C总线进人一种死锁状态。同样,当I2C进行读操作,I2C从设备应答后输出数据,如果在这个时刻I2C主设备异常复位而此时I2C从设备输出的数据位正好为0,也会导致I2C总线进入死锁状态。

 方法

    (1)尽量选用带复位输人的I2C从器件。

    (2)将所有的从I2C设备的电源连接在一起,通过MOS管连接到主电源,而MOS管的导通关断由I2C主设备来实现。
    (3)在I2C从设备设计看门狗的功能。

    (4)在I2C主设备中增加I2C总线恢复程序。

        每次I2C主设备复位后,如果检测到SDA数据线被拉低,则控制I2C中的SCL时钟线产生9个时钟脉冲(针对8位数据的情况,“9个clk可以激活”的方法来自NXP的文档,NXP(Philips)作为I2C总线的鼻祖,这样的说法是可信的),这样I2C从设备就可以完成被挂起的读操作,从死锁状态中恢复过来。

        这种方法有很大的局限性,因为大部分主设备的I2C模块由内置的硬件电路来实现,软件并不能够直接控制SCL信号模拟产生需要时钟脉冲。

        或者,发送I2C_Stop条件也能让从设备释放总线。

        如果是GPIO模拟I2C总线实现,那么在I2C操作之前,加入I2C总线状态检测I2C_Probe,如果总线被占用,则可尝试恢复总线,待总线释放后,再进行操作。要保证I2C操作最小单元的完整性,不被其他事件(中断、高优先级线程,等)打断。

  (5)在I2C总线上增加一个额外的总线恢复设备。这个设备监视I2C总线。当设备检测到SDA信号被拉低超过指定时间时,就在SCL总线上产生9个时钟脉冲,使I2C从设备完成读操作,从死锁状态上恢复出来。总线恢复设备需要有具有编程功能,一般可以用单片机或CPLD实现这一功能。

  (6)在I2C上串人一个具有死锁恢复的I2C缓冲器,如Linear公司的LTC4307是一个双向的I2C总线缓冲器,并且具有I2C总线死锁恢复的功能。LTC4307总线输入侧连接主设备,总线输出侧连接所有从设备。当LTC4307检测到输出侧SDA或SCL信号被拉低30ms时,就自动断开I2C总线输入侧与输出侧的连接.并且在输出侧SCL信号上产生16个时钟脉冲来释放总线。当总线成功恢复后,LTC4307会再次连接输入输出侧,使总线能够正常工作。

STM32中的I2C介绍

1.通讯引脚  2.时钟控制逻辑  3. 数据控制逻辑   4.整体控制逻辑

由STM32的I2C片上外设专门负责实现I2C通讯协议,只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来,CPU只要检测该外设的状态和访问数据寄存器,就能完成数据收发。这种由硬件外设处理I2C协议的方式减轻了CPU的工作,且使软件设计更加简单。STM32的I2C外设可用作通讯的主机及从机,支持100Kbit/s和400Kbit/s的速率,支持7位、10位设备地址,支持DMA数据传输,并具有数据校验功能。

1.通讯引脚

STM32芯片有多个I2C外设,它们的I2C通讯信号引出到不同的GPIO引脚上,使用时必须配置到这些指定的引脚,以《STM32F10x规格书》为准。

引脚 I2C1 I2C2
SCL PB5/PB8(重映射) PB10
SDA PB6/PB9(重映射) PB11

 2.时钟控制逻辑

SCL线的时钟信号,由I 2 C接口根据时钟控制寄存器(CCR)控制,控制的参数主要为时钟频率。• 可选择I2C通讯的“标准/快速”模式,这两个模式分别I2C对应100/400Kbit/s的通讯速率。

 在快速模式下可选择SCL时钟的占空比,可选T low /T high =2或T low /T high =16/9模式。
CCR寄存器中12位的配置因子CCR,它与I2C外设的输入时钟源共同作用,产生SCL时钟。STM32的I2C外设输入时钟源为PCLK1。

计算时钟频率:
标准模式:
T high =CCR*T PCKL1 T low = CCR*T PCLK1
快速模式中T low /T high =2时:
T high = CCR*T PCKL1 T low = 2*CCR*T PCKL1
快速模式中T low /T high =16/9时:
T high = 9*CCR*T PCKL1 T low = 16*CCR*T PCKL1
例如,我们的PCLK1=36MHz,想要配置400Kbit/s的速率,计算方式如下:
PCLK时钟周期: TPCLK1 = 1/36000000
目标SCL时钟周期: TSCL = 1/400000
SCL时钟周期内的高电平时间: THIGH = TSCL/3
SCL时钟周期内的低电平时间: TLOW = 2*TSCL/3
计算CCR的值: CCR = THIGH/TPCLK1 = 30

计算出来的CCR值写入到寄存器即可。

3. 数据控制逻辑

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

4.整体控制逻辑

整体控制逻辑负责协调整个I2C外设,控制逻辑的工作模式根据我们配
置的“控制寄存器(CR1/CR2)”的参数而改变。
在外设工作时,控制逻辑会根据外设的工作状态修改“状态寄存器(SR1
和SR2)”,只要读取这些寄存器相关的寄存器位,就可以了解I2C的工作状态。

I2C传输过程中产生的事件

SB---起始位(主模式) (Start bit (Master mode)) 

ADDR---:地址已被发送(主模式)/地址匹配(从模式) (Address sent (master mode)/matched(slave mode))

TxE---数据寄存器为空(发送时) (Data register empty (transmitters)) 

BTF---字节发送结束 (Byte transfer finished)

RxNE---数据寄存器非空(接收时) (Data register not empty (receivers))

AF--- 应答失败

猜你喜欢

转载自blog.csdn.net/rannar/article/details/81233875