IIC实验

[复制链接]
 楼主| poplaji 发表于 2013-5-10 00:52 | 显示全部楼层 |阅读模式
本帖最后由 poplaji 于 2013-5-10 01:10 编辑

IIC测试代码里面的向从机写数据函数里面调用了IicPoll这样一个函数,他和中断函数几乎一模一样,中断函数都执行过了,不知道这个函数存在的作用是什么,求大侠们赐教!~
void _Wr24C080(U32 slvAddr,U32 addr,U8 data)
{
    _iicMode      = WRDATA;
    _iicPt        = 0;
    _iicData[0]   = (U8)addr;
    _iicData[1]   = data;
    _iicDataCount = 2;
   
    rIICDS        = slvAddr;            //0xa0
      //Master Tx mode, Start(Write), IIC-bus data output enable
      //Bus arbitration sucessful, Address as slave status flag Cleared,
      //Address zero status flag cleared, Last received bit is 0
    rIICSTAT      = 0xf0;      
      //Clearing the pending bit isn't needed because the pending bit has been cleared.
    while(_iicDataCount!=-1)         //中断函数里面对iicDataCount进行--操作,也就是这个循环一直在等中断,而中断函数和IicPoll几乎一摸一样,这个IicPoll的作用?               
       Run_IicPoll();                                    

    _iicMode = POLLACK;
    while(1)
    {
        rIICDS     = slvAddr;
        _iicStatus = 0x100;             //To check if _iicStatus is changed
        rIICSTAT   = 0xf0;              //Master Tx, Start, Output Enable, Sucessful, Cleared, Cleared, 0
        rIICCON    = 0xaf;              //Resumes IIC operation.
        while(_iicStatus==0x100)  
            Run_IicPoll();
              
        if(!(_iicStatus & 0x1))
            break;                      //When ACK is received
    }
    rIICSTAT = 0xd0;                    //Master Tx condition, Stop(Write), Output Enable
    rIICCON  = 0xaf;                    //Resumes IIC operation.
    Delay(1);                           //Wait until stop condtion is in effect.
      //Write is completed.
}
        
**********************[ Run_IicPoll ]*********************************
void Run_IicPoll(void)

{
    if(rIICCON & 0x10)                  //Tx/Rx Interrupt Enable
       IicPoll();
}      
   
//**********************[IicPoll ]**************************************
void IicPoll(void)
{
    U32 iicSt,i;
   
    iicSt = rIICSTAT;
    if(iicSt & 0x8){}                   //When bus arbitration is failed.
    if(iicSt & 0x4){}                   //When a slave address is matched with IICADD
    if(iicSt & 0x2){}                   //When a slave address is 0000000b
    if(iicSt & 0x1){}                   //When ACK isn't received
    switch(_iicMode)
    {
        case POLLACK:
            _iicStatus = iicSt;
            break;
        case RDDATA:
            if((_iicDataCount--)==0)
            {
                _iicData[_iicPt++] = rIICDS;
            
                rIICSTAT = 0x90;                //Stop MasRx condition
                rIICCON  = 0xaf;                //Resumes IIC operation.
                Delay(1);                       //Wait until stop condtion is in effect.
                                                //Too long time...
                                                //The pending bit will not be set after issuing stop condition.
                break;   
            }      
            _iicData[_iicPt++] = rIICDS;
                        //The last data has to be read with no ack.
            if((_iicDataCount)==0)
                rIICCON = 0x2f;                 //Resumes IIC operation with NOACK.  
            else
                rIICCON = 0xaf;                 //Resumes IIC operation with ACK
            break;
        case WRDATA:
            if((_iicDataCount--)==0)
            {
                rIICSTAT = 0xd0;                //stop MasTx condition
                rIICCON  = 0xaf;                //resumes IIC operation.
                Delay(1);                       //wait until stop condtion is in effect.
                       //The pending bit will not be set after issuing stop condition.
                break;   
            }
            rIICDS = _iicData[_iicPt++];        //_iicData[0] has dummy.
            for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL
            rIICCON = 0xaf;                     //resumes IIC operation.
            break;
        case SETRDADDR:
//          Uart_Printf("[S%d]",_iicDataCount);
            if((_iicDataCount--)==0)
            {
                break;                  //IIC operation is stopped because of IICCON[4]   
            }
            rIICDS = _iicData[_iicPt++];
            for(i=0;i<10;i++);          //for setup time until rising edge of IICSCL
            rIICCON = 0xaf;             //resumes IIC operation.
            break;
        default:
            break;      
    }
}
Mr_driver 发表于 2013-5-10 10:19 | 显示全部楼层
他和中断函数几乎一模一样
几乎一样,到底是一样还是不一样呢?
个人理解:IicPoll()函数用switch/case封装了几种不同的操作,虽然在不同的地方都调用它,但根据判断条件执行的操作不一样,比如产生读/写中断时,对应执行的是 case RDDATA/ case WRDATA。在上面的_Wr24C080()函数中,开始_iicMode = WRDATA,进入第一个while就执行case WRDATA后面的操作,当_iicDataCount减到0时,就会break出第一个while,然后_iicMode的值会变成POLLACK。由于进入第二个while的时候,_iicStatus起始就等于0x100,显然会直接进入嵌套while,再次进入Run_IicPoll()时,首先会判断if(rIICCON & 0x10) ,前面执行case WRDATA时会把rllCCON的值resume成0xaf,所以条件还是成立的,就会再次执行IicPoll(),但这次执行的是case POLLACK,接收ack成功,写操作就执行完了。
 楼主| poplaji 发表于 2013-5-10 12:35 来自手机 | 显示全部楼层
