11567|15

57

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

凔海笔记之FPGA(九):Verilog描述IIC单字节读写协议 [复制链接]

 
本帖最后由 凔海 于 2016-5-21 08:35 编辑

一、简介AT24C04
      AT24C04是小容量(4KB)IIC总线EPROM存储元件。这句话说得很有内容呀。首先,AT24c04是存储元件,还是EPROM即可擦写可编程只读存储器,而且断电可保存。其次,对AT24c04的控制是采用IIC协议的,也就是说,IIC≠AT24C04,曾几何时,傻傻的以为IIC=AT24CXX。

那接下来,就先说一下AT24C04吧。

A0空引脚,不是地址设置引脚,A1/A2器件地址设置引脚,是用来设置器件地址的,可以挂4个AT24c04。WP写保护,低电平可对整个AT24c04的512字节进行读写操作,高电平则会使前256个地址受保护,只读不能写,后面的则爱咋地咋地了。SDA数据总线,是一个双向口,SCL则是时钟线。
IIC总线采用两线制,由数据线SDA和时钟线SCL构成。IIC总线对数据通信时序进行了严格的定义,主要包括起始、应答、结束还有数据读写的时序。
下面,就看看IIC单字节读写操作吧。n(*≧▽≦*)n

可见,写IIC协议就是玩拼图,拼的好与坏,就看咱对时序的分析了。
但在玩拼图之前咱还是先了解一下IIC协议的一些基本知识。
1、起始信号
    SCL保持高电平的状态下,SDA出现下降沿定义为I2C总线的起始信号,它是由主控器主动建立的一种电平跳变时序信号,标志着一次数据传输的开始,而在建立该信号之前IIC总线必须处于空闲状态。瞧下图


2、写地址
    写地址包括写设备地址和写数据地址。就如同笔者兼职家教,得先找到人家在哪个小区哪个楼,再找到人家在哪个单元等。然后才能去输出自己的知识(数据)。
写地址有固定的格式:

硬件ID:就是知道是哪个小区,它会随着厂商设备的种类不同而改变,例如:AT24C04是4’b1010。
硬件地址:就是芯片上的A0\A1\A2,A0空引脚(why?),A1/A2器件地址设置引脚,是用来设置器件地址的,可以挂4个AT24c04。
访问方向:写为1读是0。
写数据地址:AT24C04可以对512字节进行读写操作,而数据地址只有8位!也就是说,只能读写256字节,肿么破??????????????这时候会不会想到A0为什么说是空引脚呢?没错,它就是来凑数的,实现对512字节的读写。对此,我不得不说

还得补充一句,写数据是新的下降沿跟新数据,上升沿锁存/读取数据。
3、应答信号
 IIC总线上的所有数据都是以8位字节传送的,发送器每发送一个字节,就在下一个时钟脉冲释放数据线,由主机反馈一个应答信号。读数据就无视应答位。
  应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示主机已经成功地接收了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示主机接收该字节没有成功。

4、读写数据:
写数据就是写数据是新的下降沿跟新数据,上升沿锁存/读取数据,并且高位在前
读数据可以看做重复读取8次应答位,SCL的下降沿使从机跟新数据,然后主机在SCL的上升沿读取数据,此外,从机也会由高到低更新数据位。
结束位:
    在时钟线SCL保持高电平期间,数据线SDA被释放,使得SDA返回高电平(即正跳变),称为I2C总线的停止信号,它标志着一次数据传输的终止。
    停止信号也是一种电平跳变时序信号,而不是一个电平信号,停止信号也是由主控器主动建立的,建立该信号之后,I2C总线将返回空闲状态。

所谓的空闲状态就是I2C总线总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。


此帖出自FPGA/CPLD论坛

最新回复

一下是写函数的错误时序,很奇怪,明明是同一段代码,第二位却丢失了下降沿  详情 回复 发表于 2017-10-5 14:47

赞赏

1

查看全部赞赏

点赞 关注(1)
 

回复
举报

458

帖子

1

TA的资源

一粒金砂(高级)

沙发
 
非常不错的讲解,谢谢版主分享,请问凔海笔记之FPGA(九)怎么没看到啊?
此帖出自FPGA/CPLD论坛

点评

有的哦。。在这里 让知识变得有趣!!看凔海笔记之FPGA https://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=485361&fromuid=536508 一般我会每周抽出时间来给论坛里连载的帖子更新下汇总哈。。时间有限有时  详情 回复 发表于 2016-5-23 10:06
被我吃了,现在有了  详情 回复 发表于 2016-5-21 08:37
 
 

回复

57

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
lclhitwh 发表于 2016-5-21 08:27
非常不错的讲解,谢谢版主分享,请问凔海笔记之FPGA(九)怎么没看到啊?

被我吃了,现在有了
此帖出自FPGA/CPLD论坛

点评

希望能加你为论坛好友  详情 回复 发表于 2016-5-21 08:43
 
 
 

回复

458

帖子

1

TA的资源

一粒金砂(高级)

4
 
凔海 发表于 2016-5-21 08:37
被我吃了,现在有了

希望能加你为论坛好友
此帖出自FPGA/CPLD论坛
 
 
 

回复

3238

帖子

5

TA的资源

五彩晶圆(中级)

5
 
不错,写贴贵在坚持,与君共勉
此帖出自FPGA/CPLD论坛

点评

嗯 ,谢谢  详情 回复 发表于 2016-5-21 12:27
个人签名淘宝:https://viiot.taobao.com/Q群243090717
多年专业物联网行业经验,个人承接各类物联网外包项目
 
 
 

回复

111

帖子

0

TA的资源

一粒金砂(中级)

6
 
您好,看您发了好多关于FPGA的了,您那有没有汇总的
此帖出自FPGA/CPLD论坛

点评

咱论坛帖子过几天就不能编辑了,所以不知道怎么汇总,不过在这,有管理员汇总的 [attachimg]240661[/attachimg]  详情 回复 发表于 2016-5-21 12:29
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(中级)

7
 
wateras1 发表于 2016-5-21 09:21
不错,写贴贵在坚持,与君共勉

嗯 ,谢谢
此帖出自FPGA/CPLD论坛
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(中级)

8
 
cclccl941123 发表于 2016-5-21 09:59
您好,看您发了好多关于FPGA的了,您那有没有汇总的

咱论坛帖子过几天就不能编辑了,所以不知道怎么汇总,不过在这,有管理员汇总的


此帖出自FPGA/CPLD论坛

点评

好的,我找时间好好看看  详情 回复 发表于 2016-5-22 11:59
 
 
 

回复

57

帖子

0

TA的资源

一粒金砂(中级)

9
 
本帖最后由 凔海 于 2016-5-22 10:32 编辑

    (二)bala一下Verilog综合的AT24c04
       上面介绍了IIC协议的一些概念,下面,就开始真二八经的用Verilog综合出来吧。首先来确定要实现的功能:向AT24C04写入123456,然后读出来送给6位数码管依次显示。
       接下来,先来说说大体的框架。
smg_display_module.v数码管显示模块,这块就不多说了吧,留着以后再bala吧。
IIC_function_module.v实现对AT24c04的读写时序的综合
IIC_ctrl.v实现对写、读AT24C04的控制和对数码管显示的控制。
这三个模块也就干这点活了


      iAddr、iData分别是由IIC_ctrl模块发送给IIC_function_module地址地址和数据,oData是读出来的数据,共24位,一并发给数码管显示给我们看。iCall实现读写控制,oDone是完成信号,控制IIC_ctrl的工作启停。
      在这还是插句话吧,咱知道AT24c04的数据线是双向口,所以要用isQ来对数据线的输入输出状态进行选择。所以用实现,inout  SDA;assign SDA    =  isQ ? rSDA : 1'bz;isQ=1时为输出,即将数据写入AT24C04,isQ=0时为输入,即读出AT24C04数据。那为什么在输入时要设为高阻态呢?
      答:处于高阻抗状态时,输出电阻很大,相当于开路,没有任何逻辑控制功能。即可以认为是没有输出,对下级电路没有任何影响。而一个输出端口在高阻态的时候,其状态是由于其相连的其他电路决定的,可以将其看作是输入。当三态门的输出处于高阻状态的时候,取值由外部电路决定,也就是说,这一时刻是可以作为输入。

是否还记得,我们上节说了读写流程,就是下面这幅图,

    仔细端详这幅图我们不难发现,我们要写的就是起始位,写数据,读数据,应答位,结束位,其他的

接下来开始苦干人生了
       IIC_function_module.v该模块要完成与AT 24C04的读写通讯,也就是IIC协议。说白了就是完成写字节和读字节,所以要直勾勾的盯着下面这张图来写一写

       该图给出了AT24C04对时序的要求,高电平多少,低电平多少都有规范。可见,想实现度AT24C04的控制,要求的还是蛮多的。下面我们采用400KHz的时钟周期进行读写操作。


