[ZLG-ARM] 请教周工:I2C状态码*****!!!

[复制链接]
3591|16
 楼主| newman2008 发表于 2007-4-20 16:54 | 显示全部楼层 |阅读模式
周工的I2C程序里有这么一段:<br />case&nbsp;0x28:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//已发送I2C数据,并接收到应答<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(0==I2C_suba_en)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//无子地址直接发送数据<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{if(I2C_num&gt0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2DAT&nbsp;=&nbsp;*I2C_buf++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2CONCLR&nbsp;=&nbsp;0xX28;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2C_num--;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{;//省略}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />这里的程序能看出I2C发送数据没有判断是否接收了应答信号ACK。<br /><br />难道I2C主机可以连续发送数据,不用判断从机是否有应答信号或非应答信号?
malaohu 发表于 2007-4-20 17:29 | 显示全部楼层

我也在看I2C,问题多了

  
malaohu 发表于 2007-4-20 17:40 | 显示全部楼层

您能帮我解答这个问题么

书上说的是,通过软件置位STA后才进入I2C模式,立即发送一个起始条件。在这个实验的主函数里只是启动了i2c(&nbsp;I2CONSET&nbsp;=&nbsp;0x40;),可是没有发送起始信号啊。所以,我认为这样的话,i2c的中断标志位SI是不会置一的,无法进入中断啊。
hotpower 发表于 2007-4-20 19:09 | 显示全部楼层

LPCARM之I2C中断读写CAT1025C++程序祥解

  <br /> 相关链接:<a href='http://www.**/blog/hotpower/18019/message.aspx'>http://www.**/blog/hotpower/18019/message.aspx</a>
 楼主| newman2008 发表于 2007-4-21 09:30 | 显示全部楼层

应答信号不需要?

I2C的描述中有这么一段:<br />&quot;页写(PAGE&nbsp;WRITE),即一次性连续写8个字节,但采用页写方式时每个字节后要有一个应答信号。&quot;<br /><br /><br />但是,从上面的周立功的I2C程序里没有判断接收应答信号.<br />难道I2C主机可以连续发送数据,<br />不用判断从机是否有应答信号或非应答信号?<br /><br />
dzycp 发表于 2007-4-22 17:21 | 显示全部楼层

当中断后

