2019-03-25 10:40发布
原帖由 shinexqq 于 2010-10-12 21:48 发表 不知道有没有人研究过altrea开发板DE1上的I2C程序,有几个问题我还没吃透,不知我直接发程序上来大家介不介意.....一起学习! http://www.myfpga.org/discuz/viewthread.php?tid=133&rpid=70321&ordertype=0&page=1 ...
对于你的第一个问题,我也还没看明白,先回答第二个问题吧。
首先,从代码上看这个代码应该是i2c主机模式的代码。你再认真看一下datasheet,i2c中,主机向从机发送任何数据(包括地址),从机在接受到之后都要有响应,而这个响应就是在数据最后一位结束后产生的。
现在解释一下响应的作用,主机在向从机发送数据后,如果从机没有返回任何信息的话,主机是不知道从机有没有接受到刚才发送的这个数据,因此为了让主机知道从机到底有没有接收到,就用这个响应信号来通知主机。即当主机发送完地址,从机在接收到这个地址(并且确认是自己的从机地址之后),从机就要发送一个响应信号来通知主机让主机知道从机已经接收到了(如果没有接收到,从机就不会发送这个响应信号)。同样的,主机发送完一个8位数据,从机在接收到之后也会有响应信号。
接下来再看这段代码,wire I2C_SDAT=SDO?1'bz:0 ;在结合源程序中,每次传输8位数据后有一个SDO=1'b1;可以知道当sdo等于一时,i2c_sdat为高阻态,这个时候i2c_sdat的值就等于输入值(因为i2c-sdat是I/O口,当i2c-sdat为高阻态时,它就是一个输入口),也就是从机发送过来的数值。然后再结合这句 6'd12 : begin SDO=SD[15]; ACK1=I2C_SDAT; end ,于是ack1就等于之前一个周期的i2c_sdat的输入值,也就是状态‘ 11’6'd11 : SDO=1'b1;时从机发送过来的值,而这个从机发送过来的值是在主机发送完地址后发送的,也就是从机对地址的一个响应信号。于是ack2,ack3可以以此类推。
感谢你在两边都作了详细的回答,既然是这边的网友,咱就在这讨论好了。 我的第一个问题的意思是,程序发数据用的是case (SD_COUNTER)这个语句来执行发数的,下面的case只有0-32,而SD_COUNTER的计数是到6'b111111(即63)了才重新从0开始计的。这样应该在33-63计数器在空跑的,不知道是什么意思
二、对于从机应答我看懂了。还有点不明白的是:结合这句 6'd12 : begin SDO=SD[15]; ACK1=I2C_SDAT; end ,于是ack1就等于之前一个周期的i2c_sdat的输入值,也就是状态‘ 11’6'd11 : SDO=1'b1。。。。。
我原来理解是:在这里他用的是“=”号,ACK1读到的是SD[15]的值,如果这样写6'd12 : begin ACK1=I2C_SDAT; SDO=SD[15];end 我能理解。。。为什么说“ack1就等于之前一个周期的i2c_sdat的输入值”呢?
原帖由 shinexqq 于 2010-10-13 11:00 发表 感谢你在两边都作了详细的回答,既然是这边的网友,咱就在这讨论好了。 我的第一个问题的意思是,程序发数据用的是case (SD_COUNTER)这个语句来执行发数的,下面的case只有0-32,而SD_COUNTER的计数是到6'b111111(即 ...
我的意思是说,我也不知道32-63之间状态机在做什么,没看懂它的作用。
对于你的第二个问题,好吧,我刚才也没认真看,没有注意到它的赋值使用“=”。那对于这个阻塞跟非阻塞赋值上我们就不过多讨论了,上面说那么多我的意思主要是想表达说,ack1就是从机对于地址的响应,它的值就是从机发过来的响应的值。同理ack2,就是从机对于上一个数据(也就是从机对sub_addr的响应)的响应值,ack3同理。。。
最多设置5个标签!
http://www.myfpga.org/discuz/vie ... amp;page=1#pid70321
我把问题发到那边的一个帖子上了,但没人回复。。。如果想自己先编下程序的呢,就先不要看这个帖子了
对于你的第一个问题,我也还没看明白,先回答第二个问题吧。
首先,从代码上看这个代码应该是i2c主机模式的代码。你再认真看一下datasheet,i2c中,主机向从机发送任何数据(包括地址),从机在接受到之后都要有响应,而这个响应就是在数据最后一位结束后产生的。
现在解释一下响应的作用,主机在向从机发送数据后,如果从机没有返回任何信息的话,主机是不知道从机有没有接受到刚才发送的这个数据,因此为了让主机知道从机到底有没有接收到,就用这个响应信号来通知主机。即当主机发送完地址,从机在接收到这个地址(并且确认是自己的从机地址之后),从机就要发送一个响应信号来通知主机让主机知道从机已经接收到了(如果没有接收到,从机就不会发送这个响应信号)。同样的,主机发送完一个8位数据,从机在接收到之后也会有响应信号。
接下来再看这段代码,wire I2C_SDAT=SDO?1'bz:0 ;在结合源程序中,每次传输8位数据后有一个SDO=1'b1;可以知道当sdo等于一时,i2c_sdat为高阻态,这个时候i2c_sdat的值就等于输入值(因为i2c-sdat是I/O口,当i2c-sdat为高阻态时,它就是一个输入口),也就是从机发送过来的数值。然后再结合这句 6'd12 : begin SDO=SD[15]; ACK1=I2C_SDAT; end ,于是ack1就等于之前一个周期的i2c_sdat的输入值,也就是状态‘ 11’6'd11 : SDO=1'b1;时从机发送过来的值,而这个从机发送过来的值是在主机发送完地址后发送的,也就是从机对地址的一个响应信号。于是ack2,ack3可以以此类推。
感谢你在两边都作了详细的回答,既然是这边的网友,咱就在这讨论好了。 我的第一个问题的意思是,程序发数据用的是case (SD_COUNTER)这个语句来执行发数的,下面的case只有0-32,而SD_COUNTER的计数是到6'b111111(即63)了才重新从0开始计的。这样应该在33-63计数器在空跑的,不知道是什么意思
二、对于从机应答我看懂了。还有点不明白的是:结合这句 6'd12 : begin SDO=SD[15]; ACK1=I2C_SDAT; end ,于是ack1就等于之前一个周期的i2c_sdat的输入值,也就是状态‘ 11’6'd11 : SDO=1'b1。。。。。
我原来理解是:在这里他用的是“=”号,ACK1读到的是SD[15]的值,如果这样写6'd12 : begin ACK1=I2C_SDAT; SDO=SD[15];end 我能理解。。。为什么说“ack1就等于之前一个周期的i2c_sdat的输入值”呢?
[ 本帖最后由 shinexqq 于 2010-10-13 11:04 编辑 ]我的意思是说,我也不知道32-63之间状态机在做什么,没看懂它的作用。
对于你的第二个问题,好吧,我刚才也没认真看,没有注意到它的赋值使用“=”。那对于这个阻塞跟非阻塞赋值上我们就不过多讨论了,上面说那么多我的意思主要是想表达说,ack1就是从机对于地址的响应,它的值就是从机发过来的响应的值。同理ack2,就是从机对于上一个数据(也就是从机对sub_addr的响应)的响应值,ack3同理。。。
[ 本帖最后由 linhaiqing60 于 2010-10-13 11:47 编辑 ]一周热门 更多>