LPC_11C14平台I2C分析

作者:周志强,华清远见嵌入式培训中心讲师。

1) IIC的初始化:复位IIC,使能IIC时钟单元,设置相应的I0口为IIC功能,清除应答位、起始位、中断位、IIC使能位,设置IIC传输速率,如果是从机的话,设置从机地址,IIC中断使能,最后启动IIC.

2) IIC的启动

uint32_t I2CStart( void )
        {
                uint32_t timeout = 0;
                uint32_t retVal = FALSE;
                LPC_I2C->CONSET = I2CONSET_STA //设置起始位
                /*循环等待起始位发送,设置超时时间*/
                while( 1 )
        {
                if ( I2CMasterState == I2C_STARTED ) //起始位发送成功,中断中设置
                {
                retVal = TRUE;
                break;
                }
                if ( timeout >= I2C_MAX_TIMEOUT ) //起始位发送超时
                {
                        retVal = FALSE;
                        break;
                }
                timeout++;
                }
                return( retVal );
                }
        3)IIC的停止
        uint32_t I2CStop( void )
        {
                LPC_I2C->CONSET = I2CONSET_STO; //设置停止位
                LPC_I2C->CONCLR = I2CONCLR_SIC; //清除中断标志
                /*等待停止位发送*/
                while( LPC_I2C->CONSET & I2CONSET_STO );
                return TRUE;
        }
        4)IIC的一次完整通信
        uint32_t I2CEngine( void )
        {
                I2CMasterState = I2C_IDLE; //初始状态
                RdIndex = 0;
                WrIndex = 0;
                if ( I2CStart() != TRUE ) //发送启动信号
        {
                I2CStop();
                return ( FALSE );
        }

        while ( 1 )
        {
                if ( I2CMasterState == DATA_NACK ) //判断数据是否传输完毕
                {
                        I2CStop(); //IIC停止
                        break;
                }
        }
        return ( TRUE );
        }
        5)主发送代码
        void I2CWrite(uint8_t addr, uint8_t* buf, uint32_t len)
        {

                I2CAddr = addr; //设置从机地址
                I2CMasterBuffer = buf; //主发送Buffer指向要传输的数据
                I2CWriteLength = len; //发送数据的长度
                I2CReadLength = 0;
                I2CEngine(); //启动IIC完整的通信过程
                I2CWriteLength = I2CWriteLength;
        }
        6)中断处理函数
        每次状态的改变,SI位都会置位,在中断处理函数中,根据不同的状态码,进行相应的操作,在这些操作中,清除SI位是必须要做的,在这里主要列出主发送中断的处理函数部分,其他部分可根据数据手册的操作流程进行相应的操作。
        void I2C_IRQHandler(void)
        {
                uint8_t StatValue;
                /* 仅列出了主发送方式的处理*/
                StatValue = LPC_I2C->STAT; //读取状态码
                witch ( StatValue ) //根据状态码执行不同的操作
        {
        case 0x08: //已发送起始条件
        WrIndex = 0;
        LPC_I2C->DAT = I2CAddr; //SLA + W装入数据寄存器
        LPC_I2C->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);//请吃 SIC及STAC位
        I2CMasterState = I2C_STARTED;
        break;

        case 0x10: //已发送重复起始条件
        RdIndex = 0;
        /* 发送SLA + R状态位 */
        LPC_I2C->DAT = I2CAddr;
        LPC_I2C->CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
        I2CMasterState = I2C_RESTARTED;
        break;

        case 0x18: //以发送SLA + W,并已接受ACK
        if ( I2CMasterState == I2C_STARTED )
        {
                LPC_I2C->DAT = I2CMasterBuffer[WrIndex++]; //发送数据写入DATA寄存器
                I2CMasterState = DATA_ACK;
        }
        LPC_I2C->CONCLR = I2CONCLR_SIC;
        break;

        case 0x28: /* 数据已发送,返回ACK或非ACK*/
        case 0x30:
        if ( WrIndex < I2CWriteLength ) //判断是否发送完,未完继续发送
        {
                LPC_I2C->DAT = I2CMasterBuffer[WrIndex++];
                I2CMasterState = DATA_ACK;
        }
        Else //指定长度的数据已发送完
        {
                if ( I2CReadLength != 0 )
                {
                        LPC_I2C->CONSET = I2CONSET_STA; //设置重复起始条件
                        I2CMasterState = I2C_REPEATED_START;
                }
        else
                {
                        I2CMasterState = DATA_NACK;
                        LPC_I2C->CONSET = I2CONSET_STO; // 置位停止位
                }
        }
        LPC_I2C->CONCLR = I2CONCLR_SIC;
        break;
        ……

你可能感兴趣的:(分析)