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

📄 i2cint.c

📁 i2c的调适成学。ARM7 交流使用
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzou ZLG-MCU Development Co.,LTD.
**                                      graduate school
**                                 http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name:			I2CINT.c
** Last modified Date:  2004-09-16
** Last Version:		1.0
** Descriptions:		The main() function example template
**
**------------------------------------------------------------------------------------------------------
** Created by:			Chenmingji
** Created date:		2004-09-16
** Version:				1.0
** Descriptions:		The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:			Chenxibing
** Modified date:		2005-01-14
** Version:	
** Descriptions:		LPC2000硬件I2C中断方式软件包
**
********************************************************************************************************/

#include  "config.h" 

/*
 *  定义用于和I2C中断传递信息的全局变量 
 */
volatile uint8   __GuiI2CSla;											/*  I2C器件从地址				*/
volatile uint32  __GuiI2CSuba;											/*  I2C器件内部子地址			*/
volatile uint8   __GuiI2CSubaNum;										/*  I2C器件子地址字节数			*/
volatile uint8  *__GuiI2CBuf;											/*  数据缓冲区指针				*/
volatile uint32  __GuiI2CNum;											/*  要读取/写入的数据个数		*/
volatile uint8   __GuiI2CEnd;											/*  I2C总线结束标志:结束时置1	*/
volatile uint32  __GuiI2CSubaEn;										/*  子地址控制:
																			0为已处理或者不需要子地址;
																			1为读取操作
																			2为写操作					*/

/*********************************************************************************************************
** Function name:		ISendByte
** Descriptions:		向无子地址器件发送1字节数据
** input parameters:	uiSla	器件地址
**           			uiDat	要发送的数据
** output parameters:	返回值为0时表示出错,为1时表示操作正确
** Returned value:      无	
*********************************************************************************************************/
uint8 ISendByte (uint8 uiSla, uint8 uiDat)
{
	/*
	 *  参数设置
	 */
	__GuiI2CSla    = uiSla;												/*  写操作的器件地址			*/
    __GuiI2CBuf    = &uiDat;												/*  待发送的数据				*/
    __GuiI2CNum    = 1;													/*  待发送的数据个数			*/
    __GuiI2CSubaEn = 0;													/*  无子地址				*/
    __GuiI2CEnd    = 0;													/*  总线不结束					*/  
    
    I2CONCLR     = 0x2C;
    I2CONSET     = 0x60;												/*  设置为主机,并启动总线       */
    
    while (0 == __GuiI2CEnd);
    if(1 == __GuiI2CEnd)return(1);
    else return(0);  
}

/*********************************************************************************************************
** Function name:		IRcvByte
** Descriptions:		向无子地址器件读取1字节数据
** input parameters:	uiSla	器件地址
**           			uiDat	接收数据的变量指针
** output parameters:	返回值为0时表示操作出错,为1时表示操作正确
** Returned value:      无
*********************************************************************************************************/
uint8 IRcvByte (uint8 uiSla, uint8 *uiDat)
{
	/*
	 *  参数设置
	 */
	__GuiI2CSla    = uiSla + 1;											/*  读操作的器件地址			*/
    __GuiI2CBuf    = uiDat;												
    __GuiI2CNum    = 1;													/*  待发送的数据个数		    */
    __GuiI2CSubaEn = 0;													/*  无子地址    				*/
    __GuiI2CEnd    = 0;													/*  总线不结束					*/  
    
    I2CONCLR       = 0x2C;
    I2CONSET       = 0x60;												/*  设置为主机,并启动总线       */
    
    while (0 == __GuiI2CEnd);
    if(1 == __GuiI2CEnd)return(1);
    else return(0); 	
}

