微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 第十六章 IIC协议详解+UART串口读写EEPROM

第十六章 IIC协议详解+UART串口读写EEPROM

时间:10-02 整理:3721RD 点击:

十六、IIC协议详解+Uart串口读写EEPROM


本文由杭电网友曾凯峰根据小梅哥FPGA IIC协议基本概念公开课内容整理并最终编写Verilog代码实现使用串口读写EEPROM的功能。

以下为原文内容:
在看完小梅哥讲解IIC总线基本概念后,就有种想跃跃欲试的想法,下面先复习下梅哥讲解的IIC总线若干基本概念。以下基本概念均为小梅哥总结,我就直接拿过来供大家参考学习。
IIC基本特性总线信号
SDA:串行数据线
SCL:串行数据时钟
总线空闲状态
SDA:高电平
SCL:高电平
IIC协议起始位
SCL为高电平时,SDA出现下降沿,产生一个起始位。


IIC协议结束位
SCL为高电平时,SDA出现上升沿,产生一个结束位。


IIC读写单字节时序
IIC主机对IIC从机写入数据时,SDA上的每一位数据在SCL的高电平期间被写入从机中。对于主机,在SCL的低电平期间改变要写入的数据。


IIC主机从IIC从机中读出数据时,从机在SCL的低电平期间将数据输出到SDA总线上,在SCL的高电平期间保持数据稳定。对于主机,在SCL的高电平期间将SDA线上的数据读取并存储。
数据接收方对数据发送方的响应
每当一个字节的数据或命令传输完成时,都会有一位的应答位。需要应答位时,数据发出方将SDA总线设置为3态输入,由于IIC总线上都有上拉电阻,因此此时总线默认为高电平,若数据接收方正确接收到数据,则数据接收方将SDA总线拉低,以示正确应答。
例如当IIC主机对IIC从机写入数据或命令时,每个字节都需要从机产生应答信号以告诉主机数据或命令成功被写入。所以,当IIC主机将8位的数据或命令传出后,会将SDA信号设置为输入,等待从机应答(等待SDA被从机拉低为低电平),若从机正确应答,表明当前数据或命令传输成功,可以结束或开始下一个命令/数据的传输,否则表明数据/命令写入失败,主机就可以决定是否放弃写入或者重新发起写入。
IIC器件地址
每个IIC器件都有一个器件地址,有的器件地址在出厂时地址就设置好了,用户不可以更改(ov7670:0x42),有的确定了几位,剩下几位由硬件确定(比如有三位由用户确定,就留有3个控制地址的引脚,最常见的为IIC接口的EEPROM存储器),此类较多;还有的有地址寄存器。
  严格讲,主机不是向从机发送地址,而是主机往总线上发送地址,所有的从机都能接收到主机发出的地址,然后每个从机都将主机发出的地址与自己的地址比较,如果匹配上了,这个从机就会向主机发出一个响应信号。主机收到响应信号后,开始向总线上发送数据,与这个从机的通讯就建立起来了。如果主机没有收到响应信号,则表示寻址失败。
  通常情况下,主从器件的角色是确定的,也就是说从机一直工作在从机模式。不同的器件定义地址的方式是不同的,有的是软件定义,有的是硬件定义。例如某些单片机的IIC接口作为从机时,其器件地址是可以通过软件修改从机地址寄存器确定的。而对于一些其他器件,如CMOS图像传感器、EEPROM存储器,其器件地址在出厂时就已经设定好了,具体值可以在对应的数据手册中查到。
对于AT24C64这样一颗EEPROM器件,其器件地址为1010加3位的片选信号。3位片选信号由硬件连接决定。例如SOIC封装的该芯片pin1、pin2、pin3为片选地址。当硬件电路上分别将这三个pin连接到GND或VCC时,就实现了设置不通的片选地址。
IIC协议在进行数据传输时,主机需要首先向总线上发出控制命令,其中,控制命令就包含了从机地址/片选信号+读写控制。然后等待从机响应。以下为IIC控制命令传输的数据格式。


