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

📄 i2c.c

📁 ARM s3c44box的一些程序代码
💻 C
字号:
/*********************************************************************
 *	Description:	
 *		This pgm demostrate the I2C block control and setting.	
 *		All processing is based on interrupt mothed.					
 *	History:
 *		1) Rev. 1.0: primarily version; by felix; Oct.10/2002
 *	
 *	Status:
 *		Function test only, not overall. Please contat us if bug detected.
 *		All rights reserved by Fudan JHB Tech. Co. Ltd.
 *
 *	Any quesiton or comments, please feel free to contact us.
 *********************************************************************/
#include "global_function.h"
#include "I2C.h"

extern _EscFlag;

//* global variables 
B32 _iicStatus;
B32 _iicMode;
B8  _iicData[MaxRDByte];	//only _iicData[MaxRDByte-1:0] is valid for read result, MSB is reserved
B32 _iicIndex;			//array index for _iicData[ ]


B8 IIC_demo(void)
{
    B8    SlaveAddr, Addr = 0x00;		//SlaveAddr: chip address; Addr: word address in a chip
    B8    Data = 0;
    B8    Input;
    
    printf("\n\n\r------------------ I2C demo ------------------\n\r");
    printf(": read/write I2C device on the board\n\r");
    printf(":Esc to return\n\r");
   
    Config_PortF_as_IIC();
    IIC_Init();

    SlaveAddr = (B8)IIC_ChipAddr;		//Slave address
      
    while(!_EscFlag)
    {
      printf(": Read/Write?(r/w): ");
      
      Input = Uart0_GetInput();
      Uart0_SendByte(Input);
      
      while(!(Input == 'r' || Input == 'w'))
      	{
      	   Uart0_SendByte(0x08);
          Input = Uart0_GetInput();
          Uart0_SendByte(Input);
          if(_EscFlag)
          	return;
      	}
      
      printf("\n\r: Address(0-255) = ");
      
      while((Addr = Uart0_GetInput()) != '\r')
      	       Addr += (Addr * 10); 
      

      if(_EscFlag)
         return;
          
      if(Input == 'r')
      	{
         Data = IIC_Rx(SlaveAddr, Addr);	  // read in 1 byte from [SlaveAddr+Addr] 

         printf("\n\r: Read ");
         Uart0_SendByte(Data);
         printf(" from IIC-EEPROM at ");
         Uart0_SendByte(Addr);     
         printf("\n\r");
      	}
      else
      	{
      	  printf("\n\r: DataOut(0-255) = ");
         while((Data = Uart0_GetInput()) != '\r')
      	       Data += (Data * 10); 
      	  
         IIC_Tx(SlaveAddr, Addr, Data);
         
         printf("\n\r: Write ");
         Uart0_SendByte(Data);
         printf(" to IIC-EEPROM at ");
         Uart0_SendByte(Addr);     
         printf("\n\r");
    	}
    }
    
    return(TRUE);    
}


void Config_PortF_as_IIC(void)
{
    //* port init
    rPCONF = 0xa;				//config I/O port as IIC interface
    rPUPF    = 0x3;				//pull-up disable
}

void IIC_Init(void)
{
    //* int init
    rINTCON  = 0x1;					// IRQ/vectored IRQ enable
    rINTMOD  = 0x0;					// IRQ mode
    rINTMSK  &= ~BIT_IIC;	// int enable
    //* int priority is default 
    //rINTPSLV
    //rINTPMST
    
    pISR_IIC = (int)IIC_Serv;		//map int serve function address
}


////////////////////////////////////////////////////////////////////
//  See S3C44B0X manual page 16-7 for detailed IIC Transmit operation flow  //
///////////////////////////////////////////////////////////////////
B8 IIC_Tx(B8 SlaveAddr, B8 Addr, B8 Data)
{
    //* initialize
    rIICCON = 0xe4;				// int and ACK enable, clock setting 

    //* transfer slave address
    _iicMode = WRITE;
    rIICDS = SlaveAddr;			// word address
    rIICSTAT = 0xf0;				// MasterTx; Start
    
    //Clearing the pending bit isn't needed here because the pending bit has been cleared.

    //* transfer word address and data
    _iicIndex = 0;
    _iicData[0] = Addr;
    _iicData[1] = Data;
    while(_iicIndex <= 2);			// wait until write is done: 2 bytes (Addr+Data) and a Stop condition
    								// write operation is handled in int serv func

    _iicMode = POLLACK;

    while(TRUE)
    {
    //* start a slaveaddr transfer porecss to get device status
	rIICDS 	= SlaveAddr;
	_iicStatus	= 0x100;				// this value is used to test only
	rIICSTAT	= 0xf0; 				// MasterTx,Start;	
	rIICCON	&= 0xef;				// resumes IIC operation. 
	while(_iicStatus == 0x100);		// waiting for int serv func
	
	if(!(_iicStatus&0x1))			// Slave is busy(in internal write cycle)
	    break; 					// when ACK is received, break while loop
    }
    
    rIICSTAT = 0xd0;  				//stop MasterTx condition 
    rIICCON  &= 0xef;  			 	//resumes IIC operation. 
    Delay(10);	    					//wait until stop condition is in effect.    

    return(TRUE);
}