/*********************************************************************************************************
** Function name:		I2CReadNByte
** Descriptions:		从有子地址器件任意地址开始读取N字节数据
** input parameters:	uiSla		器件从地址
**						uiSubaType	子地址结构	1-单字节地址	2-8+X结构	2-双字节地址
**						uiSuba		器件子地址
**						*uiS		数据接收缓冲区指针
**						uiNum		读取的个数
** output parameters:	TRUE		操作成功
**						FALSE		操作失败
** Returned value:      无
*********************************************************************************************************/
uint8 I2C_ReadNByte (uint8 uiSla, uint32 uiSubaType, uint32 uiSuba, uint8 *uiS, uint32 uiNum)
{
	if(uiNum > 0)														/*  判断uiNum个数的合法性		*/
	{
		
		/*
	 	 *  参数设置
	 	 */
	 	if(uiSubaType == 1){											/*  子地址为单字节				*/
	 		__GuiI2CSla     = uiSla + 1;								/*  读操作的器件地址			*/
			__GuiI2CSuba    = uiSuba;									/*  器件子地址				    */											
			__GuiI2CSubaNum = 1;										/*  器件子地址为1字节		    */
	 	 }
	 	 
	 	if(uiSubaType == 2){											/*  子地址为两字节				*/
	 	 	__GuiI2CSla     = uiSla + 1;								/*  读操作的器件地址			*/
			__GuiI2CSuba    = uiSuba;									/*  器件子地址				    */											
			__GuiI2CSubaNum = 2;										/*  器件子地址为1字节		    */
	 	 }
	 	 
	 	if(uiSubaType == 3){											/*  子地址为8+X结构				*/
	 	 	__GuiI2CSla     = uiSla + ((uiSuba >> 7) & 0x0E) + 1;		/*  读操作的器件地址			*/
			__GuiI2CSuba    = uiSuba & 0xFF;							/*  器件子地址				    */											
			__GuiI2CSubaNum = 1;										/*  器件子地址为1字节		    */
	 	}
	 	 
	    __GuiI2CBuf    = uiS;											/*  数据接收缓冲区指针			*/
	 	__GuiI2CNum    = uiNum;											/*  要读取的数据个数			*/
	 	__GuiI2CSubaEn = 1;												/*  有子地址读      			*/
	 	__GuiI2CEnd    = 0;
	 	 
	 	/*
	 	 *  清除STA,SI,AA标志位
	 	 */
	 	I2CONCLR = (1 << 2) |					 						/*  清除AA      				*/
	 	 		   (1 << 3) |											/*  清除SI     					*/			 
	 	 		   (1 << 5) ;											/*  清除STA      				*/
	 	 			 
	 	/*
	 	 *  置位STA,启动I2C总线
	 	 */
	 	I2CONSET = (1 << 5) |					 						/*  STA     					*/
	 	 		   (1 << 6) ;											/*  I2EN    					*/
	 	 
	 	/*
	 	 *  等待I2C操作完成
	 	 */			 	
	 	while (__GuiI2CEnd == 0);
        if(__GuiI2CEnd == 1){
    		return(TRUE);	
    	} 
    	else return(FALSE);	 
	} 
	return(FALSE);	
}

