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

📄 i2cint.c

📁 I2C在ARM中rlm 的RTX驱动和程序
💻 C
📖 第 1 页 / 共 3 页
字号:
*/
U8 I2C_ReadNByte (U8 channel,U8 sla, U32 suba_type, U32 suba, U8 *s, U32 num,U16 timeout)
{
	switch(channel)
	{
		case 0:
			#if USE_I2C_CTRL0 == 1 
			if (num > 0)	/* 判断num个数的合法性 */
			{	/* 参数设置 */
				if (suba_type == 1)
				{	/* 子地址为单字节 */
					I2C0_sla     	= sla + 1;							/* 读器件的从地址,R=1 	*/
					I2C0_suba    	= suba;								/* 器件子地址 			*/
					I2C0_suba_num	= 1;								/* 器件子地址为1字节 	*/
				}
				if (suba_type == 2)
				{	/* 子地址为2字节 */
					I2C0_sla     	= sla + 1;							/* 读器件的从地址,R=1 	*/
					I2C0_suba   	= suba;								/* 器件子地址 			*/
					I2C0_suba_num	= 2;								/* 器件子地址为2字节 	*/
				}
				if (suba_type == 3)
				{	/* 子地址结构为8+X*/
					I2C0_sla		= sla + ((suba >> 7 )& 0x0e) + 1;	/* 读器件的从地址,R=1	*/
					I2C0_suba		= suba & 0x0ff;						/* 器件子地址	 		*/
					I2C0_suba_num	= 1;								/* 器件子地址为8+x	 	*/
				}
				I2C0_buf     = s;										/* 数据接收缓冲区指针 	*/
				I2C0_num     = num;										/* 要读取的个数 		*/
				I2C0_suba_en = 1;										/* 有子地址读 			*/
				while(os_sem_wait (wait_end0_sem, 0) == OS_R_OK); 	//清令牌数
				
				/* 清除STA,SI,AA标志位 */
				I20CONCLR = (1 << 2)|	/* AA 		*/
							(1 << 3)|	/* SI 		*/
							(1 << 5);	/* STA 		*/
				
				/* 置位STA,启动I2C总线 */
				I20CONSET = (1 << 5)|	/* STA 		*/
							(1 << 6);	/* I2CEN 	*/
				
				/* 等待I2C操作完成 */
				if(os_sem_wait (wait_end0_sem, timeout) != OS_R_TMO)return __TRUE;
			}
			#endif
			break;
		case 1:
			#if USE_I2C_CTRL1 == 1 
			if (num > 0)	/* 判断num个数的合法性 */
			{	/* 参数设置 */
				if (suba_type == 1)
				{	/* 子地址为单字节 */
					I2C1_sla     	= sla + 1;							/* 读器件的从地址,R=1 	*/
					I2C1_suba    	= suba;								/* 器件子地址 			*/
					I2C1_suba_num	= 1;								/* 器件子地址为1字节 	*/
				}
				if (suba_type == 2)
				{	/* 子地址为2字节 */
					I2C1_sla     	= sla + 1;							/* 读器件的从地址,R=1 	*/
					I2C1_suba   	= suba;								/* 器件子地址 			*/
					I2C1_suba_num	= 2;								/* 器件子地址为2字节 	*/
				}
				if (suba_type == 3)
				{	/* 子地址结构为8+X*/
					I2C1_sla		= sla + ((suba >> 7 )& 0x0e) + 1;	/* 读器件的从地址,R=1	*/
					I2C1_suba		= suba & 0x0ff;						/* 器件子地址	 		*/
					I2C1_suba_num	= 1;								/* 器件子地址为8+x	 	*/
				}
				I2C1_buf     = s;										/* 数据接收缓冲区指针 	*/
				I2C1_num     = num;										/* 要读取的个数 		*/
				I2C1_suba_en = 1;										/* 有子地址读 			*/
				while(os_sem_wait (wait_end1_sem, 0) == OS_R_OK); 	//清令牌数
				
				/* 清除STA,SI,AA标志位 */
				I21CONCLR = (1 << 2)|	/* AA 		*/
							(1 << 3)|	/* SI 		*/
							(1 << 5);	/* STA 		*/
				
				/* 置位STA,启动I2C总线 */
				I21CONSET = (1 << 5)|	/* STA 		*/
							(1 << 6);	/* I2CEN 	*/
				
				/* 等待I2C操作完成 */
				if(os_sem_wait (wait_end1_sem, timeout) != OS_R_TMO)return __TRUE;
			}
			#endif
			break;
		case 2:
			#if USE_I2C_CTRL2 == 1 
			if (num > 0)	/* 判断num个数的合法性 */
			{	/* 参数设置 */
				if (suba_type == 1)
				{	/* 子地址为单字节 */
					I2C2_sla     	= sla + 1;							/* 读器件的从地址,R=1 	*/
					I2C2_suba    	= suba;								/* 器件子地址 			*/
					I2C2_suba_num	= 1;								/* 器件子地址为1字节 	*/
				}
				if (suba_type == 2)
				{	/* 子地址为2字节 */
					I2C2_sla     	= sla + 1;							/* 读器件的从地址,R=1 	*/
					I2C2_suba   	= suba;								/* 器件子地址 			*/
					I2C2_suba_num	= 2;								/* 器件子地址为2字节 	*/
				}
				if (suba_type == 3)
				{	/* 子地址结构为8+X*/
					I2C2_sla		= sla + ((suba >> 7 )& 0x0e) + 1;	/* 读器件的从地址,R=1	*/
					I2C2_suba		= suba & 0x0ff;						/* 器件子地址	 		*/
					I2C2_suba_num	= 1;								/* 器件子地址为8+x	 	*/
				}
				I2C2_buf     = s;										/* 数据接收缓冲区指针 	*/
				I2C2_num     = num;										/* 要读取的个数 		*/
				I2C2_suba_en = 1;										/* 有子地址读 			*/
				while(os_sem_wait (wait_end2_sem, 0) == OS_R_OK); 	//清令牌数
				
				/* 清除STA,SI,AA标志位 */
				I22CONCLR = (1 << 2)|	/* AA 		*/
							(1 << 3)|	/* SI 		*/
							(1 << 5);	/* STA 		*/
				
				/* 置位STA,启动I2C总线 */
				I22CONSET = (1 << 5)|	/* STA 		*/
							(1 << 6);	/* I2CEN 	*/
				
				/* 等待I2C操作完成 */
				if(os_sem_wait (wait_end2_sem, timeout) != OS_R_TMO)return __TRUE;
			}
			#endif
			break;
	}
	return __FALSE;
}

