⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2410iic.c

📁 GPIO-步进电机控制实验 熟悉s3c2410a的GPIO基本功能和设置方法。 掌握步进电机的驱动原理。 掌握如何利用GPIO功能控制步进电机
💻 C
📖 第 1 页 / 共 2 页
字号:

#include <string.h>
#include "2410addr.h"
#include "2410lib.h"
#include "def.h"
#include "2410IIC.h"




#define ZLG7290_SLA_ADD	0x70	//the slave address of ZLG7290:ic which drivers leds.
#define LED_SLA_ADD	0x70	//another name of the slave address
#define LED_MAJOR	100	//the major device number of led


#define TIME_TURN 	0	//turn to display time
#define DATE_TURN 	1	//turn to display date

#define IICCON_PEND_INT_CLEAR	(1 << 4)
#define IICCON_PEND_INT_STATU   (1 << 4)



static U8 _iicData[IICBUFSIZE];
static volatile int _iicDataCount;
static volatile int _iicStatus;
static volatile int _iicMode;
static int _iicPt;







//buffers for 8 leds:

//..[0]: the zlg790's slave address
//..[1]: the commad buffer's address of zlg7290
//..[2]: the first command
//..[3]: the second command
//..[4]: the end symbol
signed char sec_buf_l[5]={LED_SLA_ADD,0x07,0x63,-1,-1};
signed char sec_buf_h[5]={LED_SLA_ADD,0x07,0x62,-1,-1};
signed char blank_buf_l[5]={LED_SLA_ADD,0X07,0X61,0x1f,-1};
signed char min_buf_l[5]={LED_SLA_ADD,0x07,0x60,-1,-1};
signed char min_buf_h[5]={LED_SLA_ADD,0x07,0x67,-1,-1};
signed char blank_buf_h[5]={LED_SLA_ADD,0X07,0X66,0x1f,-1};
signed char hour_buf_l[5]={LED_SLA_ADD,0x07,0x65,-1,-1};
signed char hour_buf_h[5]={LED_SLA_ADD,0x07,0x64,-1,-1};
//buffers for 8 leds:
signed char date_buf_l[5]={LED_SLA_ADD,0x07,0x63,-1,-1};
signed char date_buf_h[5]={LED_SLA_ADD,0x07,0x62,-1,-1};
signed char mon_buf_l[5]={LED_SLA_ADD,0x07,0x61,-1,-1};
signed char mon_buf_h[5]={LED_SLA_ADD,0x07,0x60,-1,-1};
signed char year_buf_0[5]={LED_SLA_ADD,0x07,0x64,2,-1};
signed char year_buf_1[5]={LED_SLA_ADD,0x07,0x65,0,-1};
signed char year_buf_2[5]={LED_SLA_ADD,0x07,0x66,-1,-1};
signed char year_buf_3[5]={LED_SLA_ADD,0x07,0x67,-1,-1};


int date_time_turn = TIME_TURN;	//turn to display time first
signed int date_s = 0;		//the seconds how long date has been displayed
signed int time_s = 0;		//the seconds how long time has been displayed


//time structure
static struct my_time{
	char second;
	char minute;
	char hour;
	char date;
	char month;
	char year;
}led_time;




/*
 * write the cpu's rtc!
 * you can change the time and date
 */

static void led_set_time(void)
{
	rRTCCON = 0X01;	//get the right to write rtc
	rBCDYEAR = 0x04;	//2004.9.26 11:49:30
	rBCDMON = 0x09;
	rBCDDATE = 0x26;
	rBCDHOUR = 0x11;
	rBCDMIN = 0x49;
	rBCDSEC = 0x30;
	rRTCCON = 0X00;	//free the right to write rtc
}



/*
 * get the date and time from rtc
 */
static void led_get_time(struct my_time *tempt)
{
	tempt->second = rBCDSEC;
	tempt->minute = rBCDMIN;
	tempt->hour   = rBCDHOUR;
	tempt->date   = rBCDDATE;
	tempt->month  = rBCDMON;
	tempt->year   = rBCDYEAR; 
}



/*
 * get the correct format of the time and date
 * see the cpu 2410's doc for more details of the RTC registers
 */
static void led_time_format(struct my_time *tempt)
{
	sec_buf_l[3] = (tempt->second & 0x0f);
	sec_buf_h[3] = (tempt->second & 0x70) >> 4;
	min_buf_l[3] = (tempt->minute & 0x0f) | 0x80;
	min_buf_h[3] = (tempt->minute & 0x70) >> 4;
	hour_buf_l[3] = (tempt->hour & 0x0f) |0x80;
	hour_buf_h[3] = (tempt->hour & 0x30) >> 4;

   	date_buf_l[3] = (tempt->date & 0x0f);
	date_buf_h[3] = (tempt->date & 0x30) >> 4;
	mon_buf_l[3] = (tempt->month & 0x0f) | 0x80;
	mon_buf_h[3] = (tempt->month & 0x10) >> 4;
	year_buf_2[3] = (tempt->year) / 10;
	year_buf_3[3]= (tempt->year) % 10 | 0x80;
}





/*
 * send command to zlg7290
 */
static int led_send_cmd(signed char *data)
{
	signed char *temp = data;

	if (*temp == -1)	//nothing to send!
		return 0;

	rIICDS = *temp;	//store the slave device address!
	rIICSTAT = 0xF0;	//START SEND
	temp++;


	while (*temp != -1) 
	{
		while (!(rIICCON & IICCON_PEND_INT_STATU));	//WAIT UNTIL TRANSFERS ENDED!
		rIICDS = *temp;		//put new command into it to be sended!
		rIICCON &= ~IICCON_PEND_INT_CLEAR; //A NEW TRANSFERS
		temp++;		
	}		

	while (!(rIICCON & IICCON_PEND_INT_STATU));
        rIICSTAT = 0xD0;//STOP IIC
        rIICCON &= ~IICCON_PEND_INT_CLEAR;//CLEAR PENDING INT
	Delay(5);	//delay needed before another transfers
	return 1;
}

















//===================================================================
//       SMDK2410 IIC configuration
//  GPE15=IICSDA, GPE14=IICSCL
//  "Interrupt mode" for IIC block
//=================================================================== 

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

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

    save_E   = rGPECON;
    save_PE  = rGPEUP;
    rGPEUP  |= 0xc000;                  //Pull-up disable
    rGPECON |= 0xa00000;                //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;                    //2410 slave address = [7:1]
    rIICSTAT = 0x10;                    //IIC bus data output enable(Rx/Tx)

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

    for(i=0;i<256;i++)
        Wr24C080(0xa0,(U8)i,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])); 

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


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

    _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 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -