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

📄 i2c.c

📁 手机中用的I2C代码,包含GPIO口说明
💻 C
字号:
//**********************I2C标准代码**************************
/*****使用接口说明*****
1.在宏定义中修改GPIO口名称;
2.在宏定义中修改I2C_ADDR的值,该值是使用芯片的写地址;
3.单次读函数是i2c_read_byte,单次写函数是i2c_write_byte;
4.若要使用连续读方式,调用i2c_read_byte_cont。
  读出数据放在全局变量整形数组i2c_read_result[CONT_READ_NUM]当中,
  读寄存器的数目由宏定义CONT_READ_NUM确定,按需要修改;
5.若要使用连续写方式,调用i2c_write_byte_cont。
  待写数据放在全局变量整形数组i2c_write_regdata[CONT_WRITE_NUM]当中,
  写寄存器数的数目由宏定义CONT_WRITE_NUM确定,按需要修改。
*/


//************************宏定义*****************************

#define SDA_H 			M_DLGpioAssertLine(GPIO_9)
#define SDA_L 			M_DLGpioDeassertLine(GPIO_9)
#define SCL_H 			M_DLGpioAssertLine(GPIO_13)
#define SCL_L 			M_DLGpioDeassertLine(GPIO_13)

#define I2C_ADDR 		0x20
#define SDA_INPUT_DATA  	DLGpioReadInputLine(GPIO_9)
#define SDA_INPUT_MODE		DlGpioConfigure(GPIO_9, PIN_MODE_NORMAL, GPIO_INPUT, ACTIVE_HIGH)
#define SDA_OUTPUT_MODE		DlGpioConfigure(GPIO_9, PIN_MODE_NORMAL, GPIO_OUTPUT, ACTIVE_HIGH)
#define SCL_OUTPUT_MODE		DlGpioConfigure(GPIO_13, PIN_MODE_NORMAL, GPIO_OUTPUT, ACTIVE_HIGH)

#define CONT_WRITE_NUM		10
#define CONT_READ_NUM		10
//**************************************************************

//************************子函数列表****************************
void 	i2c_GPIO_init(void);
void 	i2c_start(void);
void 	i2c_stop(void);
Boolean i2c_getack(void);
void 	i2c_sendack(void);
void	i2c_sendnoack(void);
void	i2c_send(int iicd);
int 	i2c_read(void);
void 	i2c_delay(void);
//**************************************************************

//********************主调函数及全局读写数组列表****************
//**单次读写**
Boolean i2c_write_byte(int i2c_addr,int i2c_reg,int i2c_data);		//单次写寄存器
int 	i2c_read_byte(int i2c_addr,int i2c_reg);			//单次读寄存器

//**连续读写**
int 	i2c_write_regdata[CONT_WRITE_NUM];				//存贮待写的寄存器值
Boolean i2c_write_byte_cont(int i2c_addr,int i2c_base_reg,int num_reg);	//连续写寄存器  未验证
int 	i2c_read_result[CONT_READ_NUM];					//存贮读出的寄存器值
void 	i2c_read_byte_cont(int i2c_addr,int i2c_base_reg,int num_reg);	//连续读寄存器

//**************************************************************



//****************************函数名细**************************

/*********************************************************************
	Name     :  i2c_GPIO_init
	Function :  I2C bus released, be ready to start bus
	Input    : void
	Return   : None
	Time     : 2005-08-30
*************************************************************************/
void i2c_GPIO_init(void)
{
	SDA_OUTPUT_MODE;
	SCL_OUTPUT_MODE;
	i2c_stop();
}

/*********************************************************************
	Name     :  i2c_write_byte
	Function :  write a byte to codec
	Input    : int i2c_addr,int i2c_reg,int i2c_data
	Return   : TRUE or FALSE
	Time     : 2005-08-30
*************************************************************************/
Boolean i2c_write_byte(int i2c_addr,int i2c_reg,int i2c_data)
{
	i2c_start();
	i2c_send(i2c_addr);
	if(!i2c_getack()) 
	{	
		i2c_send(i2c_reg);
		if(!i2c_getack())
		{
			i2c_send(i2c_data);
			if(!i2c_getack())
	    		{
	    			i2c_stop();	
	    			return(TRUE);
	    		}
	    		else	
	    			i2c_stop();
		 		return(FALSE);
		}
		else
			i2c_stop();
		 	return(FALSE);		 
	}
	else 
		i2c_stop();
		return(FALSE);	
}

