新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > LPC23xx通過I2C接口讀寫AT24C64

        LPC23xx通過I2C接口讀寫AT24C64

        作者: 時(shí)間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
        網(wǎng)上關(guān)于philips的32位ARM微控制器通過I2C接口讀寫AT24C系列E2PROM的例子基本都是通過中斷方式讀寫的,包括周立功的書上也是用中斷方式的,用這種方式,要在中斷服務(wù)程序中進(jìn)行復(fù)雜的處理,程序比較難以理解,使用非中斷方式編程比較方便,便于理解。以下程序本人在LPC2364上測(cè)試通過。程序中的一些常量做了簡要說明,具體課查看LPC23xx系列微控制器的用戶手冊(cè)。

        I2C.h

        本文引用地址:http://www.104case.com/article/201611/317227.htm

        #define AT24C64NW 0xA0
        #define AT24C64NR 0xA1

        #define MAX_TIMEOUT0x00FFFFFF
        #define I2CONSET_I2EN0x00000040 /* I2C Control Set Register */
        #define I2CONSET_AA0x00000004
        #define I2CONSET_SI0x00000008
        #define I2CONSET_STO0x00000010
        #define I2CONSET_STA0x00000020

        #define I2CONCLR_AAC0x00000004 /* I2C Control clear Register */
        #define I2CONCLR_SIC0x00000008
        #define I2CONCLR_STAC0x00000020
        #define I2CONCLR_I2ENC0x00000040

        #define I2DAT_I2C0x00000000 /* I2C Data Reg */
        #define I2ADR_I2C0x00000000 /* I2C Slave Address Reg */
        #define I2SCLH_SCLH0x00000080 /* I2C SCL Duty Cycle High Reg */
        #define I2SCLL_SCLL0x00000080 /* I2C SCL Duty Cycle Low Reg */


        #define SDA0 0x08000000 //p0.27
        #define SCL0 0x10000000 //p0.28
        #define SDA0CON 0x08000000
        #define SCL0CON 0x10000000
        extern DWORD I2CInit( UINT32 Fi2c );
        extern DWORD I2CStart( void );
        extern DWORD I2CStop( void );
        extern DWORD I2CStartAgain( void );
        extern DWORD I2C_ReadByte(BYTE ACK, BYTE *RcvData);
        extern DWORD I2C_SendNByte(UINT16 SubAddr ,UINT8 *Data,UINT8 Length);
        extern DWORD I2C_ReadNByte(UINT16 SubAddr ,UINT8 *Data,UINT8 Length);

        I2C.c

        DWORD I2CInit( UINT32 Fi2c )

        {

        if (Fi2c > 400000)

        Fi2c = 400000;

        PINSEL1 &= ~0x03C00000;

        PINSEL1 |= 0x01400000;/* set PIO0.27 and PIO0.28 to I2C0 SDA and SCK */

        I20SCLH = (Fpclk/Fi2c + 1) / 2;/*設(shè)定I2C時(shí)鐘*/

        I20SCLL = (Fpclk/Fi2c)/2;

        I20CONCLR = 0x2C;// clear STA, SI,AA

        I20CONSET = 0x40;// SET I2EN/*使能主I2C */

        return( TRUE );

        }

        DWORD I2CStart( void )

        {

        DWORD timeout = 0;

        DWORD returnValue = FALSE;

        /*--- Issue a start condition ---*/

        I20CONCLR=I2CONCLR_SIC|I2CONCLR_AAC|I2CONCLR_STAC;

        I20CONSET=I2CONSET_STA|I2CONSET_I2EN;/* Set Start flag */

        /*--- Wait until START transmitted ---*/

        while( 1 )

        {

        if (I20STAT==0x08)

        {

        returnValue = TRUE;

        break;

        }

        if ( timeout >= MAX_TIMEOUT )

        {

        returnValue = FALSE;

        break;

        }

        timeout++;

        }

        return( returnValue );

        }

        DWORD I2CStartAgain( void )

        {

        DWORD timeout = 0;

        DWORD returnValue = FALSE;

        /*--- Issue a start condition ---*/

        I20CONCLR = I2CONCLR_SIC|I2CONCLR_AAC|I2CONCLR_STAC;//發(fā)送重復(fù)起始條件前一定要清零SI

        I20CONSET = I2CONSET_STA|I2CONSET_I2EN;/* Set Start flag */

        /*--- Wait until START transmitted ---*/

        while( 1 )

        {

        if ( I20STAT == 0x10 )

        {

        returnValue = TRUE;

        break;

        }

        if ( timeout >= MAX_TIMEOUT )

        {

        returnValue = FALSE;

        break;

        }

        timeout++;

        }

        return( returnValue );

        }

        DWORD I2CStop( void )

        {

        I20CONSET = I2CONSET_STO;/* Set Stop flag */

        I20CONCLR = I2CONCLR_SIC|I2CONCLR_STAC|I2CONCLR_AAC;/* Clear SI flag */// modified

        /*--- Wait for STOP detected ---*/

        while( I20CONSET & I2CONSET_STO );

        return TRUE;

        }

        void I2C_SendByte(UINT8 SData)

        {

        I20DAT=SData;

        I20CONCLR =0x28;/*清零SI,STA */

        while (!(I20CONSET&I2CONCLR_SIC));// wait interrupt flag ( waiting for SI==1)

        }

        DWORD I2C_SendNByte(UINT16 SubAddr ,UINT8 *Data,UINT8 Length)

        {

        BYTE i;

        I2CStart();

        if(I20STAT==0x08)/*已發(fā)送起始條件*/

        {

        I2C_SendByte(AT24C64NW);// Device Address

        if(I20STAT==0x18) /*已發(fā)送SLA+W,已接收ACK */

        {

        I2C_SendByte((SubAddr>>8)&(0x00FF));

        if(I20STAT==0x28)/*已發(fā)送SubAddr_H,已接收ACK */

        {

        I2C_SendByte(SubAddr&(0x00FF));

        if(I20STAT==0x28) /*已發(fā)送SubAddr_L,已接收ACK */

        {

        for(i=0;i

        {

        do{

        I2C_SendByte(Data[i]);

        }while(I20STAT!=0x28);

        }

        if(I2CStop())

        {

        DelayNS(5);//10ms

        return TRUE;

        }

        return FALSE;

        }

        return FALSE;

        }

        return FALSE;

        }

        return FALSE;

        }

        return FALSE;

        }

        DWORD I2C_ReadByte(BYTE ACK, BYTE *RcvData)

        {

        if (ACK==1)//send ACK

        {

        I20CONSET=I2CONSET_AA;

        }

        else//sendNOACK

        if(ACK==0)

        {

        I20CONCLR=I2CONCLR_AAC;

        }

        I20CONCLR=I2CONCLR_SIC|I2CONCLR_STAC;// clear SISAT

        while (!(I20CONSET&I2CONCLR_SIC));// wait interrupt flag ( waiting for SI==1)

        if(ACK==1)

        {

        if((I20STAT&0xF8)==0x50) //receive data and get ack

        {

        *RcvData=I20DAT;

        return TRUE;

        }

        else

        return FALSE ;

        }

        else

        if(ACK==0)

        {

        if((I20STAT&0xF8)==0x58) //receive data and get NoAck (the last data you want to get)

        {

        *RcvData=I20DAT;

        return TRUE;

        }

        else

        return FALSE ;

        }

        return FALSE ;

        }

        DWORD I2C_ReadNByte(UINT16 SubAddr ,UINT8 *Data,UINT8 Length)

        {

        BYTEi;

        if (!I2CStart())

        {

        return FALSE;

        }

        if(I20STAT==0x08)/*已發(fā)送起始條件*/

        {

        I2C_SendByte(AT24C64NW);// Device Address

        if(I20STAT==0x18) /*已發(fā)送SLA+W,已接收ACK */

        {

        I2C_SendByte((SubAddr>>8)&(0x00FF));

        if(I20STAT==0x28)/*已發(fā)送SubAddr_H,已接收ACK */

        {

        I2C_SendByte(SubAddr&(0x00FF));

        if(I20STAT==0x28) /*已發(fā)送SubAddr_L,已接收ACK */

        {

        if (I2CStartAgain())//發(fā)送重復(fù)起始條件切換為主接受模式

        {

        I2C_SendByte(AT24C64NR);

        if(I20STAT==0x40)/*已發(fā)送SLA+R,已接收ACK*/

        {

        for(i=0;i

        {

        if(!(I2C_ReadByte(1,&Data[i])))

        {

        return FALSE;

        }

        }

        if( !( I2C_ReadByte(0, &Data[Length-1]) ) ) //讀最后一個(gè)數(shù)據(jù)

        {

        return FALSE;

        }

        if (I2CStop())//發(fā)送停止條件

        {

        return TRUE;

        }

        return FALSE;

        }

        return FALSE;

        }

        return FALSE;

        }

        return FALSE;

        }

        return FALSE;

        }

        return FALSE;

        }

        return FALSE;

        }



        關(guān)鍵詞: LPC23xxI2C接口讀寫AT24C6

        評(píng)論


        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 海宁市| 光山县| 通道| 依安县| 枣强县| 松桃| 万盛区| 弋阳县| 澜沧| 乌兰县| 广汉市| 乐东| 新巴尔虎右旗| 阿荣旗| 黄骅市| 龙井市| 奉节县| 蓝山县| 邻水| 徐闻县| 中牟县| 新野县| 南乐县| 浦江县| 屏东市| 乐至县| 宜黄县| 延庆县| 金川县| 柏乡县| 三台县| 宝应县| 夏河县| 土默特左旗| 东辽县| 云南省| 张家川| 顺义区| 新巴尔虎左旗| 澜沧| 峨山|