中断函数就是在这个函数前面清除了一下iic的中断标志,这些在中断函数里面已经做过了,为什么还要再循环里面在执行一遍?
Mr_driver 发表于 2013-5-10 15:53 | 显示全部楼层
你的中断函数贴上来看下
 楼主| poplaji 发表于 2013-5-10 16:25 | 显示全部楼层
Mr_driver 发表于 2013-5-10 15:53
你的中断函数贴上来看下
  1. void __irq IicInt(void)
  2. {
  3.         U32 iicSt,i;
  4.    
  5.         rSRCPND = BIT_IIC;          //Clear pending bit
  6.         rINTPND = BIT_IIC;
  7.         iicSt   = rIICSTAT;
  8.    
  9.         if(iicSt & 0x8){}           //When bus arbitration is failed.
  10.         if(iicSt & 0x4){}           //When a slave address is matched with IICADD
  11.         if(iicSt & 0x2){}           //When a slave address is 0000000b
  12.         if(iicSt & 0x1){}           //When ACK isn't received

  13.         switch(_iicMode)
  14.         {
  15.                 case POLLACK:
  16.                         _iicStatus = iicSt;
  17.                         break;

  18.                 case RDDATA:
  19.                         if((_iicDataCount--)==0)
  20.                         {
  21.                                 _iicData[_iicPt++] = rIICDS;
  22.             
  23.                                 rIICSTAT = 0x90;                 //Stop MasRx condition
  24.                                 rIICCON  = 0xaf;                 //Resumes IIC operation.
  25.                                 Delay(1);                        //Wait until stop condtion is in effect.
  26.                                                 //Too long time.                    //The pending bit will not be set after issuing stop condition.
  27.                                 break;   
  28.                          }      
  29.                         _iicData[_iicPt++] = rIICDS;         //The last data has to be read with no ack.

  30.                         if((_iicDataCount)==0)
  31.                                 rIICCON = 0x2f;                  //Resumes IIC operation with NOACK.  
  32.                         else
  33.                                 rIICCON = 0xaf;                  //Resumes IIC operation with ACK
  34.                         break;

  35.                 case WRDATA:
  36.                         if((_iicDataCount--)==0)
  37.                         {
  38.                                 rIICSTAT = 0xd0;                //Stop MasTx condition
  39.                                 rIICCON  = 0xaf;                //Resumes IIC operation.
  40.                                 Delay(1);                       //Wait until stop condtion is in effect.
  41.                                 //The pending bit will not be set after issuing stop condition.
  42.                                 break;   
  43.                         }
  44.                         rIICDS = _iicData[_iicPt++];        //_iicData[0] has dummy.
  45.                         for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL
  46.               
  47.                         rIICCON = 0xaf;                     //resumes IIC operation.
  48.                         break;

  49.                 case SETRDADDR:
  50.                         if((_iicDataCount--)==0)
  51.                         break;                          //IIC operation is stopped because of IICCON[4]   
  52.                         rIICDS = _iicData[_iicPt++];
  53.                         for(i=0;i<10;i++);                  //For setup time until rising edge of IICSCL
  54.                         rIICCON = 0xaf;                     //Resumes IIC operation.
  55.                         break;

  56.                 default:
  57.                         break;      
  58.         }
  59. }
Mr_driver 发表于 2013-5-10 16:51 | 显示全部楼层
也就是这个循环一直在等中断

你确定?
ghkt2000 发表于 2013-5-10 17:02 | 显示全部楼层
 楼主| poplaji 发表于 2013-5-10 17:03 | 显示全部楼层
Mr_driver 发表于 2013-5-10 16:51
你确定?

我在去仔细对一下。
刚才我跑了一下,好像
  while(_iicDataCount!=-1)                    
       Run_IicPoll();
这样不行,把所有Run_IicPoll去掉可以,改成
while(_iicDateCount!=-1);就可以了

他那个测试程序可能是关闭中断用查询标志位的方式来做的。
Mr_driver 发表于 2013-5-10 17:13 | 显示全部楼层
我们目前用的是linux,不太了解你的平台中断处理逻辑,不知道你的中断处理例程(ISR)和触发条件是怎么关联的,如果是确定在第一个while循环等待中断,那后边的Run_licPoll()完全是多余的,按你上面的结论这也是正解。
 楼主| poplaji 发表于 2013-5-10 17:53 | 显示全部楼层
Mr_driver 发表于 2013-5-10 17:13
我们目前用的是linux,不太了解你的平台中断处理逻辑,不知道你的中断处理例程(ISR)和触发条件是怎么关联 ...

搞清楚了。。。。。如果加Run_IicPoll的话,主程序中没有开中断、、、、如果不加的话是中断处理,加了是循环查询。。。。不好意思,我都是半夜看这个,可能是脑子都木了、、、、谢谢了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

12

主题

62

帖子

0

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

12

主题

62

帖子

0

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