打印
[ZLG-ARM]

请教周工:I2C状态码*****!!!

[复制链接]
2309|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
newman2008|  楼主 | 2007-4-20 16:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
周工的I2C程序里有这么一段:
case 0x28:                   //已发送I2C数据,并接收到应答
    if (0==I2C_suba_en)      //无子地址直接发送数据
     {if(I2C_num>0)
      {
        I2DAT = *I2C_buf++;
        I2CONCLR = 0xX28;
        I2C_num--;
      }
    else
      {;//省略}

     }
这里的程序能看出I2C发送数据没有判断是否接收了应答信号ACK。

难道I2C主机可以连续发送数据,不用判断从机是否有应答信号或非应答信号?

相关帖子

沙发
malaohu| | 2007-4-20 17:29 | 只看该作者

我也在看I2C,问题多了

使用特权

评论回复
板凳
malaohu| | 2007-4-20 17:40 | 只看该作者

您能帮我解答这个问题么

书上说的是,通过软件置位STA后才进入I2C模式,立即发送一个起始条件。在这个实验的主函数里只是启动了i2c( I2CONSET = 0x40;),可是没有发送起始信号啊。所以,我认为这样的话,i2c的中断标志位SI是不会置一的,无法进入中断啊。

使用特权

评论回复
地板
hotpower| | 2007-4-20 19:09 | 只看该作者

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

使用特权

评论回复
5
newman2008|  楼主 | 2007-4-21 09:30 | 只看该作者

应答信号不需要?

I2C的描述中有这么一段:
"页写(PAGE WRITE),即一次性连续写8个字节,但采用页写方式时每个字节后要有一个应答信号。"


但是,从上面的周立功的I2C程序里没有判断接收应答信号.
难道I2C主机可以连续发送数据,
不用判断从机是否有应答信号或非应答信号?

使用特权

评论回复
6
dzycp| | 2007-4-22 17:21 | 只看该作者

当中断后

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

使用特权

评论回复
7
newman2008|  楼主 | 2007-4-23 17:02 | 只看该作者

当发送一个数据后

发送完一个数据后,应该有一个信答信号,
现在程序没有接收应答信号,就直接连续不断地发送.这样可以的吗?

使用特权

评论回复
8
zlgARM| | 2007-4-24 22:54 | 只看该作者

newman2008

I2C软件包的核心在于I2C的IRQ。
I2C总线发生什么典型事件——〉触发I2C_IRQ——〉判断是什么事件发生了(用户在IRQ里查询I2C状态寄存器)——〉再跳到相应的入口执行相应的操作——〉退出IRQ。

至于你说的情况。
实际上就是发生了“已发送数据,并接收到ACK”,然后再执行相应操作(发送发送缓存里的下一个数据)。

通过中断和状态寄存器,我们就能实现复杂的I2C协议处理了。状态寄存器是核心,中断是一个通知机制。

使用特权

评论回复
9
zlgARM| | 2007-4-24 23:04 | 只看该作者

马老虎

其实发送了起始信号了!

手头没有源码。
估计是I2CINIT里使能了I2C总线。
I2C的数据发送函数里,准备好了从器件地址、发送数据信息后,再置位起始标志发送起始信号。
马老虎看一下函数源代码。

使用特权

评论回复
10
newman2008|  楼主 | 2007-4-25 10:43 | 只看该作者

仍有疑问

多谢周工及大大们解答

但仍有一个问题请教诸位

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

请周工及各位大大帮忙解答。。。。多谢。

使用特权

评论回复
11
malaohu| | 2007-4-25 14:44 | 只看该作者

还有疑问~!

 case  0x08:                   // 己发送起始条件
            if(1==I2C_suba_en) I2DAT = I2C_sla&0xFE;    // 指定子地址读时,先写入地址且第8位为0


这儿我觉得不对啊,if(1==I2C_suba_en)这儿是有子地址读,那么I2DAT = I2C_sla&0xFE;不应该将最后一位清零啊,读的话最低位应该为1的啊。

下面我看了  向有子地址器件读取多字节数据函数中,有下面一句:
I2C_sla = sla+1;        // 读操作的器件地址

可是这也不应该影响最低位为1 啊。

使用特权

评论回复
12
malaohu| | 2007-4-25 15:04 | 只看该作者

已经解决

注释已说明了(// 指定子地址读时,先写入地址且第8位为0),即“选择性读”,需要先“写”入子地址,即:起动总线->从地址(““写””)->子地址->重新起动总线->从地址(读)->接收数据... ->结束总线。

使用特权

评论回复
13
newman2008|  楼主 | 2007-4-25 17:00 | 只看该作者

疑问latest?

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

使用特权

评论回复
14
zlgARM| | 2007-4-25 21:33 | 只看该作者

newman2008

哪里来的if循环体?您再仔细看看,循环执行if吗?

使用特权

评论回复
15
malaohu| | 2007-4-26 10:13 | 只看该作者

我帮你回答

情况是这样的:这不是循环,这是if语句.这儿的自加减是为下面的0x28服务的。

每次运行完,跳出if语句,此时的自加减已经进行。并且数据已经写到I2DAT,清零SI后,数据发送. SI再次置位,状态码仍然是0x28,所以进入0x28的if语句。直到I2C_num=0.

呵呵,没想到,我还能帮人解决问题:)

使用特权

评论回复
16
newman2008|  楼主 | 2007-4-26 16:37 | 只看该作者

多谢

case 0x28:                   //已发送I2C数据,并接收到应答
    if (0==I2C_suba_en)      //无子地址直接发送数据
     {if(I2C_num>0)
      {
        I2DAT = *I2C_buf++;
        I2CONCLR = 0xX28;
        I2C_num--;
      }
    else
      {;//省略}

     }
当进入到case 0x28语句后,再进入到下面的if语句,(是条件判断,不是循环)
     if(I2C_num>0)
      {
        I2DAT = *I2C_buf++;
        I2CONCLR = 0xX28;
        I2C_num--;
      }
这个if语句的执行过程是这样的吗?
如下:
   (1)假设要发送的数据有10个字节,即I2C_num=10.
则语句I2C_num>0成立,执行if下面的语句.

   (2)I2DAT = *I2C_buf++;发送一个字节数据.
然后:
   (3)I2CONCLR = 0xX28;把起始标志清零,和把I2C中断标志清零
(I2C中断标志清零,那么只要有中断主可以再次执行)

   (4)I2C_num--;自减一操作(这时I2C_num>0)
再次回到if语句判断I2C_num>0是否成立,因为I2C_num=9,所以成立,继续执行
if语句.再次回到(2)处,然后往下执行。

直到I2C_num的值为0,这10次if语句的执行有接收从机发过来的应答信号吗?有的话,请指教。。。


这就是有一个问题:
执行一个  if(){;//其它 语句}  的时间,与中断所需要的时间,到底那个时间更短?

(A)若是中断时间更短,是可以连接发送数据?
(B)若是if(){;//其它 语句}  的时间短,呢??/

使用特权

评论回复
17
zlgARM| | 2007-4-26 22:05 | 只看该作者

newman

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

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

44

帖子

0

粉丝