1、起始信号,也就是通知AT24c04要干活的指令是要求在时钟线拉高的情况下数据线产生一个负跳变(高电平变为低电平)。而且要求起始信号的保持直接不少于600ns.所以我们可以这样描述
            begin
            isQ <= 1'b1;
            rSCL <= 1'b1;
            
            if(C1 == 8'd0)
                rSDA <= 1'b1;
            else if(C1 == (TR+20))   //上升沿再保持400ns
                rSDA <= 1'b0;
               
            if(C1 == TCLK-1)     //一个时钟周期后进入下一步骤
                begin C1 <= 8'd0; i <= i + 1'b1; end
            else
                C1 <= C1 + 1'b1;
            end
    说一下哈,else if(C1 == (TR+20))那个20不是规定,使我想让它保持20的,其实也不需要一个时钟周期,只怪我愿意

2、应答位
可以看做是读取一位数据,主机写完成或读取一字节时,从机都会产生应答位,在主机拉低SCL那一刻,从机便会发送应答位,主机借上升沿读取应答,应答信号低电平有效。
    5'd15:
            begin
            isQ <= 1'b0;
            if(C1 ==TF+8'd20)    isAck <= SDA;
            
            if(C1 == 8'd0)        rSCL <= 1'b0;
            else if(C1 == TF+8'd20)        rSCL <= 1'b1;
        
            if(C1 == TCLK -1'b1)
                begin C1 <= 8'd0; i <= i + 1'b1;    end
            else    C1 <= C1 + 1'b1;
            end
    5'd16:
        if(isAck != 1'b0)
                i <= 5'd0;
            else
                i <= jump;
3、结束位
    在SCL保持高电平时,SDA被释放,使得SDA返回高电平,即为停止信号,这也是一种电平跳变时序信号,而不是一个电平信号,停止信号也是由主控器主动建立的,该信号建立后,IIC返回空闲状态。
            begin
            isQ <= 1'b1;
            if(C1 == 0)    rSCL <= 1'b0;
            else if(C1 == 8'd31)     rSCL <= 1'b1;
            
            if(C1==0)    rSDA <= 1'b0;
            else if(C1 == 8'd76)    rSDA <= 1'b1;
            
            if(C1 == 8'd155)   
                begin C1 <= 8'd0; i <= i + 1'b1; end
            else C1 <= C1 + 1'b1;
            end
4、写数据SCL下降沿更新数据,上升沿锁存数据

        5'd7,5'd8,5'd9,5'd10,5'd11,5'd12,5'd13,5'd14:
            begin
            isQ <= 1'b1;    //写入AT24c04
            rSDA <= oData[5'd14 - i];
            
            if(C1 == 0)        rSCL <= 1'b0;
            else if(C1 == (TF+TLOW))        rSCL <= 1'b1;
            
            if(C1 == TCLK -1'b1)
                begin C1 <= 8'b0; i <= i + 1'b1;    end
            else    C1 <= C1 + 1'b1;
            end
5、读数据,权当读取八个应答信号吧
        5'd19,5'd20,5'd21,5'd22,5'd23,5'd24,5'd25,5'd26:
            begin
            isQ <= 1'b0;
            if(C1 == 8'd62)    rData[26-i] <=SDA;
            if(C1 == 0)    rSCL <= 1'b0;
            else    if(C1 == 8'd62) rSCL <= 1'b1;
            if(C1 == TCLK-1’b1)   
                begin    C1 <= 8'd0; i <= i + 1'b1;end
            else    C1 <= C1 + 1'b1;
            end

最后呢?就是IIC_ctrl中的内容了
case(i)
    3'd0:
        if(DoneU1)
                begin isCall <= 2'b00;i <= i + 1'b1;end
        else
                begin isCall <= 2'b10;rAd <= 8'd6;rDa <= 8'h21;end
               
    3'd1:
        if(DoneU1)
                begin    isCall<= 2'b00;i<= i + 1'b1;end
        else
                begin isCall <= 2'b10;rAd <= 8'd16;rDa <= 8'h43;end
               
    3'd2:
        if(DoneU1)
                begin isCall <= 2'b00;i <= i + 1'b1;end
        else
                begin isCall <= 2'b10;rAd <= 8'd66;rDa <= 8'h65;end
    3'd3:
        if(DoneU1)
            begin rNum[7:0] <= oData;isCall <= 2'b00;i <=i+1'b1; end
        else
                begin isCall <= 2'b01;rAd <= 8'd6;end
    3'd4:
        if(DoneU1)
            begin    rNum[15:8] <= oData;isCall <= 2'b00;i<=i + 1'b1;end
        else
                begin isCall <= 2'b01;rAd <= 8'd16;end
    3'd5:
        if(DoneU1)
               begin rNum[23:16] <= oData;isCall <= 2'b00;i<= i + 1'b1;end
        else
            begin isCall <= 2'b01;rAd <= 8'd66;end
    3'd6:
            i <= i;
            
        endcase


    在地址6、16、66分别写入12、34、56。说实话我挺喜欢黑金这样的写法的,虽然不知道这样写算不算好的代码风格,但挺容易懂的。在完成信号来之前,重复进行一个动作,例如begin isCall <= 2'b10;rAd <= 8'd6;rDa <= 8'h21;end写操作,在地址6写入数据12,等完成信号来了,就进入下一个操作。挺好,黑金给你32个赞

山寨源:黑金动力社区
学识浅薄出拙文,如察错误望赐教,小弟在此感涕零。

IIC.rar

4.38 MB, 下载次数: 226

此帖出自FPGA/CPLD论坛
 
 
 

回复

111

帖子

0

TA的资源

一粒金砂(中级)

10
 
凔海 发表于 2016-5-21 12:29
咱论坛帖子过几天就不能编辑了,所以不知道怎么汇总,不过在这,有管理员汇总的

好的,我找时间好好看看
此帖出自FPGA/CPLD论坛
 
 
 

回复

6423

帖子

16

TA的资源

版主

11
 
谢谢沧海给大家分享
此帖出自FPGA/CPLD论坛
个人签名training
 
 
 

回复

1万

帖子

2853

TA的资源

管理员

12
 
lclhitwh 发表于 2016-5-21 08:27
非常不错的讲解,谢谢版主分享,请问凔海笔记之FPGA(九)怎么没看到啊?

有的哦。。在这里
让知识变得有趣!!看凔海笔记之FPGA
https://bbs.eeworld.com.cn/forum ... 5361&fromuid=536508
一般我会每周抽出时间来给论坛里连载的帖子更新下汇总哈。。时间有限有时候可能没立刻注意到更新了之类的。大家要是发现哪个系列更新了都可以@我一下让我及时更新汇总帖哈。
此帖出自FPGA/CPLD论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
个人签名玩板看这里:
https://bbs.eeworld.com.cn/elecplay.html
EEWorld测评频道众多好板等你来玩,还可以来频道许愿树许愿说说你想要玩的板子,我们都在努力为大家实现!
 
 
 

回复

111

帖子

0

TA的资源

一粒金砂(中级)

13
 
原谅在下挖坟,在下不是很看得懂楼主的程序……C1是什么啊?还有为什么要二次起始位?
此帖出自FPGA/CPLD论坛
 
 
 

回复

111

帖子

0

TA的资源

一粒金砂(中级)

14
 
楼主,你写数据伪函数那里有个错误:
rSDA <= oData[5'd14 - i];
是rData,不是oData
此帖出自FPGA/CPLD论坛
 
 
 

回复

111

帖子

0

TA的资源

一粒金砂(中级)

15
 
我用楼主的函数,发现读是正常的,但写部分时序不知道为什么,明明是同一段代码,第一位、第三位以后的都是正常的,第二位的scl下降沿却丢失了,无论如何都调不出来。最后是把写函数的case条件全部移后以为才成功。
我的写函数:
5'd9,5'd10,5'd11,5'd12,5'd13,5'd14,5'd15,5'd16:
                        begin
                        isQ <= 1'b1;
                        if(C1 == 3'd5)
                                rSDA <= rData[5'd16 - i];
                       
                        if(C1 <= 3'd4)                rSCL <= 1'b0;
                        else if(C1 == (TF+TLOW))                rSCL <= 1'b1;
                       
                        if(C1 == TCLK -1'b1)
                                begin C1 <= 8'b0; i <= i + 1'b1;        end
                        else        C1 <= C1 + 1'b1;
                        end
此帖出自FPGA/CPLD论坛
 
 
 

回复

111

帖子

0

TA的资源

一粒金砂(中级)

16
 
一下是写函数的错误时序,很奇怪,明明是同一段代码,第二位却丢失了下降沿

XPR9EHC27{5IYXG8EGCNA)D.png (6.05 KB, 下载次数: 0)

XPR9EHC27{5IYXG8EGCNA)D.png
此帖出自FPGA/CPLD论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表