/*********************************************************************************************************
** Function name:		I2CWriteNByte
** Descriptions:		向有子地址器件写入N字节数据
** input parameters:	uiSla		器件从地址
**						uiSubaType  子地址结构	1-单字节地址	3-8+X结构	2-双字节地址
**			  			uiSuba		器件内部物理地址
**			  			*uiS		将要写入的数据的指针
**			  			uiNum		将要写入的数据的个数
** output parameters:	TRUE		操作成功
**			  			FALSE		操作失败
** Returned value:      无
*********************************************************************************************************/
uint8 I2C_WriteNByte(uint8 uiSla, uint8 uiSubaType, uint32 uiSuba, uint8 *uiS, uint32 uiNum)
{
	if(uiNum > 0){														/*  如果写入的个数为0,返回错误 */
		/*
	 	 *  参数设置
	 	 */
		if(uiSubaType == 1){											/*  子地址为单字节				*/
		    __GuiI2CSla     = uiSla;									/*  写操作的器件地址			*/
			__GuiI2CSuba    = uiSuba;									/*  器件子地址				    */											
			__GuiI2CSubaNum = 1;										/*  器件子地址为1字节		    */
		}
		
		if(uiSubaType == 2){											/*  子地址为单字节				*/
		    __GuiI2CSla     = uiSla;									/*  写操作的器件地址			*/
			__GuiI2CSuba    = uiSuba;									/*  器件子地址				    */											
			__GuiI2CSubaNum = 2;										/*  器件子地址为2字节		    */
		}
		
		if(uiSubaType == 3){											/*  子地址为8+X结构				*/
	 	 	__GuiI2CSla     = uiSla + ((uiSuba >> 7) & 0x0E);			/*  写操作的器件地址			*/
			__GuiI2CSuba    = uiSuba & 0xFF;							/*  器件子地址				    */											
			__GuiI2CSubaNum = 1;										/*  器件子地址为1字节		    */
	    }
	    
	    __GuiI2CBuf    = uiS;
	    __GuiI2CNum    = uiNum;
	    __GuiI2CSubaEn = 2;
	    __GuiI2CEnd    = 0;
	    
	    /*
	 	 *  清除STA,启动I2C总线
	 	 */
	 	I2CONCLR = (1 << 2) |					 						/*  清除AA      				*/
	 	 		   (1 << 3) |											/*  清除SI     					*/			 
	 	 		   (1 << 5) ;											/*  清除STA      				*/
	 	 			 
	 	/*
	 	 *  置位STA,启动I2C总线
	 	 */
	    I2CONSET = (1 << 5) |					 						/*  STA     					*/
	 	 		   (1 << 6) ;											/*  I2EN    					*/
	 	
	 	while (__GuiI2CEnd == 0);										/*  等待I2C操作完成				*/
	 	if (__GuiI2CEnd == 1){
	 		return (TRUE);
	 	}
	 	else return (FALSE);	 	  
	}
	return (FALSE);
}


