打印

IIC实验

[复制链接]
2223|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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 | 只看该作者
你的中断函数贴上来看下

使用特权

评论回复
5
poplaji|  楼主 | 2013-5-10 16:25 | 只看该作者
Mr_driver 发表于 2013-5-10 15:53
你的中断函数贴上来看下
void __irq IicInt(void)
{
        U32 iicSt,i;
   
        rSRCPND = BIT_IIC;          //Clear pending bit
        rINTPND = BIT_IIC;
        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:
                        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;      
        }
}

使用特权

评论回复
6
Mr_driver| | 2013-5-10 16:51 | 只看该作者
也就是这个循环一直在等中断

你确定?

使用特权

评论回复
7
ghkt2000| | 2013-5-10 17:02 | 只看该作者

使用特权

评论回复
8
poplaji|  楼主 | 2013-5-10 17:03 | 只看该作者
Mr_driver 发表于 2013-5-10 16:51
你确定?

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

他那个测试程序可能是关闭中断用查询标志位的方式来做的。

使用特权

评论回复
9
Mr_driver| | 2013-5-10 17:13 | 只看该作者
我们目前用的是linux,不太了解你的平台中断处理逻辑,不知道你的中断处理例程(ISR)和触发条件是怎么关联的,如果是确定在第一个while循环等待中断,那后边的Run_licPoll()完全是多余的,按你上面的结论这也是正解。

使用特权

评论回复
10
poplaji|  楼主 | 2013-5-10 17:53 | 只看该作者
Mr_driver 发表于 2013-5-10 17:13
我们目前用的是linux,不太了解你的平台中断处理逻辑,不知道你的中断处理例程(ISR)和触发条件是怎么关联 ...

搞清楚了。。。。。如果加Run_IicPoll的话,主程序中没有开中断、、、、如果不加的话是中断处理,加了是循环查询。。。。不好意思,我都是半夜看这个,可能是脑子都木了、、、、谢谢了

使用特权

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

本版积分规则

12

主题

62

帖子

0

粉丝