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

📄 e2prom.c

📁 一个27k的小程序24cxx.exe,这款程序不大,功能却不逊色于某些大型软件,搽读写校样样都能,最大的优点就是速度奇快,完全可以作为量写的工具
💻 C
字号:
/*------------------------------------------------------------------------------
〖说明〗24Cxx I2C EEPROM字节读写驱动程序,芯片A0-A1-A2要接GND(24C65接VCC,具体看DataSheet)。
现缺页写、页读,和CRC校验程序。以下程序经过50台验证,批量的效果有待考察。
为了安全起见,程序中很多NOP是冗余的,希望读者能进一步精简,但必须经过验证。
Atmel 24C01 比较特殊,为简约型,为其单独编程.
51晶振为11.0592MHz
〖文件〗RW24CXX.c 2001/09/18
〖作者〗梁眼龙
〖信箱〗jcwhit@263.net
〖参考〗http://www.c51bbs.com
〖版本〗V1.00A Build 0918
--------------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------------------------------------------
调用方式:void WriteIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address,unsigned char ddata) ﹫2001/09/18
函数说明:对于IIC芯片24CXX,在指定地址address写入一个字节ddata<
/P><P>调用方式:unsigned char ReadIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address) ﹫2001/09/18
函数说明:读取IIC芯片24CXX,指定地址address的数据。
-----------------------------------------------------------------------------------------------------------------*/
#include <reg52.h>
#include <intrins.h>

sbit D1= P0^4;
sbit SCL= P1^0;
sbit SDA= P1^1;
enum EEPROMTYPE {IIC24C01,IIC24C01A,IIC24C02,IIC24C04,IIC24C08,IIC24C16,IIC24C32,IIC24C64,IIC24C128,IIC24C256};
enum EEPROMTYPE eepromtype;

delay()
{
unsigned int i=1200;
while(i--);
}

/*----------------------------------------------------------------------------
调用方式:write_8bit(unsigned char ch) ﹫2001/03/23
函数说明:内函数,私有,用户不直接调用。
-------------------------------------------------------------------------------*/
void write_8bit(unsigned char ch)
{
	unsigned char i=8;

	SCL=0;
	_nop_();_nop_();_nop_();_nop_();_nop_();
	while (i--)
	{
		SDA=(bit)(ch&0x80);
		_nop_();_nop_();_nop_();_nop_();_nop_();
		ch<<=1;
		SCL=1;
		_nop_();_nop_();_nop_();_nop_();_nop_();
		SCL=0;
		_nop_();_nop_();_nop_();_nop_();_nop_();
	}
	_nop_();_nop_();_nop_();_nop_();_nop_();
	_nop_();_nop_();_nop_();_nop_();_nop_();
}

/*------------------------------------------------------------------------------
调用方式:void ACK(void) ﹫2001/03/23
函数说明:内函数,私有,用户不直接调用。
-------------------------------------------------------------------------------*/
void ACK(void)
{
	unsigned char time_1;

	SDA=1;
	SCL=0;
	_nop_();_nop_();_nop_();_nop_();_nop_();
	SCL=1;
	time_1=5;
	while(SDA) {if (!time_1) break;} //ACK
	SCL=0;
	_nop_();_nop_();_nop_();_nop_();_nop_();
}

void WriteIIC_24C01(unsigned char address,unsigned char ddata)
{
	SCL=1;
	_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); //Tsu:STA
	SDA=0;
	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA
	SCL=0; //START
	write_8bit( (address<<1) & 0xfe); //写页地址和操作方式,对于24C32-24C256,page不起作用
	ACK();
	write_8bit(ddata); //发送数据
	ACK();
	SDA=0;
	_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	SDA=1; //STOP
	delay();
}

