最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

基于S3C2440的IIC程序

来源:动视网 责编:小OO 时间:2025-09-27 20:51:40
文档

基于S3C2440的IIC程序

//====================================================================//FileName:IIC.c//Function:S3C2440IIC-busMasterTx/RxmodeTestProgram//(Interrupt/NonInterrupt(Polling))//Program:Shin,OnPil(SOP)//Date:May21,2002//Version:0.0//History//0.0:Program
推荐度:
导读//====================================================================//FileName:IIC.c//Function:S3C2440IIC-busMasterTx/RxmodeTestProgram//(Interrupt/NonInterrupt(Polling))//Program:Shin,OnPil(SOP)//Date:May21,2002//Version:0.0//History//0.0:Program
//====================================================================

// File Name : IIC.c

// Function  : S3C2440 IIC-bus Master Tx/Rx mode Test Program

//             (Interrupt / Non Interrupt (Polling))

// Program   : Shin, On Pil (SOP)

// Date      : May 21, 2002

// Version   : 0.0

// History

// 0.0 : Programming start (March 11, 2002) -> SOP

//====================================================================

#include

#include "2440addr.h"

#include "2440lib.h"

#include "def.h"

#include "IIC.h"

static U8 _iicData[IICBUFSIZE];

static volatile int _iicDataCount;

static volatile int _iicStatus;

static volatile int _iicMode;

static int _iicPt;

//===================================================================

//  SMDK2440 IIC configuration

//  GPE15=IICSDA, GPE14=IICSCL

//  "Interrupt mode" for IIC block中断模式下的IIC操作

//=================================================================== 

//******************[ Test_Iic ]**************************************

void Test_Iic(void)

{

    unsigned int i,j,save_E,save_PE;

    static U8 data[256];

    Uart_Printf("\\nIIC Test(Interrupt) using AT24C02\\n");

    save_E   = rGPECON;                  //保护现场

    save_PE  = rGPEUP;

    rGPEUP  |= 0xc000;                  //Pull-up disable ,1_disable,0_enable

    rGPECON |= 0xa00000;                //GPE15(10):IICSDA , GPE14(10):IICSCL,GPE15,GPE14为第二功能 时钟线和数据线

    pISR_IIC = (unsigned)IicInt;        //中断声明

    rINTMSK &= ~(BIT_IIC);              //iic中断使能

rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);//(1<<7)Enable ACK,(0<<6) Prescaler IICCLK=PCLK/16,(1<<5) Enable interrupt,

                                                // (0xf)Transmit clock value Tx clock=IICCLK/(15+1)

                                                  // If PCLK 50.7MHz, IICCLK = 3.17MHz, Tx Clock = 0.198MHz

    rIICADD  = 0x10;                    //2440 slave address = [7:1]=0x10;

    rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)

rIICLC = (1<<2)|(1);                 // Filter enable, 5 clocks SDA output delay       added by lj

    

    Uart_Printf("Write test data into AT24C02\\n");

for(i=0;i<256;i++)

        Wr24C080(0xa0,(U8)i,i);//写入0~255主设备地址0~255?从设备地址0xa0?

           

for(i=0;i<256;i++)//data[]清零

        data[i] = 0;

    Uart_Printf("Read test data from AT24C02\\n");

    

for(i=0;i<256;i++)

        Rd24C080(0xa0,(U8)i,&(data[i])); //从同一个地址读入256个字节

        //Line changed 0 ~ f

for(i=0;i<16;i++)

    {

for(j=0;j<16;j++)

            Uart_Printf("%2x ",data[i*16+j]);

            Uart_Printf("\\n");//每16字节换一行

    }

    rINTMSK |= BIT_IIC; //iic操作结束,禁止iic中断   

    rGPEUP  = save_PE;    //恢复现场

    rGPECON = save_E;

}

//*************************[ Wr24C080 ]****************************

void Wr24C080(U32 slvAddr,U32 addr,U8 data)

{

    _iicMode      = WRDATA;              //写数据模式

    _iicPt        = 0;

    _iicData[0]   = (U8)addr;

    _iicData[1]   = data;

    _iicDataCount = 2;                  //中断里写两个数据(地址)

    rIICDS   = slvAddr;                 //slvAddr=0xa0

    rIICSTAT = 0xf0;                    //11MasTx,1Start,1enable rx/tx(使能中断)首先发送从设备地址,在中断函数里发送数据

      //Clearing the pending bit isn't needed because the pending bit has been cleared.

    

    while(_iicDataCount!=-1);//等待主发送模式停止,在中断函数里进行的

    _iicMode = POLLACK;//MasTx condition  has Stoped,等待ACK应答模式,有应答表示从设备已经收到

    while(1)

    {

        rIICDS     = slvAddr;            //slvAddr=0xa0

        _iicStatus = 0x100;                //IICSTAT clear?

        rIICSTAT   = 0xf0;              //MasTx,Start

        rIICCON    = 0xaf;              //Resumes IIC operation.     

        while(_iicStatus==0x100);        //Wait until IICSTAT change 

           

        if(!(_iicStatus&0x1))

            break;                      //When ACK is received

    }

    rIICSTAT = 0xd0;                    //1101_,11~MasRx,0~stop,1~RxTx enable //Stop MasTx condition 

    rIICCON  = 0xaf;                    //Resumes IIC operation. 

    Delay(1);                           //Wait until stop condtion is in effect.

    //Write is completed.

}

        

//**********************[ Rd24C080 ] ***********************************

void Rd24C080(U32 slvAddr,U32 addr,U8 *data)

{

    _iicMode      = SETRDADDR;//写地址模式

    _iicPt        = 0;

    _iicData[0]   = (U8)addr;

    _iicDataCount = 1;//写一个数据(地址)

    rIICDS   = slvAddr;                    //slvAddr=0xa0首先写入从设备地址

    rIICSTAT = 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;//读一个数据(地址)

    

    rIICDS        = slvAddr;            //slvAddr=0xa0    

    rIICSTAT      = 0xb0;               //1011,10~MasRx,1~Start,1~RxTx enable

    rIICCON       = 0xaf;               //Resumes IIC operation.   

    while(_iicDataCount!=-1);//等待主接收模式停止,在中断函数里进行的

    *data = _iicData[1];//iic发送过来的数据将被放入_iicData[1]中,然后被传递到data[]数组中

}

//-------------------------------------------------------------------------

void __irq IicInt(void)            //iic中断函数

{

    U32 iicSt,i;

    

    rSRCPND = BIT_IIC;          //Clear pending bit

    rINTPND = BIT_IIC;            //Clear pending bit

    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;                 //1001Stop 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;         //将rIICDS中的数据,即接收到的数据存入_iicData[1];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)            //_iicDataCount=2,当第三次进入中断时进入此{},停止主发送模式

            {

                rIICSTAT = 0xd0;                //1101Stop 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.可以发送两个数据,第一个发送的是_iicData[0]=addr即主设备地址,

                                                //第二个发送的是_iicData[1]=data即要发送的数据,

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++];        //只发送一个数据_iicData[0]=addr,即主设备地址

for(i=0;i<10;i++); //For setup time until rising edge of IICSCL等待时钟上升沿

            rIICCON = 0xaf;                     //Resumes IIC operation.重复iic操作

            break;

        default:

            break;      

    }

}

//===================================================================

//  SMDK2440 IIC configuration

//  GPE15=IICSDA, GPE14=IICSCL

//  "Non-Interrupt" mode for IIC block

//=================================================================== 

//*********************[ Test_Iic2 ]*********************************

void Test_Iic2(void)

{

    unsigned int i,j,save_E,save_PE;

    static U8 data[256];

    

    Uart_Printf("[ IIC Test(Polling) using KS24C080 ]\\n");

    save_E   = rGPECON;

    save_PE  = rGPEUP;

    rGPEUP  |= 0xc000;                  //Pull-up disable

    rGPECON |= 0xa00000;                //GPE15:IICSDA , GPE14:IICSCL    

      //Enable ACK, Prescaler IICCLK=PCLK/16, Enable interrupt, Transmit clock value Tx clock=IICCLK/16

rIICCON = (1<<7) | (0<<6) | (1<<5) | (0xf);

    rIICADD  = 0x10;                    //2440 slave address = [7:1]

    rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)

//rIICLC = (1<<2)|(3); // Filter enable, 15 clocks SDA output delay added by junon

    

    Uart_Printf("Write test data into KS24C080\\n");

for(i=0;i<256;i++)

        _Wr24C080(0xa0,(U8)i,255-i);

for(i=0;i<256;i++)

        data[i] = 0;

    Uart_Printf("Read test data from KS24C080\\n");

for(i=0;i<256;i++)

        _Rd24C080(0xa0,(U8)i,&(data[i])); 

for(i=0;i<16;i++)

    {

for(j=0;j<16;j++)

            Uart_Printf("%2x ",data[i*16+j]);

        Uart_Printf("\\n");

    }

    

    rGPEUP  = save_PE;

    rGPECON = save_E;

}

/**************[ _Wr24C080 ]**************************   写  *********/

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)

       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.

}

        

/************************[ _Rd24C080 ]***************** 读 *******/

void _Rd24C080(U32 slvAddr,U32 addr,U8 *data)

{

    _iicMode      = SETRDADDR;

    _iicPt        = 0;

    _iicData[0]   = (U8)addr;

    _iicDataCount = 1;

    rIICDS   = slvAddr;

    rIICSTAT = 0xf0;                    //MasTx,Start  

      //Clearing the pending bit isn't needed because the pending bit has been cleared.

    while(_iicDataCount!=-1)

        Run_IicPoll();

    _iicMode      = RDDATA;

    _iicPt        = 0;

    _iicDataCount = 1;

    rIICDS   = slvAddr;                 //从机地址

    rIICSTAT = 0xb0;                    //Master Rx,Start

    rIICCON  = 0xaf;                    //Resumes IIC operation.   

    while(_iicDataCount!=-1)

        Run_IicPoll();

    *data = _iicData[1];

}

//**********************[ 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;      

    }

}

文档

基于S3C2440的IIC程序

//====================================================================//FileName:IIC.c//Function:S3C2440IIC-busMasterTx/RxmodeTestProgram//(Interrupt/NonInterrupt(Polling))//Program:Shin,OnPil(SOP)//Date:May21,2002//Version:0.0//History//0.0:Program
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top