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

📄 i2c.c

📁 周立功 《μCOS-II微小内核分析与程序设计-基于LPC2300》配套例程源码
💻 C
📖 第 1 页 / 共 3 页
字号:
		}
	}
}


/*********************************************************************************************************
** Function name:           hostRecvModeEntry
** Descriptions:            进入主接收模式,改函数被__i2cISR调用
** Input parameters:        Parm--I2C设备描述符结构体指针
** Output parameters:       NONE
** Returned value:          NONE
*********************************************************************************************************/
static void __hostRecvModeEntry (__PI2C_INFO Parm)
{
	            uint32				uiOffBase;
	volatile 	uint8 	           *pucAddrBase;
	
	pucAddrBase	= Parm->pucAddrBase;
	uiOffBase   = Parm->uiOffBase;
	
	if(Parm->usDataNum <= 1) {
		pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x2c;                   /*  接收字节少于等于1个         */
		                                                                /*  在收到下个字节时返回非ACK   */
		                                                            
	} else {
		pucAddrBase[__B_IIC_SET << uiOffBase] = 0x04;	                /*  当接收字节多于1个时,置位AA  */
		pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x28;                   /*  在收到下个字节时返回ACK     */
	}
}

/*********************************************************************************************************
** Function name:           ISR_I2C
** Descriptions:            中断服务函数底层调用,该中断服务函数没有完成从机模式
** Input parameters:        Parm--I2C设备描述符结构体指针
** Output parameters:       NONE
** Returned value:          NONE
*********************************************************************************************************/
static void __i2cISR (__PI2C_INFO Parm)
{
	            uint8				ucSta;
	            uint32				uiOffBase;
	volatile 	uint8 	           *pucAddrBase;
	
	pucAddrBase	= Parm->pucAddrBase;
	uiOffBase   = Parm->uiOffBase;
	
	ucSta = pucAddrBase[__B_IIC_STAT << uiOffBase];                     /*  获取I2C状态码               */
	switch(ucSta & 0xF8) {
	
    case __SEND_START:                                                  /*  已发送起始条件,共用写函数   */
	case __SEND_RESTART:                                                /*  重新启动总线后,发送从机地址*/
        __AddrWrite( Parm );                                            /*  写入器件地址                */
		break;
		
	case __SEND_SLA_W_ACK:												/*  已发送SLA+W并已经接收应答    */
	case __SEND_DATA_ACK:                                               /*  发送数据,已接收应答         */
	                                                                    /*  这两种情况都使用下面函数     */
        __subAddrWrite( Parm );                                         /*  I2C写数据和地址在一起        */
		break;
		
	case __SEND_SLA_W_NOACK:                                            /*  发送SLA_W,收到非应答         */
	case __SEND_DATA_NOACK:                                             /*  发送数据,收到非应答         */
	case __LOSS_BUS:                                                    /*  丢失仲裁                     */
	case __SEND_SLA_R_NOACK:                                            /*  发送SLA+R 接收非应答         */
	                                                                    /*  以上四中情况都要结束总线     */
	    __endBus( Parm );                                               /*  结束总线                     */
		break;
		
	case __SEND_SLA_R_ACK:                                              /*  发送SLA+R,收到ACK            */
		__hostRecvModeEntry( Parm );                                    /*  进入主接收模式               */
		break;
		
	case __RECV_DATA_ACK:                                               /*  接收了数据,返回应答位       */
	case __RECV_DATA_NOACK:                                             /*  接收完数据字节,返回非应答位  */
	                                                                    /*  以上两种情况,都采用读函数   */
		__dateRead( Parm );
		break;
		
	default:                                                            /*  其他状态                     */
        __endBus( Parm );                                               /*  结束总线                     */
		break;
	}
}

/*********************************************************************************************************
** Function name:           I2C0IRQ
** Descriptions:            库函数默认的中断服务函数,进行I2C中断处理,该函数挂接了钩子函数可处理用户任务
** Input parameters:        NONE
** Output parameters:       NONE
** Returned value:          NONE
*********************************************************************************************************/
void i2c0IRQ ( void )
{
    __OS_ENTER_CIRCT();
	__i2cISR(__GpiinfoDateTab[0]);
	i2c0Hook();
	VICVectAddr = 0x00;                                                 /*  清除VIC中断                 */
    __OS_EXIT_CIRCT();
}

/*********************************************************************************************************
** Function name:           I2C1IRQ
** Descriptions:            库函数默认的中断服务函数,进行I2C中断处理,该函数挂接了钩子函数可处理用户任务
** Input parameters:        NONE
** Output parameters:       NONE
** Returned value:          NONE
*********************************************************************************************************/
void i2c1IRQ ( void )
{
    __OS_ENTER_CIRCT();
	__i2cISR(__GpiinfoDateTab[1]);
	i2c1Hook();
	VICVectAddr = 0x00;                                                 /*  清除VIC中断                 */
    __OS_EXIT_CIRCT();
}