/*
*********************************************************************************************************
** 函数名称 :I2C_WriteNByte
** 函数功能 :向有子地址器件写入N字节数据
** 入口参数 :	channel 	通道 : 0--I2C0  1--I2C1  2--I2C2
**				sla			器件从地址
**				suba_type	子地址结构	1-单字节地址	3-8+X结构	2-双字节地址
**			  	suba		器件内部物理地址
**			  	*s			将要写入的数据的指针
**			  	num			将要写入的数据的个数
**				timeout		等待时间(以系统时间衡量)
** 出口参数 :	TRUE		操作成功
**			  	FALSE		操作失败
*********************************************************************************************************
*/
U8 I2C_WriteNByte(U8 channel, U8 sla, U8 suba_type, U32 suba, U8 *s, U32 num, U16 timeout)
{
	switch(channel)
	{
		case 0:
			#if USE_I2C_CTRL0 == 1
			if (num > 0)/* 如果读取的个数为0,则返回错误 */
			{	/* 设置参数 */	
				if (suba_type == 1)
				{	/* 子地址为单字节 */
					I2C0_sla     	= sla;								/* 读器件的从地址	 	*/
					I2C0_suba    	= suba;								/* 器件子地址 			*/
					I2C0_suba_num	= 1;								/* 器件子地址为1字节 	*/
				}
				if (suba_type == 2)
				{	/* 子地址为2字节 */
					I2C0_sla     	= sla;								/* 读器件的从地址 		*/
					I2C0_suba   	= suba;								/* 器件子地址 			*/
					I2C0_suba_num	= 2;								/* 器件子地址为2字节 	*/
				}
				if (suba_type == 3)
				{	/* 子地址结构为8+X */
					I2C0_sla		= sla + ((suba >> 7 )& 0x0e);		/* 读器件的从地址		*/
					I2C0_suba		= suba & 0x0ff;						/* 器件子地址			*/
					I2C0_suba_num	= 1;								/* 器件子地址为8+X	 	*/
				}
				I2C0_buf     = s;										/* 数据 				*/
				I2C0_num     = num;										/* 数据个数 			*/
				I2C0_suba_en = 2;										/* 有子地址,写操作 	*/
				while(os_sem_wait (wait_end0_sem, 0) == OS_R_OK); 	//清令牌数
				
				/* 清除STA,SI,AA标志位 */
				I20CONCLR = 	(1 << 2)|	/* AA 	*/
								(1 << 3)|	/* SI 	*/
								(1 << 5);	/* STA 	*/
				
				/* 置位STA,启动I2C总线 */
				I20CONSET = 	(1 << 5)|	/* STA 	*/
								(1 << 6);	/* I2CEN*/
				
				/* 等待I2C操作完成 */
		        if(os_sem_wait (wait_end0_sem, timeout) != OS_R_TMO)return __TRUE;
			}				
			#endif
			break;
		case 1:
			#if USE_I2C_CTRL1 == 1
			if (num > 0)/* 如果读取的个数为0,则返回错误 */
			{	/* 设置参数 */	
				if (suba_type == 1)
				{	/* 子地址为单字节 */
					I2C1_sla     	= sla;								/* 读器件的从地址	 	*/
					I2C1_suba    	= suba;								/* 器件子地址 			*/
					I2C1_suba_num	= 1;								/* 器件子地址为1字节 	*/
				}
				if (suba_type == 2)
				{	/* 子地址为2字节 */
					I2C1_sla     	= sla;								/* 读器件的从地址 		*/
					I2C1_suba   	= suba;								/* 器件子地址 			*/
					I2C1_suba_num	= 2;								/* 器件子地址为2字节 	*/
				}
				if (suba_type == 3)
				{	/* 子地址结构为8+X */
					I2C1_sla		= sla + ((suba >> 7 )& 0x0e);		/* 读器件的从地址		*/
					I2C1_suba		= suba & 0x0ff;						/* 器件子地址			*/
					I2C1_suba_num	= 1;								/* 器件子地址为8+X	 	*/
				}
				I2C1_buf     = s;										/* 数据 				*/
				I2C1_num     = num;										/* 数据个数 			*/
				I2C1_suba_en = 2;										/* 有子地址,写操作 	*/
				while(os_sem_wait (wait_end1_sem, 0) == OS_R_OK); 	//清令牌数
				
				/* 清除STA,SI,AA标志位 */
				I21CONCLR = 	(1 << 2)|	/* AA 	*/
								(1 << 3)|	/* SI 	*/
								(1 << 5);	/* STA 	*/
				
				/* 置位STA,启动I2C总线 */
				I21CONSET = 	(1 << 5)|	/* STA 	*/
								(1 << 6);	/* I2CEN*/
				
				/* 等待I2C操作完成 */
		        if(os_sem_wait (wait_end1_sem, timeout) != OS_R_TMO)return __TRUE;
			}				
			#endif
			break;
		case 2:
			#if USE_I2C_CTRL2 == 1
			if (num > 0)/* 如果读取的个数为0,则返回错误 */
			{	/* 设置参数 */	
				if (suba_type == 1)
				{	/* 子地址为单字节 */
					I2C2_sla     	= sla;								/* 读器件的从地址	 	*/
					I2C2_suba    	= suba;								/* 器件子地址 			*/
					I2C2_suba_num	= 1;								/* 器件子地址为1字节 	*/
				}
				if (suba_type == 2)
				{	/* 子地址为2字节 */
					I2C2_sla     	= sla;								/* 读器件的从地址 		*/
					I2C2_suba   	= suba;								/* 器件子地址 			*/
					I2C2_suba_num	= 2;								/* 器件子地址为2字节 	*/
				}
				if (suba_type == 3)
				{	/* 子地址结构为8+X */
					I2C2_sla		= sla + ((suba >> 7 )& 0x0e);		/* 读器件的从地址		*/
					I2C2_suba		= suba & 0x0ff;						/* 器件子地址			*/
					I2C2_suba_num	= 1;								/* 器件子地址为8+X	 	*/
				}
				I2C2_buf     = s;										/* 数据 				*/
				I2C2_num     = num;										/* 数据个数 			*/
				I2C2_suba_en = 2;										/* 有子地址,写操作 	*/
				while(os_sem_wait (wait_end2_sem, 0) == OS_R_OK); 	//清令牌数
				
				/* 清除STA,SI,AA标志位 */
				I22CONCLR = 	(1 << 2)|	/* AA 	*/
								(1 << 3)|	/* SI 	*/
								(1 << 5);	/* STA 	*/
				
				/* 置位STA,启动I2C总线 */
				I22CONSET = 	(1 << 5)|	/* STA 	*/
								(1 << 6);	/* I2CEN*/
				
				/* 等待I2C操作完成 */
		        if(os_sem_wait (wait_end2_sem, timeout) != OS_R_TMO)return __TRUE;
			}				
			#endif
			break;
	}
	return __FALSE;
}