IIC传输时,按照从高到低的位序进行传输。控制字节的最低位为读写控制位,当该位为0时表示主机对从机进行写操作,当该位为1时表示主机对从机进行读操作。例如,当需要对片选地址为100的AT24LC64发起写操作,则控制字节应该为CtrlCode = 1010_100_0。若要读,则控制字节应该为CtrlCode = 1010_100_1。
IIC存储器地址
每个支持IIC协议的器件,内部总会有一些可供读写的寄存器或存储器,例如,对于我们用到的EEPROM存储器,内部就是顺序编址的一系列存储单元。对于我们常接触的CMOS摄像头如OV7670(OV7670的该接口叫SCCB接口,其实质也是一种特殊的IIC协议,可以直接兼容IIC协议),其内部就是一系列编址的可供读写的寄存器。因此,我们要对一个器件中的存储单元(寄存器和存储器以下简称存储单元)进行读写,就必须要能够指定存储单元的地址。IIC协议设计了有从机存储单元寻址地址段,该地址段为一个字节或两个字节长度,在主机确认收到从机返回的控制字节响应后,由主机发出。地址段长度视不同的器件类型,长度不同,例如同是EEPROM存储器,AT24C04的址段长度为一个字节,而AT24C64的地址段长度为两个字节。具体是一个字节还是两个字节,与器件的存储单元数量有关。
AT24C01地址段:


AT24C64地址段:


IIC读写时序IIC单字节写时序1字节地址段器件单字节写时序


2字节地址段器件单字节写时序


从主机角度看一次写入过程
a. 主机设置SDA为输出
b. 主机发起起始信号
c. 主机传输器件地址字节,其中最低为0,表明为写操作。
d. 主机设置SDA为输入三态,读取从机应答信号。
e. 读取应答信号成功,传输1字节地址数据
f. 主机设置SDA为输入三态,读取从机应答信号。
g. 对于两字节地址段器件,传输地址数据低字节,对于1字节地址段器件,传输待写入的数据
h. 设置SDA为输入三态,读取从机应答信号。
i. 对于两字节地址段器件,传输待写入的数据(2字节地址段器件可选)
j. 设置SDA为输入三态,读取从机应答信号(2字节地址段器件可选)。
k. 主机产生STOP位,终止传输。
IIC连续写时序(页写时序)
注:IIC连续写时序仅部分器件支持。
1字节地址段器件多字节写时序


2字节地址段器件多字节写时序


从主机角度看一次写入过程
a. 主机设置SDA为输出
b. 主机发起起始信号
c. 主机传输器件地址字节,其中最低为0,表明为写操作。
d. 主机设置SDA为输入三态,读取从机应答信号。
e. 读取应答信号成功,传输1字节地址数据
f. 主机设置SDA为输入三态,读取从机应答信号。
g. 对于两字节地址段器件,传输低字节地址数据,对于1字节地址段器件,传输待写入的第一个数据
h. 设置SDA为输入三态,读取从机应答信号。
i. 写入待写入的第2至第n个数据并读取应答信号。对于AT24Cxx,一次可写入的最大长度为32字节。
j. 主机产生STOP位,终止传输。
IIC单字节读时序1字节地址段器件单节读时序


2字节地址段器件单节读时序


从主机角度看一次读取过程
a. 主机设置SDA为输出
b. 主机发起起始信号
c. 主机传输器件地址字节,其中最低为0,表明为写操作。
d. 主机设置SDA为输入三态,读取从机应答信号。
e. 读取应答信号成功,传输1字节地址数据
f. 主机设置SDA为输入三态,读取从机应答信号。
g. 对于两字节地址段器件,传输低字节地址数据,对于1字节地址段器件,无此段数据传输。
h. 主机发起起始信号
i. 主机传输器件地址字节,其中最低为1,表明为写操作。
j. 设置SDA为输入三态,读取从机应答信号。
k. 读取SDA总线上的一个字节的数据
l. 产生无应答信号(高电平)(无需设置为输出高点片,因为总线会被自动拉高)
m. 主机产生STOP位,终止传输。
IIC多字节连续读时序(页读取)1字节地址段器件多字节读时序


2字节地址段器件多字节读时序


