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信号。

这部分的代码如下:

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秒读取一次。

[content_control]

i2c_r_pcf8591_quartus_pra006.zip

[/content_control]

运行效果:

 

 

Posted in FPGA 教材教案, FPGA习题库, Verilog, 教材与教案

发表回复

相关链接