Menu Close

FPGA I2C(IIC) Verilog 开发学习技巧(二)当前地址读

上一节里讲到了I2C的基础部分以及字节写操作,本节继续I2C操作,进行当前地址读操作。

I2C当前地址读,所谓当前地址,指从芯片有一个地址指针,当前所指向的地址。可以把I2C通讯地址看成一个一维数组,或者一个队列,地址编号从小到大依次排列,芯片内有个地址指针指向某个地址。指针可以滑动,滑动一次,地址加一。连续读/连续写就是利用指针不停向后滑动进行的。

那么当前地址是哪个地址呢?

如果上次是我们自己使用的话,在芯片不断电的情况下会保持上次的地址,如果芯片断电了,当前地址会回到0地址(大部分芯片会)。如果上次通讯不是我们自己使用的,那就不知道当前地址是什么了。那这样使用当前地址读还有什么用?它的好处是,在我们知道当前地址的情况下,可以多次读取而不需要重新定位地址。比随机地址读节省时间和资源。

当前地址读的操作步骤如下:

0、空闲状态 SCL SDA 都是高电平
1、主机发送开始信号
2、主机发送设备地址(从机地址),同时发送读命令(8bit长度  从机地址 7 bit位,读写命令1bit位,0-写命令,1-读命令)。
3、从机应答(ack)
4、从机发送寄存器的数据8bit
5、主机发送应答(非应答 NACK)
6、主机发送结束命令

步骤上并不复杂,具体操作和写操作一样,不同的是第五步和第六步。

第五步:主机发送“非”应答。“非”应答表示主机想要结束本次通讯,不再需要后续数据(发“是”应答,则从机会继续发送后续寄存器数据,也就是“连续读”)。“非”应答的具体操作是:主机在SCL 为低电平时,发送SDA高电平,并持续一个周期。

第六步:发送结束命令。一般发送结束命令只要“SCL为高时,让SDA从低到高跳变”即可。但是由于第5步,SDA已经是高电平了,所以需要在第5步之后的SCL低电平先拉低SDA,再在SCL高电平时拉高SDA信号。

这部分的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
      S_NACK        :       if(!scl)//主机发送,在scl为低时候,发送sda为1
                                    begin
                                        sda_sel <= 1;
                                        sda_buf <= 1;
                                        cstate <= S_STOP;
                                    end

      S_STOP        :       if(num==0)//SCL高电平时,SDA从低到高的跳变
                                    num <= 1;
                                else if( num ==1)
                                    begin
                                        sda_buf<= 0;
                                        num <=2;
                                    end
                                else if(num ==2)
                                    begin
                                        sda_buf <=1;
                                        cstate <= S_IDLE;
                                    end

代码文件:代码使用PRA006开发板。每0.5秒读取一次。

https://www.icfedu.cn/wp-content/uploads/2021/03/i2c_r_pcf8591_quartus_pra006.zip

 

运行效果:

%title插图%num

 

 

附件下载

Posted in FPGA, FPGA习题库, Verilog, 教材与教案
0 0 投票数
Article Rating
订阅评论
提醒
guest
0 评论
内联反馈
查看所有评论

相关链接