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

📄 iic0.c

📁 Philips LPC2000系列通过I2C读写EEPROM的程序, 没有读写长度的限制了. 关键词: ARM7, I2C, EEPROM
💻 C
字号:
/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$  Copyright (c)  $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$												肖遥电子(广州)研发中心
$										Shawyoo Electronics (GuangZhou) R&D Center
$                       	http://www.shawyoo.com		 Email: autoele@qq.com
$								 QQ群:9069471/9069433/9524253		All rights reserved.	  
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$  Copyright (c)  $$$$$$$$$$$$$$$$$$$$$$$$$$$ */
/*  
                                      文件描述
	文件名: 	  IIC0.c
	功能描述: IIC0底层驱动程序
	编译环境: Keil for ARM + ARTX
	目标CPU:   LPC2000
	作者:	  肖建辉
	创建时间: 
	建议编辑环境:UltraEdit 11.00a+  制表符宽度为三个字符,程序可读性更好。
					  Keil中可用配置工具
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
*/					  
#include		"RTOS.h"

#define		IIC0_GLOBALS	1

#include		"IIC0.h"


/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
	函数名称:IIC_Read
   功能描述:按指定的从机地址的当前存储地址和长度读取数据
   入口参数:从机地址,任务命令,读取的长度,接收缓冲
   出口参数:无
   全局变量: 无
   创建时间:
   修改时间:
*/ 	
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
uchar        IIC_Read(uchar SlaveAddr,uchar Comm,uint16 Length,uchar *pBuffer)
{
	NOP();	NOP();
	if(IIC.Busy)
		return ERROR;
	IIC.Busy = TRUE;
	IIC.SlaverAddress = SlaveAddr;
	IIC.Command = Comm;
	IIC.RLen = Length;	
	IIC.ReadWrite = TW_READ;
	IIC.RW_Type = IIC_READ_COMM;
	IIC.pReadBuffer = pBuffer;
	TW_Start();		
	return OK;
}	// End of <IIC_Read> function




/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
	函数名称:IIC_Write
   功能描述:写数据到从机
   入口参数:从机地址,任务命令,长度,写入的数据区指针
   出口参数:
   全局变量: 
   创建时间:
   修改时间:
*/ 	
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
uchar        IIC_Write(uchar SlaveAddr,uchar Comm,uint16 Length,uchar *pBuffer)
{
	NOP();	NOP();
	if(IIC.Busy)
		return ERROR;
	IIC.Busy = TRUE;
	IIC.SlaverAddress = SlaveAddr;
	IIC.Command = Comm;
	IIC.WLen = Length;	
	IIC.ReadWrite = TW_WRITE;	
	IIC.RW_Type = IIC_WRITE_COMM;
	IIC.pWriteBuffer = pBuffer;
	TW_Start();	
	return OK;
	
}	// End of <IIC_Write> function



/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
	函数名称:IIC_WriteRead
   功能描述:按指定的从机地址的随机存储地址读取数据
   入口参数:器件地址,任务命令,写长度和写数据缓冲指针,读长度和数据缓冲指针
   出口参数:无
   全局变量: 
   创建时间:
   修改时间:
*/ 	
void			Delay_mS(unsigned char  c);
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
uchar       IIC_WriteRead(uchar Addr,uchar Comm,uint16 WLen,uchar *pW,uint16 RLen,uchar *pR)
{		  
	NOP();	NOP();
	if(IIC.Busy)
		return ERROR;
	IIC.Busy = TRUE;		
	IIC.SlaverAddress = Addr;
	IIC.Command = Comm;
	IIC.WLen = WLen;						// 写长度
	IIC.ReadWrite = TW_WRITE;
	IIC.RW_Type = IIC_RW_COMM;	
	IIC.pWriteBuffer = pW;				// 写缓冲
	////////////////////////////////////////	
	IIC.RLen = RLen;						// 读长度
	IIC.pReadBuffer  = pR;	  			// 读缓冲
	TW_Start();								// 启动IIC
	return OK;
}	// End of <IIC_WriteRead> function

/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
	函数名称:ReadEEPROM
   功能描述:读EEPROM
   入口参数:器件地址,存储器地址,读长度,读取存储指针
   出口参数:无
   全局变量: 
   创建时间:
   修改时间:
*/ 
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
void			ReadEEPROM(uchar DAddr,uint16 RAddr,uint16 RLen,uchar *pData)
{
	uchar		sAddr[2];
	NOP();	NOP();
	sAddr[0] = RAddr>>8;
	sAddr[1] = RAddr;
	while(IIC_WriteRead(DAddr,0,2,sAddr,RLen,pData));
	os_dly_wait(1+(RLen/(I2C_FREQUENCY/1000)));			// 以适应读数据时延时
	NOP();	NOP();
} // End of <ReadEEPROM> function