///////////////////////////////////////////////////////////////////
//  See S3C44B0X manual page 16-7 for detailed IIC Receive operation flow  //
///////////////////////////////////////////////////////////////////
B8 IIC_Rx(B8 SlaveAddr, B8 Addr)
{
    //* initialize
    rIICCON = 0xe4;				// int and ACK enable, clock setting 

    //* set target address
    _iicMode = SETRDADDR;
    _iicIndex = 0;
    _iicData[0] = Addr;
    rIICDS = SlaveAddr;
    rIICSTAT = 0xf0;				// MasterTx,Start  
    //Clearing the pending bit isn't needed because the pending bit has been cleared.
    while(_iicIndex < 2);			// wait int serv func: send word address
    
    _iicMode = READ;			// byte read
    _iicIndex = 1;				// read n byte(s), set to n
    rIICDS    = SlaveAddr;
    rIICSTAT = 0xb0;			// MasterRx, Start to send Slave addres
    rIICCON  &= 0xef;			// resumes IIC operation: clear int pending bit

    while(_iicIndex != -1);		// waiting for int serv func

    return(_iicData[0]);			// not _iicData[1]
}
	

void __irq IIC_Serv(void)
{
    B32  iicStatus, i;

    iicStatus = rIICSTAT; 
    if (iicStatus & 0x8)	{} 		 	// when bus arbitration is failed.
    if (iicStatus & 0x4)	{} 		 	// when a slave address is matched with IICADD
    if (iicStatus & 0x2)	{} 		 	// when a slave address is 0000000b
    if (iicStatus & 0x1)	{}		 	// when ACK isn't received

    switch(_iicMode)				// global var set in main()
    {
	case POLLACK:
	    _iicStatus = iicStatus;			//return status register
	    rIICCON	&= 0xef;   			//resumes IIC operation.
	    break;

	case READ:
	    if(_iicIndex == 0)
	    {								// is last byte 
		_iicData[_iicIndex--] = rIICDS;

		rIICSTAT	= 0x90;  				//stop MasRx condition 
		rIICCON	&= 0xef;   			//resumes IIC operation.
		Delay(10);					//wait until stop condtion is in effect.
		//The pending bit will not be set after issuing stop condition.
		break;    
	    }	     
	    _iicData[_iicIndex--] = rIICDS;
	    if((_iicIndex) == 0)				//The last data has to be read with no ack
		rIICCON &= 0x6f;				//resumes IIC operation with no ACK.  
	    else 
		rIICCON &= 0xef;				//resumes IIC operation with ACK
	    break;

	case WRITE:
	    if(_iicIndex == 2)
	    {
		rIICSTAT = 0xd0;				//stop MasTx condition 
		rIICCON  &= 0xef;			//resumes IIC operation
		_iicIndex++;
		Delay(10);					//wait until stop condtion is in effect.
		//The pending bit will not be set after issuing stop condition.
		break;    
	    }
	    rIICDS = _iicData[_iicIndex++];  	//_iicData[0] has dummy.
	    for(i = 0; i < 10; i++);	    		//for setup time until rising edge of IICSCL
	    rIICCON &= 0xef;	    			//resumes IIC operation.
	    break;

	case SETRDADDR:
	    if(_iicIndex == 1)
	    {
	       _iicIndex++;
		break;  						//IIC operation is stopped because of IICCON[4] not cleared   
	    }
	    rIICDS = _iicData[_iicIndex++];
	    for(i = 0; i < 50; i++);  			//for setup time until rising edge of IICSCL
	    rIICCON &= 0xef;	    			//resumes IIC operation.
	    break;

	default:
	    break;	  
    }

    rI_ISPC=BIT_IIC;					// clear pending bit
}






⌨️ 快捷键说明

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