Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7723776
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: 嵌入式

2011-07-15 11:05:44

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

//  工程名称:  IIC.mcp

//  功能描述:  通过超级终端可以看到IIC传输状态及其结果

//             

//  IDE环境:   TX2440A      ADS v1.2

//  组成文件:  main.c, IIC.c IIC.h

//  硬件连接:  使用AT24C04

//  维护记录:  2009-8-26  V1.0  

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

#include "2440lib.h"

#include "2440addr.h"

#include "def.h"

#include "uart.h"

#include

 

#define WRDATA      (1)

#define POLLACK     (2)

#define RDDATA      (3)

#define SETRDADDR   (4)

#define IICBUFSIZE 0x20

 

static U8 _iicData[IICBUFSIZE];

static volatile int _iicDataCount;

static volatile int _iicStatus;

static volatile int _iicMode;

static int _iicPt;

 

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

// 函数定义区

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

void __irq IicInt(void);

void Wr24C04(U32 slvAddr,U32 addr,U8 data);   

void Rd24C04(U32 slvAddr,U32 addr,U8 *data);

 

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

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

//          (Interrupt / Non Interrupt (Polling))

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

 

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

void Test_Iic(void)

{

    unsigned int i,j,save_E,save_PE;

    static U8 data[256];

 

    Uart_Printf("[ IIC Test(Interrupt) using AT24C04 ]\n");

 

    save_E   = rGPECON;

    save_PE  = rGPEUP;

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

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

 

    pISR_IIC = (unsigned)IicInt;

    rINTMSK &= ~(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

    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)|(1);                 // Filter enable, 15 clocks SDA output delay       added by junon

   

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

 

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

        Wr24C04(0xa0,(U8)i,i);

          

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

        data[i] = 0;

 

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

   

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

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

 

        //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");

    }

    rINTMSK |= BIT_IIC;   

    rGPEUP  = save_PE;

    rGPECON = save_E;

}

 

//*************************[ Wr24C04 ]****************************

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

{

    _iicMode      = WRDATA;

    _iicPt        = 0;

    _iicData[0]   = (U8)addr;

    _iicData[1]   = data;

    _iicDataCount = 2;

   

    rIICDS   = slvAddr;                 //0xa0

    rIICSTAT = 0xf0;                    //MasTx,Start

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

   

    while(_iicDataCount!=-1);

 

    _iicMode = POLLACK;

 

    while(1)

    {

        rIICDS     = slvAddr;

        _iicStatus = 0x100;

        rIICSTAT   = 0xf0;              //MasTx,Start

        rIICCON    = 0xaf;              //Resumes IIC operation.

          

        while(_iicStatus==0x100);

          

        if(!(_iicStatus&0x1))

            break;                      //When ACK is received

    }

    rIICSTAT = 0xd0;                    //Stop MasTx condition

    rIICCON  = 0xaf;                    //Resumes IIC operation.

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

       //Write is completed.

}

       

//**********************[ Rd24C04 ] ***********************************

void Rd24C04(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);

 

    _iicMode      = RDDATA;

    _iicPt        = 0;

    _iicDataCount = 1;

   

    rIICDS        = slvAddr;

    rIICSTAT      = 0xb0;               //MasRx,Start

    rIICCON       = 0xaf;               //Resumes IIC operation.  

    while(_iicDataCount!=-1);

 

    *data = _iicData[1];

}

 

 

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

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:

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

    }

}

 

void Main(void)

{

    memcpy((unsigned char *)0x0,(unsigned char *)0x30000000,0x1000);

   

    SetSysFclk(FCLK_400M);         //设置系统时钟 400M

    ChangeClockDivider(2, 1);      //设置分频 148

    CalcBusClk();           //计算总线频

 

    Uart_Select(0);

    Uart_Init(0, 115200);   

   

    Test_Iic();

   

    while(1);

}

 

 s3c2440的IIC 读写AT24C04驱动源码 IIC.rar   

阅读(1858) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~