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

📄 i2c.c

📁 周立功 《μCOS-II微小内核分析与程序设计-基于LPC2300》配套例程源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/***********************************************Copyright (c)*********************************************
**                                Guangzou ZLG-MCU Development Co.,LTD.
**                                     
**                                       http://www.zlgmcu.com
**
**--------------File Info---------------------------------------------------------------------------------
** File name:			    IIC.c
** Last modified Date:      2007-10-15
** Last Version:		    1.0
** Descriptions:		    I2C函数实现,采用设备描述符来操作
**
**--------------------------------------------------------------------------------------------------------
** Created by:			    lixiaocheng
** Created date:		    2007-10-15
** Version:				    1.0
** Descriptions:		    无
**
**--------------------------------------------------------------------------------------------------------
** Modified by:			    lixiaocheng
** Modified Date:		    2007-10-26
** Version:				    1.1
** Descriptions:		    增加了I2C对UCOSII操作系统的兼容
**
*********************************************************************************************************/
#include "Config.h"
#include "I2cPrivate.h"
#include "I2c.h"                                                        
#include "I2cHook.h"
#include "CmdStr.h"
#include "DeviceConfig.h"
                                                        
/*********************************************************************************************************
   定义操作I2C器件的结构体,有多个器件就需要声明多个结构体
*********************************************************************************************************/
static __I2C_INFO   __I2C0Data;
static __I2C_INFO   __I2C1Data;
static __I2C_INFO   __I2C2Data;

/*********************************************************************************************************
   是操作系统就申明信号量
*********************************************************************************************************/
#if __UCOSII_EN > 0
    OS_EVENT       *GposeI2c0Sem;
    OS_EVENT       *GposeI2c1Sem;
    OS_EVENT       *GposeI2c2Sem;
    OS_EVENT      **GpposeI2cTable[__IIC_MAX_NUM] = {&GposeI2c0Sem, &GposeI2c1Sem, &GposeI2c2Sem};
#endif

/*********************************************************************************************************
   下面使用指针数组来保存结构体指针,方便对该驱动的扩展
*********************************************************************************************************/
const __PI2C_INFO   __GpiinfoDateTab[__IIC_MAX_NUM] = {&__I2C0Data, &__I2C1Data, &__I2C2Data};

/*********************************************************************************************************
   下面定义了I2C0基地址值,如果有多个I2C器件可以在该位置添加相应的基地址即可
*********************************************************************************************************/
const uint32        __GuiI2cBaseAddrTab[__IIC_MAX_NUM] = {I2C0_BASE_ADDR, I2C1_BASE_ADDR, I2C2_BASE_ADDR};

/*********************************************************************************************************
** Function name:           endBus
** Descriptions:            总线错误结束总线,改函数被__i2cISR调用
** Input parameters:        Parm--I2C设备描述符结构体指针
** Output parameters:       NONE
** Returned value:          NONE
*********************************************************************************************************/
static void __endBus (__PI2C_INFO Parm)
{
	            uint32				uiOffBase;
	volatile 	uint8 	           *pucAddrBase;
	
	pucAddrBase	= Parm->pucAddrBase;
	uiOffBase   = Parm->uiOffBase;
    
	pucAddrBase[__B_IIC_SET << uiOffBase] = 1 << 4;                     /*  总线出错,结束总线.STO      */
	pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x2C;                       /*  总线出错,清零STA,SI,AA     */
	Parm->ucIICflag                       = I2C_ERR;
    __I2C_UNLOCK(*GpposeI2cTable[Parm->uiID]);                          /*  释放信号量                  */
}

/*********************************************************************************************************
** Function name:           AddrWrite
** Descriptions:            写入从机地址,改函数被__i2cISR调用
** Input parameters:        Parm--I2C设备描述符结构体指针
** Output parameters:       NONE
** Returned value:          NONE
*********************************************************************************************************/
static void __AddrWrite (__PI2C_INFO Parm)
{
	            uint32				uiOffBase;
	volatile 	uint8 	           *pucAddrBase;
	
	pucAddrBase	= Parm->pucAddrBase;
	uiOffBase   = Parm->uiOffBase;
	
    if (Parm->ucI2CSubAddrCtl == 1) {                                   /*  指定子地址读时,先写入地址  */
		pucAddrBase[__B_IIC_DAT << uiOffBase] = (uint8)((Parm->ucSLAddr)&0xFE);
	} else {														    /*  否则直接发送从机地址        */
		pucAddrBase[__B_IIC_DAT << uiOffBase] = (Parm->ucSLAddr);
	}
	pucAddrBase[__B_IIC_CLR << uiOffBase]     = 0x28;                   /*  清除中断标志                */
}

/*********************************************************************************************************
** Function name:           dateWrite
** Descriptions:            写入数据,改函数被__subAddrWrite调用
** Input parameters:        Parm--I2C设备描述符结构体指针
** Output parameters:       NONE
** Returned value:          NONE
*********************************************************************************************************/
static void __dateWrite (__PI2C_INFO Parm)
{
	            uint32				uiOffBase;
	volatile 	uint8 	           *pucAddrBase;
	
	pucAddrBase	= Parm->pucAddrBase;
	uiOffBase   = Parm->uiOffBase;
	
	if (Parm->usDataNum > 0) {
		pucAddrBase[__B_IIC_DAT << uiOffBase] = *Parm->pucDataBuf++;
		pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x28;                   /*  清零SI,STA                 */
		Parm->usDataNum--;
	} else {
		pucAddrBase[__B_IIC_SET << uiOffBase] = 0x10;                   /*  无数据发送结束总线          */
		pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x28;
		Parm->ucIICflag = I2C_WRITE_END;						        /*  设置总线结束标志            */
        __I2C_UNLOCK(*GpposeI2cTable[Parm->uiID]);                      /*  释放信号量                  */
	}
}