/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
	函数名称:EEPROM_Write
   功能描述:写EEPROM
   入口参数:器件地址,页长度,写存储地址,写长度,待写数据指针
   出口参数:输入成功与否(只判断输入EEPROM,不判断是否写成功),返回0表示成功
   全局变量: 
   创建时间:
   修改时间:
*/ 
#include		<string.h>
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
uchar			WriteEEPROM(uchar  DAddr,uchar PageLen,uint16 WAddr,
                        uint16 WLen,uchar *pData)
{
	uchar		PageBuffer[68];
	uchar		owLen;		// One time Write Len
	NOP();	NOP();
	if(PageLen%8)		return ERROR;		// 页长度必须为8的位数	
	////////////////////////////////////// 写首址
	PageBuffer[0] = WAddr>>8;
	PageBuffer[1] = WAddr;
	if((WLen+(WAddr%PageLen))<=PageLen)
	{
		memmove(&PageBuffer[2],pData,WLen);
		IIC_Write(DAddr,0,(WLen+2),PageBuffer);
		os_dly_wait(1);
	}
	else
	{
		if(WAddr%PageLen)									// 不是从整页地址开始写
		{
			owLen = PageLen-WAddr%PageLen;			// 第一轮写的长度
			memmove(&PageBuffer[2],pData,owLen);	// 第一轮写的数据
			while(IIC_Write(DAddr,0,(owLen+2),PageBuffer));	// 输入EEPROM
			os_dly_wait(1);
			WAddr += owLen;				// 下一页地址
			pData += owLen;
			WLen -= owLen;	
		}
		/////////////////////////////////////////////////////////////
		while(WLen)
		{
			PageBuffer[0] = WAddr>>8;
			PageBuffer[1] = WAddr;							// 写地址
			if(WLen>=PageLen)
				owLen = PageLen;
			else
				owLen = WLen;
			memmove(&PageBuffer[2],pData,owLen);		// 取数据到缓冲
			while(IIC_Write(DAddr,0,(owLen+2),PageBuffer));		// 输入EEPROM
			os_dly_wait(1);
			WAddr += owLen;
			pData += owLen;
			WLen  -= owLen;
		}		
	}
	return OK;
}	// End of <WriteEEPROM> function


/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
	函数名称:I2C0_INT
   功能描述:IIC0中断服务程序
   入口参数:无
   出口参数:无
   全局变量: 
   创建时间:
   修改时间:
*/ 
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
void			I2C0_INT(void)   __irq      // IIC0 interrupt function
{
	uchar		s;
	NOP();	NOP();
	s = IIC.Status = I20STAT;
	NOP();	NOP();
	switch(s)
	{			
	   /// &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
		/// Start or repeat Start bit has been Transmitted
		case TW_MS_START:			// Start bit OK;
		case TW_MS_REP_START: 	// Repeat Start bit OK				
			I20DAT = (IIC.SlaverAddress|IIC.ReadWrite);
			break;			
		///&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
		// Master Transmitter Mode ///////////////////////////////////////////////				
		case TW_MT_SLA_ACK:		//	SLA+W has been transmitted; ACK has been received						
			I20DAT = *IIC.pWriteBuffer++;			
			break;
		case TW_MT_DATA_ACK:		// Data byte in I2DAT has been transmitted; 
										// ACK has been received			
			IIC.WLen--;
			if(IIC.WLen)
				I20DAT = *IIC.pWriteBuffer++;			
			else
			{
				if(IIC.RW_Type==IIC_RW_COMM)
				{
					IIC.ReadWrite = TW_READ;
					IIC.RW_Type = IIC_READ_COMM;
					I20CONCLR = (TW_INT_FLAG);    // 清除IIC中断标志
					VICVectAddr = 0;					// 清除总中断标志
					TW_Start();							// 再次启动IIC
					return;
				}
				else			// 单写完成
				{
					UserEvtFlag.IIC = IIC_WRITE_OK_EVT_FLAG;
					TW_Stop();        //  结束总线 
					IIC.Busy = FALSE;
				}
				//isr_evt_set(IIC_WRITE_EVT_OK,tidGetSpeedValue);
			}
			break;
		///&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
		// Master Receive Mode  //////////////////////////////////////////////////
		case TW_MR_SLA_ACK:		//	SLA+R has been transmitted; ACK has been received			
			if(IIC.RLen>1)
				TW_Ack();       	// 下次发送应答信号
			else
				TW_NoAck();      	// 下次发送非应答信号				
			break;		
		case TW_MR_DATA_ACK:		// Data byte has been received,ACK has been returned
			*IIC.pReadBuffer++ = I20DAT;						
			IIC.RLen--;
			if(IIC.RLen==1)			
				TW_NoAck();      	// 下次发送非应答信号
			break;		
		case TW_MR_DATA_NACK:	// Data byte has been received,NOT ACK has been returned
			*IIC.pReadBuffer++ = I20DAT;
			/////////////////////////////////////////////////////////
			if(IIC.Command==IIC_GET_GPS_COMMAND)					 	// GPS 任务操作IIC完成
			{
				UserEvtFlag.GPS = GPS_REC_OK_EVT_FLAG;
				isr_evt_set(GPS_REC_OK_EVT_FLAG,TaskID.GPS);
			}
			else if(IIC.Command==IIC_GET_T485_COMMAND)			  	// 读485数据之任务操作IIC完成
			{
				UserEvtFlag.MainTask = MAIN_TASK_EVT_FLAG;
				isr_evt_set(MAIN_TASK_EVT_FLAG,TaskID.MainTask);
			}
			else if(IIC.Command==IIC_EEPROM_UART0)					  // 串口0任务中操作IIC完成
			{
				UserEvtFlag.UART0 = IIC_RW_OK_EVT_FLAG;
				isr_evt_set(IIC_RW_OK_EVT_FLAG,TaskID.UART0);
			}
			else if(IIC.Command==IIC_EEPROM_GSM_GPRS)					// GSM/GPRS 任务操作IIC完成
			{
				UserEvtFlag.GSM_GPRS = IIC_RW_OK_EVT_FLAG;
				isr_evt_set(IIC_RW_OK_EVT_FLAG,TaskID.GSM_GPRS);
			}	
			else if(IIC.Command==IIC_INIT_CHECK_COMM)					// 系统初始化任务操作IIC完成
			{
				UserEvtFlag.MainTask = IIC_INIT_CHECK_EVT_FLAG;
				isr_evt_set(IIC_INIT_CHECK_EVT_FLAG,TaskID.MainTask);
			}
			////////////////////////////////////////////////////////
			NOP();
			TW_Stop();           //  结束总线 			
			IIC.Busy = FALSE;
			break;
		///&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
		// Master 异常处理  //////////////////////////////////////////////////
		case TW_MR_SLA_NACK:		// 发送了地址没收到应答
		case TW_MT_SLA_NACK:		// 发送了地址没收到应答
		case TW_MT_DATA_NACK:	// 发送了数据没收到应答
		case TW_MT_ARB_LOST:		// 丢失仲裁
		default: 
			TW_Stop();			
			IIC.Busy = FALSE;
			break;		
	}
	I20CONCLR = (TW_INT_FLAG);    // 清除中断标志
	NOP();	NOP();
	VICVectAddr = 0;
}	// End of <I2C0_INT> function




/* $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
	函数名称:I2cInit
   功能描述:I2c0初始化函数
   入口参数:无
   出口参数:无
   全局变量: 
   创建时间:
   修改时间:
*/ 
// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 以上原形声明的函数供本函数调用
void		I2C0_Init(void)
{
	I20CONCLR = 0x6C;                             	// 清除控制寄存器 
   VICIntEnClr = (1<<IIC0_INT_VECT);             	// 禁止能I2c中断    	   
   PINSEL0 = (PINSEL0 & 0xffffff0f) | 0x50;      	// 选择管脚为I2c 	
   I20SCLH = (Fpclk / I2C_FREQUENCY + 1) / 2;    	// 设置高电平时间 
   I20SCLL = (Fpclk / I2C_FREQUENCY) / 2;        	// 设置低电平时间               
   I20CONSET = 1<<TW_ENABLE;       	 					// Master model
   /////////////////////////////////////////////
   VICVectAddr6  = (uint32)I2C0_INT;
   VICVectCntl6  = (IRQ_ENABLE|IIC0_INT_VECT);
   VICIntEnable  |= (1<<IIC0_INT_VECT);				//    
	IIC.Busy = IIC.WLen = IIC.RLen = IIC.RW_Type = 0;
	IIC.Command = IIC.SlaverAddress = 0;
} //End of <I2C0_Init> Function




/*
 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$  End of File $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
 */

⌨️ 快捷键说明

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