/*********************************************************************************************************
** Function name:           I2C2IRQ
** Descriptions:            库函数默认的中断服务函数,进行I2C中断处理,该函数挂接了钩子函数可处理用户任务
** Input parameters:        NONE
** Output parameters:       NONE
** Returned value:          NONE
*********************************************************************************************************/
void i2c2IRQ ( void )
{
    __OS_ENTER_CIRCT();
	__i2cISR(__GpiinfoDateTab[2]);
	i2c2Hook();
	VICVectAddr = 0x00;                                                 /*  清除VIC中断                 */
    __OS_EXIT_CIRCT();
}

/*********************************************************************************************************
** Function name:           __I2CInit
** Descriptions:            I2c初始化程序(非字符串型),该函数需要被封装一层的,如果设置参数的速度超过400K
**                          则设置标准速度100K
** Input parameters:        ID              器件子设备号
**                          Speed           I2C通讯速度
**                          Rsv             保留参数
** Output parameters:       NONE
** Returned value:          PIN_ERR         管脚配置错误
**                          OPERATE_FAIL    初始化失败,ID错误
**                          OPERATE_SUCCESS 初始化成功
*********************************************************************************************************/
static int __i2cInit ( uint32 ID, 
                       uint32 Speed, 
                       void  *Rsv )
{
	volatile uint8 *pucAddrBase;
	volatile uint32 uiOffBase;
	
	Rsv = Rsv;                                                          /*  防止编译报警                */
	/* 
	 *  参数过滤,判断
	 */
	if ( ID >= __IIC_MAX_NUM ) {
	    return OPERATE_FAIL;
	}
	
	if ( Speed > 400000 ) {
	    Speed = 100000;
	}
	
	/*
	 *  创建信号量,操作系统部分
	 */
	 #if __UCOSII_EN > 0
	    *GpposeI2cTable[ID] = OSSemCreate(1);
	    if(*GpposeI2cTable[ID] == (void *)NULL) {                       /*  如果创建信号量失败返回错误  */
	        return OPERATE_FAIL;
	    }
	 #endif
	 
	/* 
	 *  初始化一些参数 
	 */
	__GpiinfoDateTab[ID]->uiID          = ID;
	__GpiinfoDateTab[ID]->pucAddrBase   = (uint8*)__GuiI2cBaseAddrTab[ID];
	__GpiinfoDateTab[ID]->uiOffBase     = 2;
	__GpiinfoDateTab[ID]->ucIICflag     = I2C_IDLE;                     /*  标识该器件现在空闲          */
	__GpiinfoDateTab[ID]->ucSlave       = __IIC_MASTER;                 /*  标识该器件为主机            */
	__GpiinfoDateTab[ID]->usDataNum     = 0;
	
	pucAddrBase = __GpiinfoDateTab[ID]->pucAddrBase;	                /*  获取指针参数                */
	uiOffBase   = __GpiinfoDateTab[ID]->uiOffBase;
	
	*(uint16*)(pucAddrBase+(__B_IIC_SCLH << uiOffBase) ) = (uint16)((Fpclk / Speed + 1) / 2);
	                                                                    /*  设置时钟高电平时间          */
	                                                                    
	*(uint16*)(pucAddrBase+(__B_IIC_SCLL << uiOffBase) ) = (uint16)((Fpclk / Speed) / 2);	
	                                                                    /*  设置时钟低电平时间          */
                                                                    
    pucAddrBase[__B_IIC_CLR << uiOffBase]  = 0x2C;
    pucAddrBase[__B_IIC_SET << uiOffBase]  = 0x40;                      /*  设置主模式                  */
    
    return OPERATE_SUCCESS;
}

/*********************************************************************************************************
** Function name:           i2cInit
** Descriptions:            I2c初始化程序,如果设置参数的速度超过400K则设置标准速度100K
** Input parameters:        ID   器件子设备号,例如ID=0,表示初始化的是I2C0
**                          arg	 设置参数的字符串,该函数暂时只设置I2C速度
**                              例如要设置的速度为200K,则字符串为"Speed=200000"
**                          Rsv	 保留参数
** Output parameters:       NONE
** Returned value:          PIN_ERR         管脚配置错误
**                          OPERATE_FAIL    初始化失败,ID错误
**                          OPERATE_SUCCESS 初始化成功
*********************************************************************************************************/
int32 i2cInit (uint32   ID, 
               char    *arg, 
               void    *Rsv)
{
	uint32 uiParm[1]={-1};
	
	if (ID < __IIC_MAX_NUM) {
		ImpCmd(Tab_I2C, arg, uiParm);                                   /*  解析字符串参数              */
		return __i2cInit(ID, uiParm[0], Rsv);                           /*  初始化部件                  */
	} 
	return OPERATE_FAIL;

⌨️ 快捷键说明

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