/*********************************************************************************************************
** Function name:           dateRead
** Descriptions:            读取数据,改函数被__i2cISR调用
** Input parameters:        Parm--I2C设备描述符结构体指针
** Output parameters:       NONE
** Returned value:          NONE
*********************************************************************************************************/
static void __dateRead (__PI2C_INFO Parm)
{
	            uint32				uiOffBase;
	volatile 	uint8 	           *pucAddrBase;
	
	pucAddrBase	= Parm->pucAddrBase;
	uiOffBase   = Parm->uiOffBase;
	
	*(Parm->pucDataBuf++) = pucAddrBase[__B_IIC_DAT << uiOffBase];
	Parm->usDataNum--;
	
	switch ( Parm->usDataNum ) {
	
	case 0:
		pucAddrBase[__B_IIC_SET << uiOffBase] = 0x10;                   /*  结束总线                    */
		pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x28;
		Parm->ucIICflag = I2C_READ_END;                                 /*  返回读取成功                */
        __I2C_UNLOCK(*GpposeI2cTable[Parm->uiID]);                      /*  释放信号量                  */
	break;
	
	case 1:                                                             /*  接收最后一个字节            */
		pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x2C;                   /*  再接收到数据返回非应答位    */
	break;
	
	default:
		pucAddrBase[__B_IIC_SET << uiOffBase] = 0x04;                   /*  接收到数据,返回ACK         */
		pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x28;
	break;
	}
}

/*********************************************************************************************************
** Function name:           subAddrWrite
** Descriptions:            写入从机子地址地址,改函数被__i2cISR调用
** Input parameters:        Parm--I2C设备描述符结构体指针
** Output parameters:       NONE
** Returned value:          NONE
*********************************************************************************************************/
static void __subAddrWrite (__PI2C_INFO Parm)
{
	            uint32				uiOffBase;
	volatile 	uint8 	           *pucAddrBase;
	
	pucAddrBase	= Parm->pucAddrBase;
	uiOffBase   = Parm->uiOffBase;

	if (Parm->ucI2CSubAddrCtl == __IIC_SUB_NONE) {                      /*  无子地址或子地址已处理      */
	    __dateWrite( Parm );                                            /*  直接发送数据                */
	                                                                
	} else if (Parm->ucI2CSubAddrCtl == __IIC_SUB_R) {                  /*  读操作发送子地址            */
		if(Parm->ucSubAddrNum == 2) {
			pucAddrBase[__B_IIC_DAT << uiOffBase] = (uint8)((Parm->usSubAddr >> 8) & 0xff);	
			                                                            /*  多于一个字节从机子地址      */
			                                                            /*  先发送高字节地址            */
			                                                        
			pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x28;
			Parm->ucSubAddrNum--;
		} else if (Parm->ucSubAddrNum == 1) {
			pucAddrBase[__B_IIC_DAT << uiOffBase] = (uint8)((Parm->usSubAddr) & 0xff);
			                                                            /*  发送低字节地址或单字节地址  */
			pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x28;
			Parm->ucSubAddrNum--;
		} else if (Parm->ucSubAddrNum == 0) {                           /*  发送完子地址,重起总线      */	
			pucAddrBase[__B_IIC_SET << uiOffBase] = 0x20;
			pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x18;
			Parm->ucI2CSubAddrCtl = __IIC_SUB_NONE;
		}
	} else if (Parm->ucI2CSubAddrCtl == __IIC_SUB_W) {                  /*  写操作发送子地址            */
		if(Parm->ucSubAddrNum == 2) {
			pucAddrBase[__B_IIC_DAT << uiOffBase] = (uint8)((Parm->usSubAddr >> 8) & 0xff);	
			                                                            /*  多于一个字节从机子地址      */
			                                                            /*  先发送高字节地址            */
			                                                        
			pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x28;
			Parm->ucSubAddrNum--;
		} else if ( Parm->ucSubAddrNum == 1 ) {
			pucAddrBase[__B_IIC_DAT << uiOffBase] = (uint8)(Parm->usSubAddr & 0xff);
			                                                            /*  发送低字节地址或单字节地址  */
			                                                        
			pucAddrBase[__B_IIC_CLR << uiOffBase] = 0x28;
			Parm->ucI2CSubAddrCtl                 = __IIC_SUB_NONE;     /*  子地址已处理                */
			Parm->ucSubAddrNum--;
		} else if (Parm->ucSubAddrNum == 0) {                           /*  写数据无子地址              */
		     __dateWrite( Parm );                                       /*  直接发送数据                */
		     Parm->ucI2CSubAddrCtl                = __IIC_SUB_NONE;     /*  子地址已处理                */

⌨️ 快捷键说明

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