/*********************************************************************************************************
** Function name:		__irq IRQI2C
** Descriptions:		硬件I2C中断服务程序
** input parameters:	无
** output parameters:	无
** Returned value:      无 
*********************************************************************************************************/
void __irq IRQ_I2C (void)
{
	/*
	 *  读取I2C状态寄存器I2STAT
	 *  按照全局变量的设置进行操作及设置软件标志
	 *  清除中断逻辑,中断返回
	 */
	switch(I2STAT & 0xF8){
	
		/*
		 *  根据状态码进行相应的处理  
		 */
		case 0x08:														/*  已发送起始条件				*/
			
			/*
			 *  装入SLA+W或者SLA+R 
			 */ 
			if(__GuiI2CSubaEn == 1){									/*  指定子地址读操作			*/
				I2DAT = __GuiI2CSla & 0xFE;								/*  先写入地址					*/
			}
			else
			{
				I2DAT = __GuiI2CSla;									/*  否则直接发送从机地址		*/
			}
			
			/*
			 *  清零SI位
			 */ 
			I2CONCLR = (1 << 3) |										/*  清零SI						*/
			           (1 << 5) ;										/*  清零STA						*/
			break;
			
		case 0x10:														/*  已发送重复起始位			*/
			I2DAT    = __GuiI2CSla;										/*  重起总线后,重发从地址		*/
			I2CONCLR = 0x28;											/*  清零SI和STA					*/
			
			break;
			
		case 0x18:
		case 0x28:														/*  已发送I2DAT中的数据,
																		 *	已接收ACK					*/
			if (__GuiI2CSubaEn == 0){
				if (__GuiI2CNum > 0){									/*  如果还有数据需要写			*/
					I2DAT    = *__GuiI2CBuf++;							/*  写数据						*/
					I2CONCLR = 0x28;									/*  清零SI和STA					*/
					__GuiI2CNum--;										/*  字节数减一					*/
				}
				
				else{													/*  没有数据发送了				*/
					I2CONSET  = (1 << 4);								/*  STO							*/
					I2CONCLR  = 0x28;									/*  清零SI和STA					*/
					__GuiI2CEnd = 1;									/*  总线已经停止				*/
				}
			}
			
			if (__GuiI2CSubaEn == 1){									/*  若是指定地址读,重新启动总线*/
				if (__GuiI2CSubaNum == 2){								/*  如果是双字节地址			*/
					I2DAT = ((__GuiI2CSuba >> 8) & 0xFF);				/*  先发送地址高字节			*/
					I2CONCLR = 0x28;									/*  清零SI和STA					*/
					__GuiI2CSubaNum--;									/*  字节数减一					*/
					break;
				}
				
				if (__GuiI2CSubaNum == 1){								
					I2DAT = (__GuiI2CSuba & 0xFF);						/*  发送地址低字节				*/
					I2CONCLR = 0x28;									/*  清零SI和STA					*/
					__GuiI2CSubaNum--;									/*  字节数减一					*/
					break;
				}
				
				if (__GuiI2CSubaNum == 0){								
					I2CONSET     = 0x20;								/*  置位STA,总线重起			*/
					I2CONCLR     = 0x08;								/*  清零SI						*/
                    __GuiI2CSubaEn = 0;									/*  子地址已处理				*/
					break;
				}
			}
				
			if (__GuiI2CSubaEn == 2){									/*  指定地址写,发送子地址		*/
				if (__GuiI2CSubaNum > 0){
					if (__GuiI2CSubaNum == 2){							/*  如果是双字节地址			*/
						I2DAT = ((__GuiI2CSuba >> 8) & 0xFF);			/*  先发送地址高字节			*/
						I2CONCLR = 0x28;								/*  清零SI和STA					*/
						__GuiI2CSubaNum--;								/*  字节数减一					*/  
						break;
					}
					
					if (__GuiI2CSubaNum == 1){								
						I2DAT = (__GuiI2CSuba & 0xFF);					/*  发送地址低字节				*/
						I2CONCLR = 0x28;								/*  清零SI和STA					*/
						__GuiI2CSubaNum--;									/*  字节数减一					*/
						__GuiI2CSubaEn = 0;		
						break;
					}
				}
			}
			break;
		
		case 0x40:														/*  已发送SLA+R,已接收ACK		*/
		
			if (__GuiI2CNum <= 1){										/*  如果是最后一字节			*/	
				I2CONCLR = 1 << 2;										/*  下次发送非应答信号			*/
			}	
			else{																	
				I2CONSET = 1 << 2;										/*  下次发送应答信号			*/
			}
			I2CONCLR = 0x28;											/*  清零SI和STA					*/	
			break;
			
		case 0x20:														/*  已发送SLA+W,已接收非应答	*/
		case 0x30:														/*  已发送I2DAT中的数据,
																		 *  已接收非应答				*/
		case 0x38:														/*  SLA+R/W或数据字节中丢失仲裁 */
		case 0x48:														/*  已发送SLA+R,已接收非应答	*/
		I2CONCLR  = 0x28;
		__GuiI2CEnd = 0xFF;												/*  总线出错					*/ 
		break;
		
		case 0x50:														/*  已接收数据字节,已返回ACK	*/
		   *__GuiI2CBuf++ = I2DAT;
		    __GuiI2CNum--;
			if(__GuiI2CNum == 1){										/*  接收最后一个字节			*/
				I2CONCLR = 0x2C;										/*  STA、SI和AA=0				*/
			}
			else{
				I2CONSET = 0x04;										/*  AA=1						*/
				I2CONCLR = 0x28;
			}															 
			break;
			
		case 0x58:														/*  已接收数据字节,已返回非应答*/
		   *__GuiI2CBuf++ = I2DAT;										/*  读取最后一字节数据			*/
		    I2CONSET      = 0x10;										/*  结束总线					*/
		    I2CONCLR      = 0x28;
		    __GuiI2CEnd   = 1;
		    break;
		    
		default:
		break; 
	}
	VICVectAddr = 0x00;													/*  中断处理结束				*/
}




⌨️ 快捷键说明

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