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

📄 i2c.c

📁 液晶显示键盘操作密码编辑控制加上对存储器操作
💻 C
字号:
#include <reg51.h>

#include "i2c.h"

uchar code set_tab[]={ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x00,0x01,
                       0x00,0x01,0x02,0x03,0x04,0x06,0x06,0x07,0x08,0x09,0x00,0x02,
                       0x00,0x01,0x02,0x03,0x04,0x07,0x06,0x07,0x08,0x09,0x00,0x03,
                       0x00,0x01,0x02,0x03,0x04,0x08,0x06,0x07,0x08,0x09,0x00,0x04,
                       0x00,0x01,0x02,0x03,0x04,0x09,0x06,0x07,0x08,0x09,0x00,0x05 };
////5个用户的帐号和密码信息,前6个是帐户,后6个是密码////////////////////////////////////
/* =========================================================================
*     I2C总线基本操作函数(接口模拟函数)
* =========================================================================*/

/****************************************************************************
*    函数原型: void i_delay(void);
*    功    能: 本函数实际上只有一条返回指令, 在具体应用中可视具体要求增加延时 
*              指令。
****************************************************************************/
void i_delay( void )
 {	;;;;
 }

/****************************************************************************
*    函数原型: void I_start(void);
*    功    能: 提供I2C总线工作时序中的起始位。                             
****************************************************************************/
void I_start( void )
 {	SCL = HIGH ;
    SDA = HIGH;
	i_delay() ;
	SDA = LOW ;
	i_delay() ;
	SCL = LOW ;
	i_delay() ;
  
 }

/****************************************************************************
*    函数原型: void I_stop(void);
*    功    能: 提供I2C总线工作时序中的停止位。
****************************************************************************/
void I_stop( void ) 
{	SDA = LOW ;
	SCL = HIGH ;
	i_delay() ;
	SDA = HIGH ;
	i_delay() ;
	SCL = LOW ;
	i_delay() ;
 }

/****************************************************************************
*    函数原型: void I_init(void);
*    功    能: I2C总线初始化。在main()函数中应首先调用本函数, 然后再调用
*              其它函数。
****************************************************************************/
void I_init( void ) 
{	SCL = LOW ;
	I_stop() ;
}

/****************************************************************************
*    函数原型: bit I_clock(void);
*    功    能: 提供I2C总线的时钟信号, 并返回在时钟电平为高期间SDA 信号线上状
*              态。本函数可用于数据发送, 也可用于数据接收。
****************************************************************************/
bit I_clock( void )
 {	bit sample ;
	SCL = HIGH ;
	i_delay() ;
	sample = SDA ;
	SCL = LOW ;
	i_delay() ;
	return (sample);
 }

/****************************************************************************
*    函数原型: bit I_send(uchar I_data);
*    功    能: 向I2C总线发送8位数据, 并请求一个应答信号ACK。如果收到ACK应答
*              则返回1(TRUE), 否则返回0(FALSE)。
****************************************************************************/
bit I_send( uchar I_data )
 {	uchar i;
	for (i=0;i<8;i++) 	// 发送8位数据 //
	{	SDA = (bit)(I_data & 0x80) ;
		I_clock() ;
		I_data=I_data<<1 ;
	}	
	SDA=HIGH ; //请求应答信号ACK //
	return (~I_clock());
  }

/****************************************************************************
*    函数原型: uchar I_receive(void);
*    功    能: 从I2C总线上接收8位数据信号, 并将接收到8位数据作为一个字节
*              返回, 不回送应答信号ACK。主函数在调用本函数之前应保证SDA信
*              号线处于浮置状态, 即使8051的P1.7脚置1。
****************************************************************************/
uchar I_receive( void )
 {	uchar I_data = 0 ;
	register uchar i ;
	for (i=0;i<8;i++) 
	{	I_data *= 2 ;
		if (I_clock()) I_data++;
	}
	return (I_data) ;
	//注意:没有回送ACK信号,方便后面读取数据时控制传输结束////////////
}
/****************************************************************************
*    函数原型: void I_Ack(void);
*    功    能: 向I2C总线发送一个应答信号ACK, 一般用于连续数据读取时。
*****************************************************************************/
void I_Ack( void )
{	SDA = LOW ;
	I_clock() ;
	SDA = HIGH ;
}
/****************************************************************************
*    函数原型: bit E_address(uchar Address);
*    功    能: 对24C01指定一个存储器空间地址。
*****************************************************************************/
bit E_address( uchar Address ) 
{	I_start() ;// 发送启动信号,该信号不可掉,否则无法正常传输////////
	if (I_send(WRITE))
		return (I_send( Address));
	else
		return (FALSE);
}