/*---------------------------------------------------------------------------------------------------------------
调用方式:void WriteIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address,unsigned char ddata) ﹫2001/09/18
函数说明:对于IIC芯片24CXX,在指定地址address写入一个字节ddata
-----------------------------------------------------------------------------------------------------------------*/
void WriteIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address,unsigned char ddata)
{ 
	unsigned char page,address_in_page;
	if(eepromtype==IIC24C01) //如果是24c0
	{
		WriteIIC_24C01(address,ddata);
		return;
	}
	page=(unsigned char)(address>>8) & 0x07;
	page=page<<1;
	address_in_page=(unsigned char)(address);
	SCL=1;
	_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); //Tsu:STA
	SDA=0;
	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA
	SCL=0; //START
	write_8bit(0xa0 | page); //写页地址和操作方式,对于24C32-24C256,page不起作用
	ACK();
	if(eepromtype>IIC24C16) //如果是24C01-24C16,地址为一字节;24C32-24C256,地址为二字节
	{
		write_8bit(address>>8);
		ACK();
	}
	write_8bit(address_in_page);
	ACK();
	write_8bit(ddata);
	ACK();
	SDA=0;
	_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	SDA=1; //STOP
	delay();
}

unsigned char ReadIIC_24C01(unsigned char address)
{
	unsigned char ddata=0;
	unsigned char i=8;
	
	SCL=1;
	_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); //Tsu:STA
	SDA=0;
	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA
	SCL=0; //START
	write_8bit( (address<<1) | 0x01); //写页地址和操作方式
	ACK();
	while (i--)
	{
		SDA=1;
		ddata<<=1;
		SCL=0;
		_nop_();_nop_();_nop_();_nop_();_nop_();SCL=1;
		if (SDA) 
			ddata|=0x01;
	}
	SCL=0;
	_nop_();
	SCL=1;
	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	SDA=0;
	_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	SDA=1; //STOP
	delay();
	return ddata;
}

/*----------------------------------------------------------------------------------------------------
调用方式:unsigned char ReadIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address) ﹫2001/09/18
函数说明:读取IIC芯片24CXX,指定地址address的数据。
------------------------------------------------------------------------------------------------------*/
unsigned char ReadIIC_24CXX(enum EEPROMTYPE eepromtype,unsigned int address)
{ 
	unsigned char page,address_in_page;
	unsigned char ddata=0;
	unsigned char i=8;

	if(eepromtype==IIC24C01)
	{
		return( ReadIIC_24C01(address) );
	}
	page=(unsigned char)(address>>8) & 0x07;
	page=page<<1;
	address_in_page=(unsigned char)(address);
	SDA=0;
	_nop_();
	SCL=0; //START
	write_8bit(0xa0 | page); //写页地址和操作方式,对于24C32-24C256,page不起作用
	ACK();
	if(eepromtype>IIC24C16) //如果是24C32-24C256,地址为二字节,先送高位,后送低位
	{
		write_8bit(address>>8);
		ACK();
	}
	//如果是24C01-24C16,地址为一字节;
	write_8bit(address_in_page);
	ACK();//以上是一个“哑”写操作,相当于设置当前地址</P><P> SCL=1;
	SCL=1;
	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Tsu:STA
	SDA=0;
	_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA
	SCL=0; //START
	write_8bit(0xa1); //写从地址,置为读模式
	ACK();
	while (i--)
	{
		SDA=1;
		ddata<<=1;
		SCL=0;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=1;
		if (SDA) 
			ddata|=0x01;
	}
	SCL=0;
	_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	SDA=0;
	_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
	SDA=1; //STOP
	delay();
	return ddata;
}

/*分析:
该芯片采用传统的IIC口的规约形式,是一个标准的经典IIC封装。
注:使用该程序时注意改变芯片各个接口的修改。注意屏蔽主函数。 
*/

main()
{
	unsigned int i;
	unsigned char kk,j[32];
	
	D1 = 1;

	delay();
//	kk=ReadIIC_24C01(12);
	kk = ReadIIC_24CXX(IIC24C16,12);
	D1 = 0;
//	WriteIIC_24C01(12,0x67);
	WriteIIC_24CXX(IIC24C16,12,0x55);
//	kk=ReadIIC_24C01(12);
	kk = ReadIIC_24CXX(IIC24C16,12);
	if (kk == 0x55)
		D1 = 0;
	else
		D1 = 1;
/*	for(i=0;i<32;i++) 
		j[i]=ReadIIC_24CXX(IIC24C01,i);
	for(i=0;i<32;i++) 
		j[i]=i*2;
	for(i=0;i<32;i++) 
		WriteIIC_24CXX(IIC24C01,i,0x55);
	for(i=0;i<32;i++) 
		j[i]=0;
	for(i=0;i<32;i++) 
		j[i]=ReadIIC_24CXX(IIC24C02,i);*/
}

⌨️ 快捷键说明

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