/*********************************************************************
	Name     :  i2c_write_byte_cont   未验证
	Function :  write a byte to codec
	Input    : int i2c_addr,int i2c_base_reg,int* i2c_data,int num_reg
	Return   : TRUE or FALSE
	Time     : 2005-08-30
*************************************************************************/
Boolean i2c_write_byte_cont(int i2c_addr,int i2c_base_reg,int num_reg)
{
	int i;
	
	i2c_start();
	i2c_send(i2c_addr);
	if(!i2c_getack()) 
	{	
		i2c_send(i2c_base_reg);
		if(!i2c_getack())
		{
			for(i=0;i<num_reg;i++)
			{
				i2c_send(i2c_write_regdata[i]);
				if(i2c_getack())
				{
	    				i2c_stop();
		 			return(FALSE);
		 		}
		 	}
		 	i2c_stop();	
	    		return(TRUE);
		}
		else
			i2c_stop();
		 	return(FALSE);		 
	}
	else 
		i2c_stop();
		return(FALSE);	
}

/*********************************************************************
	Name     :  i2c_read_byte
	Function :  read a byte from codec
	Input    : int i2c_addr,int i2c_reg
	Return   : i2c_data
	Time     : 2005-08-30
*************************************************************************/  
int i2c_read_byte(int i2c_addr,int i2c_reg)
{
	int result;
	
	i2c_start();				//START
	i2c_send(i2c_addr);			//写I2C写地址
	i2c_getack();
	i2c_send(i2c_reg);
	i2c_getack();
	
	i2c_start();     			//RE-START 
	i2c_send((i2c_addr| 0x01));		//写I2C读地址
  	i2c_getack();
	result=i2c_read();
  	i2c_sendnoack();
  	i2c_stop();
	
	return(result);
}

/*********************************************************************
	Name     :  i2c_read_byte_cont
	Function :  read continuous byte from codec
	Input    : int i2c_addr,int i2c_base_reg,int num_reg
	Return   : none
	Time     : 2005-08-30
*************************************************************************/
void i2c_read_byte_cont(int i2c_addr,int i2c_base_reg,int num_reg)
{
	int i;
//	int* p_temp = malloc(num_reg);
	
	i2c_start();				//START
	i2c_send(i2c_addr);			//写I2C写地址
	i2c_getack();
	i2c_send(i2c_base_reg);
	i2c_getack();
	
	i2c_start();     			//RE-START 
	i2c_send((i2c_addr| 0x01));		//写I2C读地址
  	i2c_getack();
  	
  	for(i=0;i<num_reg;i++)
  	{
		i2c_read_result[i] = i2c_read();
		if(i==(num_reg-1))
			{
				i2c_sendnoack();
				i2c_stop();
//				free(p_temp);
				return;
			}
		i2c_sendack();
	}
}


/*********************************************************************
I2C timeing-production functions listed below
*************************************************************************/
void i2c_start()
{	
	SDA_H;
	i2c_delay();
	SCL_H;
	i2c_delay();
	SDA_L;
	i2c_delay();
	SCL_L;
}

void i2c_stop()
{
	SDA_L;
	i2c_delay();
	SCL_H;
	i2c_delay();
	SDA_H;
}

Boolean i2c_getack()
{
	Boolean i2c_ack;
	
	SDA_INPUT_MODE;
	
	SCL_H;
	i2c_ack=SDA_INPUT_DATA;
	/*调试用
	if(i2c_ack==TRUE)	//no answer
	{
		printf("no ACK");
	}
	else			//answer
	{
		printf("ACK");
	}
	*/
	SCL_L;
	SDA_OUTPUT_MODE;
	return(i2c_ack);
}

void i2c_sendack()
{
	SDA_OUTPUT_MODE;
	SDA_L;
	i2c_delay(); 
	SCL_H;
	i2c_delay();
	SCL_L;
	SDA_INPUT_MODE;
}

void i2c_sendnoack()
{
	SDA_OUTPUT_MODE;
	SDA_H;
	i2c_delay();
	SCL_H;
	i2c_delay();
	SCL_L;
	i2c_delay();
	SDA_L;
}

void i2c_send(int i2c_data)
{
	int i;
	
	for(i=0;i<8;i++)
	{	
		if(((i2c_data)& (0x80))>0)	//send 1
		{
			SDA_H;
			i2c_delay();
			SCL_H;		
			i2c_delay();
			SCL_L;
			SDA_L;			//不加此句会产生半高电平(原因是低电平响应位提前出现,会造成短时间短路)
		}
		else       			//send 0
		{
			SDA_L;
			i2c_delay();
			SCL_H;
			i2c_delay();
			SCL_L;
		}
		i2c_data<<=1; 			//RLC  
	}
}

int  i2c_read(void)
{
	int i,temp,result=0;
	SDA_INPUT_MODE;
	for(i=0;i<8;i++)
	{
		i2c_delay();
		SCL_H;
		i2c_delay();
		temp=SDA_INPUT_DATA;
		if(temp==1)   			//read 1
		{
			result<<=1;
			result|=1;
			i2c_delay();
			SCL_L;
		}
		else       			// read 0
		{
			result<<=1;
			i2c_delay();
			SCL_L;
		}
	}
	SDA_OUTPUT_MODE;
	return(result);
}

void i2c_delay(void)
{
}

⌨️ 快捷键说明

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