当中断后,如果在switch中跳到了下面这条语句,(case&nbsp;0x28:&nbsp;//已发送I2C数据,并接收到应答)就表示I2C已经收到正确的应答,0x28可以在数据手册中找到定义,我用中断和查询两种方式编写过读取eeprom的程序,不知到这样理解对不对,大家多交流。
 楼主| newman2008 发表于 2007-4-23 17:02 | 显示全部楼层

当发送一个数据后

发送完一个数据后,应该有一个信答信号,<br />现在程序没有接收应答信号,就直接连续不断地发送.这样可以的吗?
zlgARM 发表于 2007-4-24 22:54 | 显示全部楼层

newman2008

I2C软件包的核心在于I2C的IRQ。<br />I2C总线发生什么典型事件——〉触发I2C_IRQ——〉判断是什么事件发生了(用户在IRQ里查询I2C状态寄存器)——〉再跳到相应的入口执行相应的操作——〉退出IRQ。<br /><br />至于你说的情况。<br />实际上就是发生了“已发送数据,并接收到ACK”,然后再执行相应操作(发送发送缓存里的下一个数据)。<br /><br />通过中断和状态寄存器,我们就能实现复杂的I2C协议处理了。状态寄存器是核心,中断是一个通知机制。
zlgARM 发表于 2007-4-24 23:04 | 显示全部楼层

马老虎

其实发送了起始信号了!<br /><br />手头没有源码。<br />估计是I2CINIT里使能了I2C总线。<br />I2C的数据发送函数里,准备好了从器件地址、发送数据信息后,再置位起始标志发送起始信号。<br />马老虎看一下函数源代码。<br /><br />
 楼主| newman2008 发表于 2007-4-25 10:43 | 显示全部楼层

仍有疑问

多谢周工及大大们解答<br /><br />但仍有一个问题请教诸位<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;I2C程序中,连续发送数据,没有应答信号。<br />就是在程序中的if循环体内(在下面),进行数据连续发送,直到数据发送为止.<br />当然在这个循环体内部清除了中断标志,可以I2C中断产生.<br />要考虑的是从中断标志清除到中断产生所需要的时间,与if循环体循环一次<br />所要的时间想比,那一个的时间更短。<br />{if(I2C_num&gt0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2DAT&nbsp;=&nbsp;*I2C_buf++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2CONCLR&nbsp;=&nbsp;0xX28;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2C_num--;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;按照周工的I2C程序,明显就是“从中断标志清除到中断产生所需要的时间”<br />比“if循环体循环一次所要的时间”要短,所以能够接收到应答信号,但是<br />真是是中断的时间比循环的时间短吗?<br /><br />请周工及各位大大帮忙解答。。。。多谢。
malaohu 发表于 2007-4-25 14:44 | 显示全部楼层

还有疑问~!

&nbsp;case&nbsp;&nbsp;0x08:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;己发送起始条件<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(1==I2C_suba_en)&nbsp;I2DAT&nbsp;=&nbsp;I2C_sla&0xFE;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;指定子地址读时,先写入地址且第8位为0<br /><br /><br />这儿我觉得不对啊,if(1==I2C_suba_en)这儿是有子地址读,那么I2DAT&nbsp;=&nbsp;I2C_sla&0xFE;不应该将最后一位清零啊,读的话最低位应该为1的啊。<br /><br />下面我看了&nbsp;&nbsp;向有子地址器件读取多字节数据函数中,有下面一句:<br />I2C_sla&nbsp;=&nbsp;sla+1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;读操作的器件地址<br /><br />可是这也不应该影响最低位为1&nbsp;啊。<br />
malaohu 发表于 2007-4-25 15:04 | 显示全部楼层

已经解决

注释已说明了(//&nbsp;指定子地址读时,先写入地址且第8位为0),即“选择性读”,需要先“写”入子地址,即:起动总线-&gt从地址(““写””)-&gt子地址-&gt重新起动总线-&gt从地址(读)-&gt接收数据...&nbsp;-&gt结束总线。
 楼主| newman2008 发表于 2007-4-25 17:00 | 显示全部楼层

疑问latest?

&nbsp;&nbsp;&nbsp;I2C程序中,连续发送数据,没有应答信号。<br />就是在程序中的if循环体内(在下面),进行数据连续发送,直到数据发送为止.<br />当然在这个循环体内部清除了中断标志,可以I2C中断产生.<br />要考虑的是从中断标志清除到中断产生所需要的时间,与if循环体循环一次<br />所要的时间想比,那一个的时间更短。<br />{if(I2C_num&gt0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2DAT&nbsp;=&nbsp;*I2C_buf++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2CONCLR&nbsp;=&nbsp;0xX28;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2C_num--;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;按照周工的I2C程序,明显就是“从中断标志清除到中断产生所需要的时间”<br />比“if循环体循环一次所要的时间”要短,所以能够接收到应答信号,但是<br />真是是中断的时间比循环的时间短吗?
zlgARM 发表于 2007-4-25 21:33 | 显示全部楼层

newman2008

哪里来的if循环体?您再仔细看看,循环执行if吗?
malaohu 发表于 2007-4-26 10:13 | 显示全部楼层

我帮你回答

情况是这样的:这不是循环,这是if语句.这儿的自加减是为下面的0x28服务的。<br /><br />每次运行完,跳出if语句,此时的自加减已经进行。并且数据已经写到I2DAT,清零SI后,数据发送.&nbsp;SI再次置位,状态码仍然是0x28,所以进入0x28的if语句。直到I2C_num=0.<br /><br />呵呵,没想到,我还能帮人解决问题:)
 楼主| newman2008 发表于 2007-4-26 16:37 | 显示全部楼层

多谢

<b>case&nbsp;0x28:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//已发送I2C数据,并接收到应答<br />&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(0==I2C_suba_en)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//无子地址直接发送数据<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{if(I2C_num&gt0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2DAT&nbsp;=&nbsp;*I2C_buf++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2CONCLR&nbsp;=&nbsp;0xX28;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2C_num--;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{;//省略}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />当进入到case&nbsp;0x28语句后,再进入到下面的if语句,(是条件判断,不是循环)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(I2C_num&gt0)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2DAT&nbsp;=&nbsp;*I2C_buf++;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2CONCLR&nbsp;=&nbsp;0xX28;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I2C_num--;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />这个if语句的执行过程是这样的吗?<br />如下:<br />&nbsp;&nbsp;&nbsp;(1)假设要发送的数据有10个字节,即I2C_num=10.<br />则语句I2C_num&gt0成立,执行if下面的语句.<br /><br />&nbsp;&nbsp;&nbsp;(2)I2DAT&nbsp;=&nbsp;*I2C_buf++;发送一个字节数据.<br />然后:<br />&nbsp;&nbsp;&nbsp;(3)I2CONCLR&nbsp;=&nbsp;0xX28;把起始标志清零,和把I2C中断标志清零<br />(I2C中断标志清零,那么只要有中断主可以再次执行)<br /><br />&nbsp;&nbsp;&nbsp;(4)I2C_num--;自减一操作(这时I2C_num&gt0)<br />再次回到if语句判断I2C_num&gt0是否成立,因为I2C_num=9,所以成立,继续执行<br />if语句.再次回到(2)处,然后往下执行。<br /><br />直到I2C_num的值为0,这10次if语句的执行有接收从机发过来的应答信号吗?有的话,请指教。。。<br /><br /><br />这就是有一个问题:<br />执行一个&nbsp;&nbsp;if(){;//其它&nbsp;语句}&nbsp;&nbsp;的时间,与中断所需要的时间,到底那个时间更短?<br /><br />(A)若是中断时间更短,是可以连接发送数据?<br />(B)若是if(){;//其它&nbsp;语句}&nbsp;&nbsp;的时间短,呢??/</b>
zlgARM 发表于 2007-4-26 22:05 | 显示全部楼层

newman

&nbsp;&nbsp;&nbsp;“(4)I2C_num--;自减一操作(这时I2C_num&gt0)<br />再次回到if语句判断I2C_num&gt0是否成立,因为I2C_num=9,所以成立,继续执行<br />if语句.再次回到(2)处,然后往下执行。”<br />&nbsp;&nbsp;&nbsp;您可以自己编写一个小程序,观察条件为真时所执行的分支语句,执行了一次后,是否还会返回继续执行if()的判断。<br />&nbsp;&nbsp;&nbsp;必须自己动手试一下。答案在实践中,在书中。<br />
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

44

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部