从主机角度看一次读取过程
a. 主机设置SDA为输出
b. 主机发起起始信号
c. 主机传输器件地址字节,其中最低为0,表明为写操作。
d. 主机设置SDA为输入三态,读取从机应答信号。
e. 读取应答信号成功,传输1字节地址数据
f. 主机设置SDA为输入三态,读取从机应答信号。
g. 对于两字节地址段器件,传输低字节地址数据,对于1字节地址段器件,无此段数据传输。
h. 主机发起起始信号
i. 主机传输器件地址字节,其中最低为1,表明为写操作。
j. 设置SDA为输入三态,读取从机应答信号。
k. 读取SDA总线上的n个字节的数据(对于AT24Cxx,一次读取长度最大为32字节)
l. 产生无应答信号(高电平)(无需设置为输出高点片,因为总线会被自动拉高)
主机产生STOP位,终止传输。
EEPROM读写控制程序设计硬件平台分析
下面就小梅哥开发板上的EEPROM芯片编写IIC协议读写EEPROM里的数据,首先查看小梅哥开发板中EEPROM存储器芯片的型号为AT24C64,其存储器容量为64kbit,器件片选地址有3位,A2、A1、A0。数据存储地址是13位,属于2字节地址段器件。


这里EEPROM读写控制模块的设计主要是针对读写EEPROM单字节数据,总的来说就是2字节地址段器件单节读写控制模块的设计。有关多字节的数据的读写读者可以自己学习设计。
根据上面IIC的基本概念中有关读写时SDA与SCL时序,不管对于从机还是主机SDA上的每一位数据在SCL的高电平期间为有效数据,在SCL的低电平期间是要改变的数据。根据这个用2个标志位对时钟SCL的高电平和低电平进行标记,如下图所示:scl_high对SCL高电平中间进行标志,scl_low对SCL低电平中间进行标志。这个在具体的实现中也不难实现。


SCL时钟设计
首先考虑到SCL最大时钟周期为400kHz,这里SCL就实现周期为200kHz的时钟,这个具体读者可以做修改,系统时钟直接采用小梅哥开发板的50MHz外部时钟,采用计数器方法产生SCL,这样计数器最大计数值SCL_CNT_M = 500_000_000/200_000 - 1 =249。只需在计数到最大值一半值和最大值进行翻转SCL就可实现,具体实现代码如下:





上述代码中iic_en信号为IIC通信使能信号,done信号为一次IIC读/写数据完成标志位。在此基础上,对SCL高电平中间标志位scl_high和低电平标志位scl_low就很容易实现,只需在计数到四分之一和四分之三时分别置1就能得到。具体代码如下:


IIC读写状态机设计
SCL时钟总线以及其高低电平中间标志位产生完成后其后就是SDA数据线的产生,这个需要根据具体的读写操作完成。这里主要采用状态机实现,根据上面IIC基本概念中2字节地址段器件单字节读和写的过程设计大致的状态机如下,具体的有些条件和输出等没有写。这是按照小梅哥讲解IIC读写过程想到的,对于实现单字节的读写是没有问题,但对于读写多字节还需要做修改,这个后续再做优化。


整个模块的具体实现代码如下:























IIC读写状态机仿真
仿真验证需要编写一个模块模拟EEPROM的存储器,这里仿真片选地址就省掉不做考虑。模拟EEPROM的存储器的主要功能是接收存储器数据地址,根据开始信号的次数(主机写数据有一次开始信号,主机读数据有2次开始信号)判断是读还是写数据,进而做出数据的输出/接收。这个仿真模型我是借用夏宇闻Verilog数字系统设计教程一书中的代码稍作修改以满足AT24C64芯片2字节地址段的情况。










IIC读写状态机仿真测试顶层设计
仿真验证的框图如下,将EEPROM读写控制模块与EEPROM模型相连接就行了。


代码如下:






IIC读写逻辑仿真结果分析
仿真验证主要是对模拟的EEPROM存储器器写入200个数据,然后读出写入的200个数据,观察波形情况及读写是否和预期一样。
仿真波形如下:
写数据和读数据总体情况波形如下:


向EEPROM写数据波形图如下:


读取EEPROM数据波形如下:


由波形可以看出我们的设计是满足要求的。
串口读写EEPROM应用系统设计
接下来就是设计通过串口发送地址和写入数据,通过一定的数据处理后对EEPROM进行读写操作。设计的框图如下:


读写控制位是通过一个按键来切换的,EEPROM读写使能也是通过一个按键来使能的,前期为了方便测试就是按键按下一次进行一次读写,在调试完成后可以将这个按键去掉,通过发送的数据进行一定的判断后使能。按键和串口收发模块的代码都是学习小梅哥课程上的,在芯航线FPGA数字系统设计教程+实例解析教程上有详细的设计过程。
数据转发模块设计
下面主要是数据转换模块的设计。前面EEPROM设计的是2字节地址段单字节读写,串口发送一组数据包括2个字节地址和1字节写数据(如果是读操作该字节可以为任意数),就相当于串口每次读写EEPROM时发送3个字节,数据处理模块将接收的3个字节数赋值个读写地址和写数据(读数据时第个字节可以为任意数)。具体实现代码如下:







大致的思路是,,串口接收数据存入一个3字节缓存器中,,当接受到3个字节后就将缓存器中的数据赋值给EEPROM读写控制模块的地址address和写数据write_data。这样再通过外部的按键使能这次的读/写操作就可完成一次读/写操作。
数据转发模块仿真文件设计
下面对数据转换模块进行仿真验证,仿真利用上面已经编写和的EEPROM读写控制模块和EEPROM模块进行仿真,代码如下:









数据转发模块仿真结果分析
仿真波形如下:
写数据和读数据总的波形图如下:


写数据波形图如下:


读数据波形如下:


观察波形,与预期效果一致。
系统顶层文件设计
下面就是顶层文件的设计,根据上面的框图很容易写出顶层文件,代码如下:







在顶层文设计中增加了两个LED,LED0用指示当前的读/写操作状态,亮表示写EEPROM操作状态,灭表示读EEPROM数据操作状态;LED1表示EEPROM读/写使能按键按下指示,按键按下灯亮,按键松开灯灭。完成后进行引脚分配,编译,板级下载后测试。
系统测试
测试如下:
初始默认状态下是写EEPROM操作(通过LED0亮可以观察),此时,用串口工具发送十六进制数00 00 56 ,然后按下引脚key_icc_en对应的按键key0,使能EEPROM读写操作,完成了一次写操作。可以多次使用同样的方法写入不同地址中的数据。这里我再写入2组数据,分别为00 AB 39 、00 B1 AB 。写操作完成后按下引脚key_icc_wr对应的按键key1,此时LED0灭,表示可以进行读操作。这里我们依次对上面写入数据的地址进行读操作,同样在串口发送个字节,前两个字节中低13位表示的地址,第3个字节可以为任意数都行(这里具体可以看代码理解,读者也可以想其他方法实现),串口工具依次发送00 00 12 后按下按键key0;发送00 AB 23  后按下按键key0;发送00 B1 AB 后按下按键key0;每次按下按键会接收到读出的数据,如下图所示:


这里串口每次发送3个字节,然后按一下使能按键key0,完成一次读写操作,写操作中第3个字节为写入的数据,在读操作中,第3个字节是可以为任意值,但是不能省掉,要省掉可以更改设计进行优化,读者可以自己寻找优化方法。至于每次按键一次才进行一次读写操作有点麻烦,读者也可以进行修改优化。本次的是除了用modelsim仿真验证以外,还用到了SignalTap II Logic Analyzer工具对波形进行了抓取分析

如有更多问题,欢迎加入芯航线 FPGA 技术支持群交流学习:472607506

小梅哥

芯航线电子工作室

关于学习资料,小梅哥系列所有能够开放的资料和更新(包括视频教程,程序代码,教程文档,工具软件,开发板资料)都会发布在我的云分享。(记得订阅)链接:http://yun.baidu.com/share/home? ... are#category/type=0
赠送芯航线AC6102型开发板配套资料预览版下载链接:链接:http://pan.baidu.com/s/1slW2Ojj 密码:9fn3
赠送SOPC公开课链接和FPGA进阶视频教程。链接:http://pan.baidu.com/s/1bEzaFW 密码:rsyh

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top