TQ2440之I2C操作

 开启IIC时钟:

 CLKCON |= (1<<10)|(1<<13); //开启串口0时钟

 中断服务程序:

void  IRQ_Handler(void) __irq //irq中断函数
{
    switch(INTOFFSET)
    {
        case 27:
        irq_IIC();//中断处理程序
        break;
    }
}

 中断处理函数:

void irq_IIC(void)
{
    unsigned int iicSt,i;

    SRCPND = BIT_IIC;          //Clear pending bit
    INTPND = BIT_IIC;
    iicSt   = IICSTAT; 
    
    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;      //0xf0
           break;

       case RDDATA:
           if((_iicDataCount--)==0)
           {
               _iicData[_iicPt++] = IICDS;
            
               IICSTAT = 0x90;                 //Stop MasRx condition     1001 0000
               IICCON  = 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++] = IICDS;         //The last data has to be read with no ack.

           if((_iicDataCount)==0)
               IICCON = 0x2f;                  //Resumes IIC operation with NOACK.  
           else 
               IICCON = 0xaf;                  //Resumes IIC operation with ACK
               break;

        case WRDATA:
            if((_iicDataCount--)==0)
            {
                IICSTAT = 0xd0;                //Stop MasTx condition 
                IICCON  = 0xaf;                //Resumes IIC operation.  1010 1111
                Delay(1);                       //Wait until stop condtion is in effect.
                       //The pending bit will not be set after issuing stop condition.
                break;    
            }
            IICDS = _iicData[_iicPt++];        //_iicData[0] has dummy.  发送接收数据移位寄存器
            for(i=0;i<10;i++);                  //for setup time until rising edge of IICSCL
            IICCON = 0xaf;                     //resumes IIC operation.
            break;

        case SETRDADDR:
//          Uart_Printf("[ S%d ]",_iicDataCount);
            if((_iicDataCount--)==0)
                break;                          //IIC operation is stopped because of IICCON[4]    
            IICDS = _iicData[_iicPt++];
            for(i=0;i<10;i++);                  //For setup time until rising edge of IICSCL
            IICCON = 0xaf;                     //Resumes IIC operation.
            break;

        default:
            break;      
    }
}

 

写一个字节函数:

void Wr24C080(unsigned char slvAddr,unsigned char addr,unsigned char data)
{
    _iicMode      = WRDATA;
    _iicPt        = 0;
    _iicData[0]   = (unsigned char)addr;
    _iicData[1]   = data;
    _iicDataCount = 2;
    
    IICDS   = slvAddr;                 //0xa0
    IICSTAT = 0xf0;                    //MasTx,Start
      //Clearing the pending bit isn't needed because the pending bit has been cleared.
    
    while(_iicDataCount!=-1);

    _iicMode = POLLACK;

    while(1)
    {
        IICDS     = slvAddr;
        _iicStatus = 0x100;
        IICSTAT   = 0xf0;              //MasTx,Start
        IICCON    = 0xaf;              //Resumes IIC operation. 
           
        while(_iicStatus==0x100);
           
        if(!(_iicStatus&0x1))
            break;                      //When ACK is received
    }
    IICSTAT = 0xd0;                    //Stop MasTx condition 
    IICCON  = 0xaf;                    //Resumes IIC operation. 
    Delay(1);                           //Wait until stop condtion is in effect.
       //Write is completed.
}

读一个字节函数:

void Rd24C080(unsigned char slvAddr,unsigned char addr,unsigned char *data)
{
    _iicMode      = SETRDADDR;
    _iicPt        = 0;
    _iicData[0]   = (unsigned char)addr;
    _iicDataCount = 1;

    IICDS   = slvAddr;
    IICSTAT = 0xf0;                    //MasTx,Start  
      //Clearing the pending bit isn't needed because the pending bit has been cleared.
    while(_iicDataCount!=-1);

    _iicMode      = RDDATA;
    _iicPt        = 0;
    _iicDataCount = 1;
    
    IICDS        = slvAddr;
    IICSTAT      = 0xb0;               //MasRx,Start
    IICCON       = 0xaf;               //Resumes IIC operation.   
    while(_iicDataCount!=-1);

    *data = _iicData[1];
}

IIC测试程序:

void Test_Iic(void)
{
    unsigned int i,j,save_E,save_PE;
    static unsigned char data[256];

    Uart_Printf("\n\rIIC Test(Interrupt) using AT24C02\n\r");

    save_E   = GPECON;
    save_PE  = GPEUP;
    GPEUP  |= 0xc000;                  //Pull-up disable
    GPECON |= 0xa0000000;                //GPE15:IICSDA , GPE14:IICSCL 

    //pISR_IIC = (unsigned)IicInt;
    INTMSK &= ~(BIT_IIC);

      //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16
      // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz
    IICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);

    IICADD  = 0x10;                    //2440 slave address = [7:1]
    IICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)
    IICLC = (1<<2)|(1);                  // Filter enable, 15 clocks SDA output delay       added by junon
    
    Uart_Printf("\rWrite test data into AT24C02\n");

    for(i=0;i<256;i++)
        Wr24C080(0xa0,(unsigned char)i,i);//字节写
           
    for(i=0;i<256;i++)
        data[i] = 0;

    Uart_Printf("\rRead test data from AT24C02\n");
    
    for(i=0;i<256;i++)
        Rd24C080(0xa0,(unsigned char)i,&(data[i])); //选择读时序

        //Line changed 0 ~ f
    for(i=0;i<16;i++)
    {
                Uart_Printf("\r");
        for(j=0;j<16;j++)
            Uart_Printf("%2x ",data[i*16+j]);
        Uart_Printf("\n");
    }
    INTMSK |= BIT_IIC;    
    GPEUP  = save_PE;
    GPECON = save_E;
}
posted @ 2013-01-08 00:02  zpehome  阅读(303)  评论(0编辑  收藏  举报