打印
[ZLG-ARM]

【SmartArm2200】I2C的问题【Arm嵌入式系统实验教程二】

[复制链接]
2143|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
51ti5000|  楼主 | 2007-1-18 10:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
周公好,
    又来麻烦你了,最近一周一直在看I2C的相关资料和你们写的源码,也在用开发板做实验,但还是有很多问题不明白,所以这里想详细问下。
    1,首先是这里
   void  __irq  IRQ_I2C(void)
{  uint8  sta;

   sta = I2STAT;                    // 读出I2C状态字
   switch(sta)
   {  case  0x08:                   // 己发送起始条件
            if(1==I2C_suba_en) I2DAT = I2C_sla&0xFE;    // 指定子地址读时,先写入地址
              else I2DAT = I2C_sla;                     // 否则直接发送从机地址
            I2CONCLR = 0x28;        // SI=0
            break;
Question1:为什么else后面不分情况?因为写操作时候(2==I2C_suba_en),也要写从机地址+子地址啊;2==I2C_suba_en和0==I2C_suba_en后面执行的动作肯定应该不一样啊,为什么不分情况,直接就else I2DAT = I2C_sla; ...了呢??
   2 case  0x18:                   // 已发送SLA+W,并已接收应答
            if(0==I2C_suba_en)      // 无子地址,则直接发送数据
            {  if(I2C_num>0)
               {  I2DAT = *I2C_buf++;
                  I2CONCLR = 0x28; 
                  I2C_num--;
               }
Question2:无子地址应该是写了从机地址+子地址后就可以叫无子地址了;在18H这个状态子地址肯定是没有写入到从机的啊,所以应该还有子地址,所以我的疑问是怎么会在case 18H的时候出现无子地址直接发送数据这个语句呢(就是我上面贴出来这句)??
   3  case  0x40:                   // 己发送SLA+R,并已接收到应答
            if(1==I2C_num)          // 最后一字节,接收数据后发送非应答信号
            {  I2CONCLR = 0x2C;     // AA=0,接收到数据后产生非应答
            }
            else                    // 接收数据并发送应答信号
            {  I2CONSET = 0x04;     // AA=1,接收到数据后产生应答
               I2CONCLR = 0x28;
            }
            break;
       case  0x50:
            *I2C_buf++ = I2DAT;     // 读取数据
            I2C_num--;
            if(1==I2C_num)
            {  I2CONCLR = 0x2C;     // AA=0,接收到数据后产生非应答
            }
            else
            {  I2CONSET = 0x04;     // AA=1,接收到数据后产生应答
               I2CONCLR = 0x28;
            }
            break;
Question3:40H是从机已经给主机发送了应答位,在case 40H这个语句里为什么没有象case 50H接受数据的语句?我分析是case 40H语句里是能够接受数据的。
Question4:为什么最后一字节用if(1==I2C_num)判断而不是if(0==I2C_num)??

相关帖子

沙发
51ti5000|  楼主 | 2007-1-18 11:04 | 只看该作者

Question5 Question5 Question5

Question5  
最后读取程序中的:
I2C_sla=sla+1;   怎么能保证sal最低位是0呢?如果是1,加1后就变成0了啊,?????????

使用特权

评论回复
板凳
51ti5000|  楼主 | 2007-1-18 12:55 | 只看该作者

顶一个吧

顶一个吧。。。。。。耐心等待

使用特权

评论回复
地板
51ti5000|  楼主 | 2007-1-18 15:15 | 只看该作者

顶一个吧。。。。。。耐心等待

顶一个吧。。。。。。耐心等待

使用特权

评论回复
5
ZLGARM| | 2007-1-18 15:35 | 只看该作者

re:

1. 在启动总线前(如IRcvByte函数),已正确设置好I2C_suba_en和I2C_sla
   I2C_suba_en=0, 读写操作要在I2C_sla正确设置(R/W位)
   I2C_suba_en=1, 要在I2C_sla正确设置R/W位为1 (读操作)
   I2C_suba_en=2, 要在I2C_sla正确设置R/W位为0 (读操作)

那么,只有在I2C_suba_en=1,要对I2C_sla进行&0xFE操作(先写子地址),其它情况直接使用I2C_sla即可。

2. 只要发送SLA+W,就会进入0x18状态,再进行子地址/数据发送。
   无子地址器件的操作: 启动 + SLA+W + 数据...
   有子地址器件的操作: 启动 + SAL+W + I2C_suba + 数据(或重启总线)...

3. 发送SLA+R后,就会进入0x40,还没有接收到任何数据。

4. 1==I2C_num,表示还要接收1字节数据,即最后一字节。
   执行I2CONCLR = 0x2C才开始接收。

5. 在调用IRcvByte等接口函数时,用户提供的sla的R/W位必须为0,否则出错。

使用特权

评论回复
6
51ti5000|  楼主 | 2007-1-18 21:49 | 只看该作者

关于Question1

首先谢谢zlgmcu百忙中抽时间给于我的回答,对于Question2--5我现在已经理解清楚,现在对于Question1还是有问题存在,比如有子地址的器件进行写操作的化,仍然也要进行写子地址啊,所以我认为2==I2C_suba_en时候,I2DAT的这句应该I2DAT = I2C_sla&0xFE,请周公指教!

使用特权

评论回复
7
ZLGARM| | 2007-1-19 08:35 | 只看该作者

re:

2==I2C_suba_en时,已正确设置好I2C_sla的R/W位为0,就不需要 &0xFE. 当然,如果使用也没有关系.

使用特权

评论回复
8
51ti5000|  楼主 | 2007-1-19 09:20 | 只看该作者

看来自己还是不会思考啊。

这么早ZLGARM就回我的问题,真是特别感谢!!大公司的人就是不一样啊!
看了ZLGARM最新的回答才知道自己是个不会思考的人啊,原来这个问题在ZLGARM第一次回答的时候就已经给出答案了:“在调用IRcvByte等接口函数时,用户提供的sla的R/W位必须为0,否则出错。”
最后还想问个问题,就是贵公司给出的这个I2C软件包根据我的分析应该是针对大多数I2C器件的,而不是仅仅针对CAT1025的,我这种理解对吗??
再次真心感谢!!!I LOVE THIS MCU!

使用特权

评论回复
9
51ti5000|  楼主 | 2007-1-19 11:11 | 只看该作者

新问题

再次重新综合起来看整个程序的时候,又产生了一个新问题
为何每个CASE 后面都要break?break的话不就跳出CASE程序了吗,直接跳到VICVectAddr0x00去了,这不就是关闭中断了吗??比如说我们想发送一连串字节,在case 0x18时候,执行完后break那么不就跳出去了吗,也就是根本没字节写进去了啊?

1 主程序里面设置了I2C为向量IRQ中断
2 I2C里面还设置了一个中断SI,这个SI中断是用来写数据到I2DAT的
  **所以我的理解是有两个中断 I2C本身是个中断,I2C里面SI还有个中断,中断这么嵌套的**
我想说的是 Q1那么到底有几个中断啊?
           Q2 那个break到底是怎么会事情??越想越糊涂了。。。。。

ZLGARM请指点迷津吧

使用特权

评论回复
10
51ti5000|  楼主 | 2007-1-22 14:24 | 只看该作者

新问题

再次重新综合起来看整个程序的时候,又产生了一个新问题
为何每个CASE 后面都要break?break的话不就跳出CASE程序了吗,直接跳到VICVectAddr0x00去了,这不就是关闭中断了吗??比如说我们想发送一连串字节,在case 0x18时候,执行完后break那么不就跳出去了吗,也就是根本没字节写进去了啊?

1 主程序里面设置了I2C为向量IRQ中断
2 I2C里面还设置了一个中断SI,这个SI中断是用来写数据到I2DAT的
  **所以我的理解是有两个中断 I2C本身是个中断,I2C里面SI还有个中断,中断这么嵌套的**
我想说的是 Q1那么到底有几个中断啊?
           Q2 那个break到底是怎么会事情??越想越糊涂了。。。。。

ZLGARM请指点迷津吧

使用特权

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

本版积分规则

4

主题

20

帖子

0

粉丝