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

📄 drv_i2c.c

📁 Enhanced LPC213x device drivers,tools ADS1.2
💻 C
📖 第 1 页 / 共 2 页
字号:
////////////////////////////////////////////////////////////////////////
#include "config_60_61.h"
#include "config_GD61.h"
#include "include_GD61.h"

////////////////////////////////////////////////////////////////////////
#define ONE_BYTE_SUBA		1
#define TWO_BYTE_SUBA		2
#define X_ADD_8_SUBA		3

#define I2C_EN				0x40	//I2CONSET bits define
#define I2C_STA				0x20
#define I2C_STO				0x10
#define I2C_SI				0x08
#define I2C_AA				0x04

#define I2C_W				0xFE
#define I2C_R				0x01

#define I2C_DEV_FREE		0x01
#define I2C_DEV_BUSY		0x00
#define I2C_TRANS_LIMIT		100		//100 milsecond, about 100 bytes

extern volatile uint16 mSecondTick;
///////////////////////////////////////////////////////////////////////
/* 定义用于和I2C中断传递信息的全局变量 */
volatile uint8 	I2C_dveAddr;		//I2C器件从地址
volatile uint8 	I2C_subAddrNum;		//I2C子地址字节数
volatile uint32	I2C_subAddr;		//I2C器件内部子地址

volatile uint8 	*I2C_dbuf_Pt;		//数据缓冲区指针
volatile uint8  I2C_byteNum;		//要读取/写入的数据个数
volatile uint8 	I2C_endFlag;		//I2C总线结束标志:结束总线是置1

volatile uint8 	I2C_subAddrFlag;	// 	子地址控制。
									//	0--子地址已经处理或者不需要子地址
									//	1--读取操作
									//	2--写操作
///////////////////////////////////////////////////////////////////////
void I2C_StopAct(void);
void I2C_Initialize(uint32 FrqI2C);

//uint8 I2C_SendByte(uint8 sla, uint8 dat);
//uint8 I2C_RcvByte(uint8 sla, uint8 *dat);

uint8 I2C_ReadNByte (uint8 sla, uint8 suba_type, uint32 suba, uint8*s, uint8 num);
uint8 I2C_WriteNByte(uint8 sla, uint8 suba_type, uint32 suba, uint8*s, uint8 num);

void __irq IRQ_I2C_Serving(void);

///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
void I2C_StopAct(void)
{
	IRQDisable();

	I2CONSET 	= I2C_STO;			//0x10;	/*结束总线*/
	I2CONCLR 	= I2C_STA|I2C_SI;	//0x28;
	I2C_endFlag = I2C_DEV_FREE;		//1; 

	VICVectAddr = 0x00;     		/*中断处理结束*/

	IRQEnable();					// 使能IRQ中断
}

/*
///////////////////////////////////////////////////////////////////////
** 函数名称 :I2C_Initialize()
** 函数功能 :I2C初始化
** 入口参数 :FrqI2C	I2C总线频率(最大400K)
** 出口参数 :无
///////////////////////////////////////////////////////////////////////
*/
void I2C_Initialize(uint32 FrqI2C)
{
	IRQDisable();

	if (FrqI2C > 400000) FrqI2C = 400000;

	PINSEL0  = 	(PINSEL0 & (~0xF0))|0x50; 	// 不影响其它管脚连接

	I2SCLH 	 = 	(LPC_FPCLK/FrqI2C + 1)/2;	/* 设定I2C时钟*/
	I2SCLL 	 = 	(LPC_FPCLK/FrqI2C)/2;

	I2CONCLR = 	I2C_STA|I2C_SI |I2C_AA;		//0x2C;
	I2CONSET = 	I2C_EN;		//0x40;			/* 使能主I2C*/

/* 设置I2C中断允许 */
	VICVectCntl3 = (0x20|INT_IIC0);			/* I2C通道分配到IRQ slot3*/
	VICVectAddr3 = (int32)IRQ_I2C_Serving;	/* 设置I2C中断向量*/
	VICIntEnable = 1<<INT_IIC0;				/* 使能I2C中断*/

	IRQEnable();							// 使能IRQ中断
}

/*
**********************************************************************************
** 函数名称 :I2C_ReadNByte()
** 函数功能 :从有子地址器件任意地址开始读取N字节数据
** 入口参数 :	sla			器件从地址
**				suba_type	子地址结构	1-单字节地址	2-8+X结构	2-双字节地址
**				suba		器件子地址
**				s			数据接收缓冲区指针
**				num			读取的个数
** 出口参数 :	TRUE		操作成功
**				FALSE		操作失败
**********************************************************************************
*/
//#define ONE_BYTE_SUBA		1
//#define TWO_BYTE_SUBA		2
//#define X_ADD_8_SUBA		3

uint8 I2C_ReadNByte (uint8 sla, uint8 suba_type, uint32 suba, uint8 *s, uint8 num)
{
	I2C_StopAct();	DelayMS_(1);

	if (num>0){	/* 判断num个数的合法性 *//* 参数设置 */

		if (suba_type == ONE_BYTE_SUBA){		/* 子地址为单字节 */
			I2C_dveAddr  	= sla|I2C_R;	//+ 1;	/* 读器件的从地址,R=1 	*/
			I2C_subAddr    	= suba;			/* 器件子地址 */
			I2C_subAddrNum	= 1;			/* 器件子地址为1字节 */

		}else if (suba_type == TWO_BYTE_SUBA){	/* 子地址为2字节 */
			I2C_dveAddr  	= sla|I2C_R;	// + 1;	/* 读器件的从地址,R=1 	*/
			I2C_subAddr   	= suba;			/* 器件子地址 */
			I2C_subAddrNum	= 2;			/* 器件子地址为2字节 */

		}else if (suba_type == X_ADD_8_SUBA){	/* 子地址结构为8+X*/
			I2C_dveAddr		= (sla+((suba>>7)&0x0e))|I2C_R;	//1;/* 读器件的从地址,R=1	*/
			I2C_subAddr		= suba & 0x0ff;	/* 器件子地址 */
			I2C_subAddrNum	= 1;			/* 器件子地址为8+x */
		}
		
		I2C_dbuf_Pt     = s;				/* 数据接收缓冲区指针 */
		I2C_byteNum     = num;				/* 要读取的个数 */
		
		I2C_subAddrFlag = 1;				/* 有子地址, 读操作 */
		I2C_endFlag     = I2C_DEV_BUSY;		//0;

		I2CONCLR = 	I2C_AA|I2C_SI|I2C_STA;	/* AA SI STA ,清除STA,SI,AA标志位 */
		I2CONSET = 	I2C_STA|I2C_EN;			/* STA I2CEN ,置位STA,启动I2C总线 */
		
		/* 等待I2C操作完成 */
		mSecondTick=I2C_TRANS_LIMIT;
		while((I2C_endFlag == I2C_DEV_BUSY)&&(mSecondTick>1));
		if(I2C_endFlag	   == I2C_DEV_BUSY) DB_SendString("time overflow in I2C_ReadNByte()");

		if (I2C_endFlag == I2C_DEV_FREE)	return (TRUE);
		else								return (FALSE);			
	}
	return (FALSE);
}

/*
***********************************************************************************
** 函数名称 :I2C_WriteNByte()
** 函数功能 :向有子地址器件写入N字节数据
** 入口参数 :	sla			器件从地址
**				suba_type	子地址结构	1-单字节地址	3-8+X结构	2-双字节地址
**			  	suba		器件内部物理地址
**			  	*s			将要写入的数据的指针
**			  	num			将要写入的数据的个数
** 出口参数 :	TRUE		操作成功
**			  	FALSE		操作失败
**********************************************************************************
*/
//#define ONE_BYTE_SUBA		1
//#define TWO_BYTE_SUBA		2
//#define X_ADD_8_SUBA		3

uint8 I2C_WriteNByte(uint8 sla, uint8 suba_type, uint32 suba, uint8 *s, uint8 num)
{
	I2C_StopAct();	DelayMS_(1);

	if (num>0){	/* 如果读取的个数为0,则返回错误 */	/* 设置参数 */

		if (suba_type == ONE_BYTE_SUBA){			/* 子地址为单字节 */
			I2C_dveAddr 	= sla & I2C_W;	/* 读器件的从地址	 	*/
			I2C_subAddr    	= suba;			/* 器件子地址 			*/
			I2C_subAddrNum	= 1;			/* 器件子地址为1字节 	*/
		}
		
		else if (suba_type == TWO_BYTE_SUBA){		/* 子地址为2字节 */
			I2C_dveAddr     = sla & I2C_W;	/* 读器件的从地址 		*/
			I2C_subAddr   	= suba;			/* 器件子地址 			*/
			I2C_subAddrNum	= 2;			/* 器件子地址为2字节 	*/

		}else if (suba_type == X_ADD_8_SUBA){		/* 子地址结构为8+X */
			I2C_dveAddr	    = (sla+((suba>>7)&0x0e)) & I2C_W;	/*读器件的从地址*/
			I2C_subAddr		= suba & 0x0ff;	/* 器件子地址			*/
			I2C_subAddrNum	= 1;			/* 器件子地址为8+X	 	*/
		}

		I2C_dbuf_Pt     = s;				/* 数据 				*/
		I2C_byteNum     = num;				/* 数据个数 			*/
		
		I2C_subAddrFlag = 2;				/* 有子地址,写操作 	*/
		I2C_endFlag     = I2C_DEV_BUSY;	//0;
	
		I2CONCLR = 	I2C_AA|I2C_SI|I2C_STA;	/* AA SI STA  清除STA,SI,AA标志位 */
		I2CONSET = 	I2C_STA|I2C_EN;			/* STA I2CEN, 置位STA,启动I2C总线 */
		
		/* 等待I2C操作完成 */
		mSecondTick=I2C_TRANS_LIMIT;
		while((I2C_endFlag == I2C_DEV_BUSY)&&(mSecondTick>1));
		if((I2C_endFlag	   == I2C_DEV_BUSY)) DB_SendString("time overflow in I2C_WriteNByte()");
		
		if (I2C_endFlag == I2C_DEV_FREE)	return (TRUE);
		else								return (FALSE);	
	}
	return (FALSE);
}

/*
**************************************************************************
** 函数名称 :__irq IRQ_I2C_Serving()
** 函数名次 :硬件I2C中断服务程序。 

⌨️ 快捷键说明

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