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

📄 i2c.c

📁 花高价买来的开发板
💻 C
字号:
/****************************************Copyright (c)**************************************************
**                               Guangzhou ZHIYUAN electronics Co.,LTD.
**                                     
**                                 http://www.zyinside.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: I2C.c
** Last modified Date: 2006-01-11 
** Last Version: v1.0
** Description: S3C2410的I2C软件包
**              查询控制方式
**------------------------------------------------------------------------------------------------------
** Created By: 黄绍斌
** Created date: 2005-12-31 
** Version: v1.0
** Descriptions:
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Description:
**
********************************************************************************************************/
#define  IN_I2C
#include  "config.h"

// I2C总线设置宏定义
#define	  IICCON_DACK		((1<<7) | (1<<6) | (1<<5) | (0<<0))	/* 使能ACK位,IICCLK=PCLK/512=97656 */
#define	  IICCON_DNACK		((0<<7) | (1<<6) | (1<<5) | (0<<0))	/* 中断使能(这样才能正确操作I2C) */



/*********************************************************************************************************
** Function name: InitI2C
** Descriptions: 初始化总线 (100KHz总线速率)
**               设FCLK=200MHz,HCLK=100MHz,PCLK=50MHz。
** Input: 无
** Output: 无
** Created by: 黄绍斌
** Created Date: 2006-01-11 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void  InitI2C(void)
{  	
    // 设置管脚连接  
    rGPECON = (rGPECON & 0x0FFFFFFF) | 0xA0000000;	// 设置I2C口使能
    rGPEUP = rGPEUP | 0xC000;		// 禁止内部上拉电阻           
       
    // 设置I2C控制寄存器 (使能ACK位时才能接收从机的应答位)
    rIICCON = IICCON_DACK;          
    
    // 设置I2C为主机模式
    rIICSTAT = (3<<6)|(1<<4); 
    
    // 从机地址 (作主机时没有用)
    rIICADD = 0x10;         
}



/*********************************************************************************************************
** Function name: START_I2C
** Descriptions: 启动总线,发送从机地址,并发送从机地址
** Input: sla		从机动地址
** Output: 操作成功返回TRUE,仲载失败/无从机应答返回FALSE
** Note: sla位最低位为读写控制位
** Created by: 黄绍斌
** Created Date: 2006-01-11 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int  StartI2C(uint8 sla)
{	
    uint32  i;	

	rIICDS = sla;		// 设置从机地址				
	if(sla&0x01)
	{	
	    rIICSTAT = (2<<6)|(1<<5)|(1<<4);	// 主接收模式,发送使能,启动总线
		rIICCON = IICCON_DACK;				// 若是重启总线,则需要有此操作
    }
    else
    {	
        rIICSTAT = (3<<6)|(1<<5)|(1<<4);	// 主发送模式,发送使能,启动总线 
    }
      
    // 等待操作完成
    while((rIICCON&0x10) == 0);    
    
    // 判断操作是否成功 (总线仲裁和从机应答)
   	if((rIICSTAT&0x09) == 0)
   	{  	
   	    return(TRUE);   		
   	}
   	else
   	{  	
   	    // 发送结束信号
   		if(sla&0x01) rIICSTAT = (2<<6)|(0<<5)|(1<<4);	
		  else  rIICSTAT = (3<<6)|(0<<5)|(1<<4);	
		rIICCON = IICCON_DACK;	
   	
   		for(i=0; i<5000; i++);				// 等待结束信号产生完毕
   		return(FALSE);
   	} // end of if((rIICSTAT&0x09) == 0)...else... 
}		    
	
	

/*********************************************************************************************************
** Function name: I2C_SendByte
** Descriptions: 发送一字节数据,并接收应答位
** Input: dat		要发送的数据
** Output: 操作成功返回TRUE,仲载失败/无从机应答返回FALSE
** Created by: 黄绍斌
** Created Date: 2006-01-11 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int  I2C_SendByte(uint8 dat)
{	
    uint32  i;

	rIICDS = dat;				// 将数据写入I2C数据寄存器
	rIICCON = IICCON_DACK;		// 清除中断标志,允许发送数据操作
	
	// 等待操作完成
    while((rIICCON&0x10) == 0);
    
    // 判断操作是否成功 (总线仲裁和从机应答)
   	if((rIICSTAT&0x09) == 0)
   	{  	
   	    return(TRUE);   		
   	}
   	else
   	{  	
   	    // 发送结束信号	
		rIICSTAT = (3<<6)|(0<<5)|(1<<4);	
		rIICCON = IICCON_DACK;
		
		for(i=0; i<5000; i++);	// 等待结束信号产生完毕
   		return(FALSE);
   	}
}



/*********************************************************************************************************
** Function name: I2C_RcvByteNA
** Descriptions: 接上I2C总线上一字节数据,并发送非应答位
** Input: dat		用于接收数据的指针
** Output: 操作成功返回TRUE,仲载失败/无从机应答返回FALSE
** Created by: 黄绍斌
** Created Date: 2006-01-11 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int  I2C_RcvByteNA(uint8 *dat)
{	
    uint32  i;
	
	// 允许接收数据
	rIICCON = IICCON_DNACK;	
	
	// 等待接收数据操作完成
    while((rIICCON&0x10) == 0);
    
    // 判断操作是否成功 (总线仲裁)
   	if((rIICSTAT&0x08) != 0)   	
   	{  	
   	    // 发送结束信号	
		rIICSTAT = (2<<6)|(0<<5)|(1<<4);	
		rIICCON = IICCON_DACK;
		
		for(i=0; i<5000; i++);	// 等待结束信号产生完毕
		return(FALSE);
   	}
   	
	*dat = rIICDS;		// 读取数据	
	return(TRUE);   	
}



/*********************************************************************************************************
** Function name: I2C_RcvByteA
** Descriptions: 接上I2C总线上一字节数据,并发送应答位
** Input: dat		用于接收数据的指针
** Output: 操作成功返回TRUE,仲载失败/无从机应答返回FALSE
** Created by: 黄绍斌
** Created Date: 2006-01-11 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int  I2C_RcvByteA(uint8 *dat)
{	
    uint32  i;

	// 允许接收数据
	rIICCON = IICCON_DACK;
	
	// 等待接收数据操作完成
    while((rIICCON&0x10) == 0);
    
    // 判断操作是否成功 (总线仲裁)
   	if((rIICSTAT&0x08) != 0)   	
   	{  	
   	    // 发送结束信号	
		rIICSTAT = (2<<6)|(0<<5)|(1<<4);	
		rIICCON = IICCON_DACK;
		
		for(i=0; i<5000; i++);	// 等待结束信号产生完毕
		return(FALSE);
   	}

	*dat = rIICDS;		// 读取数据
	return(TRUE);  
}



/*********************************************************************************************************
** Function name: STOP_I2C
** Descriptions: 结束总线
** Input: send	    I2C当前模模式。主发送模式时为1,否则为0(主接收模式)
** Output: 无
** Created by: 黄绍斌
** Created Date: 2006-01-11 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void  StopI2C(uint8 send)
{	
    uint32  i;

	if(send)
	{	
	    rIICSTAT = (3<<6)|(0<<5)|(1<<4);// 发送结束信号
	}
	else
	{	
	    rIICSTAT = (2<<6)|(0<<5)|(1<<4);// 发送结束信号
	}
  	rIICCON = IICCON_DACK;	
	for(i=0; i<5000; i++);				// 等待结束信号产生完毕
}



/*********************************************************************************************************
** Function name: ISendStr
** Descriptions: 使用硬件I2C发送数据。
** Input: sla		从机地址
**		  suba	    器件子地址(第一字节用来表示子地址字节个数)
**		  s		    发送数据缓冲区
**		  no		发送数据个数
** Output: 操作成功返回TRUE,仲载失败/无从机应答返回FALSE
** Note: 使用前设置好参数。程序不会更改s、suba缓冲区的数据
** Created by: 黄绍斌
** Created Date: 2006-01-11 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int  ISendStr(uint8 sla, uint8 *suba, uint8 *s, uint8 no)
{	
    int  bak;

	sla = sla & 0xFE;
	if(!StartI2C(sla)) 
	{	 
	    if(!StartI2C(sla)) return(FALSE);		// 启动总线,发送从机地址
	}
	
	// 发送器件子地址
	bak = *suba++;
	for(; bak>0; bak--)
	{	
	    if(!I2C_SendByte(*suba++)) return(FALSE);
	}
	
	// 发送数据
	for(; no>0; no--)
	{	
	    if(!I2C_SendByte(*s)) return(FALSE); 
		s++;
	} 
	
	StopI2C(1);		// 结束总线
	
	return(TRUE);
}



/*********************************************************************************************************
** Function name: IRcvStr
** Descriptions: 使用硬件I2C读取数据。
** Input: sla		从机地址
*		  suba	    器件子地址缓冲区指针(第一字节用来表示子地址字节个数)
*		  s		    接收数据缓冲区
*		  no		接收数据个数
** Output: 操作成功返回TRUE,仲载失败/无从机应答返回FALSE
** Note: 使用前设置好参数。程序不会更改suba缓冲区的数据
** Created by: 黄绍斌
** Created Date: 2006-01-11 
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
int  IRcvStr(uint8 sla,uint8 *suba,uint8 *s,uint8 no)
{  	
    int  bak;

	bak = *suba++;	// 子地址个数
	if(bak > 0)
	{	
	    sla = sla & 0xFE;
		if(!StartI2C(sla)) 
		{	 
		    if(!StartI2C(sla)) return(FALSE);	// 启动总线,发送从机地址(写)
		}
	
		// 发送器件子地址	
		for(; bak>0; bak--)
		{	
		    if(!I2C_SendByte(*suba++)) return(FALSE);
		}
	}
	
	// 重启总线
	sla = sla | 0x01;
	if(!StartI2C(sla)) return(FALSE);		// 启动总线,发送从机地址(读)
	
	// 读取数据	
	for(; no>1; no--)
	{	
	    if(!I2C_RcvByteA(s)) return(FALSE); // 发送数据
		s++;
	}	
	if(!I2C_RcvByteNA(s)) return(FALSE);	
	
	StopI2C(0);		// 结束总线
	
	return(TRUE);
}

/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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