/****************************************************************************
*    函数原型: uchar E_read_onedata(uchar address);
*    功    能: 从24C01中address地址中读取1个字节的数据,并将读取的数据作为
*              函数的返回值返回。读取不成功返回值为0。注意不要将address地址
*              中的数据放为0,以免误解。
*****************************************************************************/
/*
uchar E_read_onedata(uchar address)
{	uchar m ;	
	if ( E_address(address)) // 从指定的地址开始读取数据 //
	  {  I_start();      	  // 发送重复启动信号//
		if(I_send( READ)) 
		  {	
             m=(I_receive());
			   return(m);				
		  }		
		else {
			I_stop() ;
			return (0) ;
		    }
	}
	else
	   {  I_stop() ;
		  return (0) ;
	   }
}
*/
/****************************************************************************
*    函数原型: void wait_5ms(void);
*    功    能: 提供5ms延时(时钟频率为12MHz)。
*****************************************************************************/
void wait_5ms( void ) 
{	int i;
	for(i=0;i<1000;i++) 
	{	
	;
	}
}

/****************************************************************************
*    函数原型: bit E_write_onedata(uchar address,uchar i_data );
*    功    能: 将数据i_data写入到24C01的address地址中
*               成功写入返回1( TRUE ), 否则返回0(FALSE)
*****************************************************************************/
/*
bit E_write_onedata(uchar address,uchar i_data )
{
  if(E_address(address) &&I_send( i_data ) )  
	 {	
      I_stop() ;
	  wait_5ms();
	  return(TRUE);
	 }
 else
	{return(FALSE);}
}
*/
/****************************************************************************
*    函数原型: uchar E_read_datablock(uchar address,uchar length);
*    功    能: 从24C01中以指定的地址address为首地址读取length个长度的数据
*                放到由指针p指定内部存储器(的数组变量)中 ,读取成功返回1,否则返回0。 
*                          
*****************************************************************************/

bit E_read_datablock(uchar address,uchar length,uchar *p)
{	uchar i ;	
	if (E_address(address) ) //从地址address开始读取数据//
	{	////只指定了一个起始地址为首址,顺序读取数据///////
	  I_start() ;  // 发送重复启动信号 //
		if(I_send(READ)) 
		 {
           for(i=0;i<=length;i++) 
			  {
                p[i] = (I_receive()) ;
				if (i !=length) I_Ack() ;//每读取一个数据后要有一个Ack信号/////
				else 
                  {
				   I_clock();/////不给Ack信号,准备结束传输/////
				   I_stop();
				   }
			  }
		   return (TRUE);
		}
	 else {
			I_stop() ;
			return (FALSE);
	      }
    }
  else I_stop() ;		
return (FALSE);
}


/****************************************************************************
*    函数原型:bit E_write_datablock(uchar address,uchar length,uchar *p);
*    功    能: 写入数据到24C01的以address为首址length个存储器中,数据来源 
*              由指针p指定内部RAM(数组)中的数据,成功写入返回1( TRUE ), 
*              否则返回0(FALSE)
*****************************************************************************/
bit E_write_datablock(uchar address,uchar length,uchar *p)
{	uchar i ;
	for(i=0;i<=length;i++) 
	{	if(E_address(address+i)&&I_send(*(p+i)))
    ////指定一个地址。写一个数据//////
		{	I_stop() ;
			wait_5ms();
		}
		else
			return (FALSE);
	}
	return (TRUE);
 }


⌨️ 快捷键说明

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