/*
*********************************************************************************************************
** 函数名称 :__irq IRQ_I2C
** 函数名次 :硬件I2C中断服务程序。 
** 入口参数 :无
** 出口参数 :无
** 说    明 :注意处理子地址为2字节的情况。 
*********************************************************************************************************
*/
void __irq IRQ_I2C(void)
{	
	#if USE_I2C_CTRL0 == 1
	/* 读取I2C状态寄存器I2DAT */
	/* 按照全局变量的设置进行操作及设置软件标志 */
	/* 清除中断逻辑,中断返回 */
	if(I20CONSET & 1 << 3)
	{
		switch (I20STAT & 0xF8)
		{	/* 根据状态码进行相应的处理 */
			case 0x08:	/* 已发送起始条件 */				/* 主发送和主接收都有 		*/
				/* 装入SLA+W或者SLA+R */
			 	if(I2C0_suba_en == 1)/* SLA+R */			/* 指定子地址读 			*/
			 	{	I20DAT = I2C0_sla & 0xFE; 				/* 先写入地址 				*/
			 	}
	            else	/* SLA+W */
	            {  	I20DAT = I2C0_sla;        				/* 否则直接发送从机地址 	*/
	            }
	            /* 清零SI位 */
	            I20CONCLR =	(1 << 3)|						/* SI 						*/
	            			(1 << 5);						/* STA 						*/
	            break;
	            
	       	case 0x10:	/*已发送重复起始条件 */ 			/* 主发送和主接收都有 		*/
	       		/* 装入SLA+W或者SLA+R */
	       		I20DAT = I2C0_sla;							/* 重起总线后,重发从地址 	*/
	       		I20CONCLR = 0x28;							/* 清零SI,STA */
	       		break;
	
			case 0x18:
	       	case 0x28:	/* 已发送I2DAT中的数据,已接收ACK */
	       		if (I2C0_suba_en == 0)
	       		{
		       		if (I2C0_num > 0)
		       		{	I20DAT = *I2C0_buf++;
		       			I20CONCLR = 0x28;					/* 清零SI,STA 				*/
		       			I2C0_num--;
		       		}
		       		else	/* 没有数据发送了 */
		       		{		/* 停止总线 */
		       		  	I20CONSET = (1 << 4);				/* STO 						*/
		       			I20CONCLR = 0x28;					/* 清零SI,STA 				*/
		       		  	isr_sem_send (wait_end0_sem);		/* 总线已经停止 			*/
		       		}
	       		}
	            if(I2C0_suba_en == 1)	/* 若是指定地址读,则重新启动总线 				*/
	            { 

⌨️ 快捷键说明

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