`

硬件和软件兼容i2c协议的24Cxx系列EEPROM存储器

阅读更多

硬件上由于24c01的A0A1A2管脚不允许悬空,故暂时的想法是兼容24c02 ---24c16

使用一个dip8封装的芯片插座,A0 A1 A2管脚都悬空即可,换芯片方便

软件上24c02地址只有8位,而其他型号是大于8位的,故地址参数使用16位

256个字节作为一个大页,即largePage,测试芯片24c04空间有512字节

 

上代码,求测试和讨论

#include "MY51.H"
//转载请注明:http://xouou.iteye.com  求测试讨论
//stc89c52rc,11.0592MHz晶振
sbit sda=P2^0;		//总线连接口定义
sbit scl=P2^1;		//总线连接口定义

void delayus() 		//需要4个机器周期,大概4.34us
{
	;				//晶振频率11.0592M,机器周期为1.085微秒
}

void iic_start()  	//启动信号
{
	sda=1;
	scl=1;
	delayus();		//sda和scl同为高电平保持4.7us以上
	_nop_();		//1.085us,共5.78us
	sda=0; 			//下降沿
	delayus();		//sda低电平保持4us以上	,这里是4.34us满足要求
}

void iic_stop()		//停止信号
{
	sda=0;_nop_();	//准备状态
	scl=1;
	delayus();		//该状态稳定时间要求保持4us以上
	sda=1;			//scl高电平期间,sda来一个上升沿
	delayus();		//sda保持4.7us以上,4.34加上函数返回时间大于4.7us
					//注:此时scl和sda都为1	
}

void iic_sendByte(u8 byteData) //mcu发送一个字节
{
	u8 i;
	u8 temp=byteData;
	for(i=0;i<8;i++)
	{
		temp=temp<<1;    //移动后最高位到了PSW寄存器的CY位中
		scl=0;			 //准备
		_nop_();		 //稳定一下
		sda=CY;			 //将待发送的数据一位位的放到sda上
		_nop_();
		scl=1;    		 //每一个高电平期间,ic器件都会将数据取走
		_nop_();		
	}

	scl=0;				 //如果写成scl=1;sda=1就是停止信号,不能这么写
	_nop_();				
	sda=1;				 //释放总线,数据总线不用时要释放
	_nop_();
}

u8 iic_readByte() 			//读一个字节
{
	u8 i,temp;
	scl=0;					//准备读数据
	_nop_();
	sda=1;					//释放总线
	_nop_();

	for(i=0;i<8;i++)
	{
		scl=1;				//mcu开始取数据
		delayus();			//scl为高电平后,ic器件就会将1位数据送到sda上
							//总共用时不会大于4.34us,然后就可以让mcu读sda了
		temp=(temp<<1)|sda; //读一位保存到temp中
		scl=0;
		delayus();		
	}
	return temp;
}

bool iic_checkACK()		  //处理应答信号
{
	u8 errCounts=255; 	  //定义超时量为255次
	scl=1;
	_nop_();
	
	while(sda)			  //在一段时间内检测到sda=0的话认为是应答信号
	{	
		if(0==errCounts)
		{
			scl=0;		  //钳住总线
			_nop_();
			return FALSE; //没有应答信号
		}
		errCounts--;
	}

	scl=0;			     //钳住总线,为下1次通信做准备 
	_nop_();
	return TRUE;	     //成功处理应答信号
}

void iic_init()		     //总线初始化
{
	scl=1;
	sda=1;
	delayus();
}

void iic_sendACK(bool b_ACK)  //发送应答或非应答信号
{
	scl=0;			//准备
	_nop_();

	if(b_ACK)		//ACK	发送应该信号
	{
		sda=0;
	}
	else			//unACK	发送非应答信号
	{
		sda=1;
	}

	_nop_();
	scl=1;
	delayus(); 		//大于4us的延时
	scl=0;  	  	//钳住scl,以便继续接收数据	
	_nop_();
}

void AT24Cxx_writeByte(u16 address,u8 dataByte)//向24cxx写一字节数据
{
	u8 largePage     = address/256;	  //24c04是512字节(寻址范围0~511),largePage最大值是1
	u8 addressOffset = address%256;   //largePage=0的话地址范围是(0~255)
	iic_start();
	iic_sendByte(0xa0|(largePage<<1));//控制字,前4位固定1010,后三位是器件地址,末位0是写
	iic_checkACK();		    		  //mcu处理应答信号
	iic_sendByte(addressOffset);  	  //指定要写入的器件内地址在	largePage块中的偏移
	iic_checkACK();
	iic_sendByte(dataByte); 		  //写数据
	iic_checkACK();
	iic_stop();
	delayms(2);	
	//按字节写入时,24cxx在接收到停止信号后将数据擦写到内部,这需要时间
	//并且在这段时间内不会响应总线上的任何请求,故让mcu有2毫秒以上的等待	
}

void AT24Cxx_writeData(u16 address,u8 numBytes,u8* buf)//写入任意长度数据(最大256字节)
{
	while(numBytes--)
	{
		AT24Cxx_writeByte(address++,*buf++);
	}
}

void AT24Cxx_readData(u16 beginAddr,u8 dataSize,u8* buf)//读取任意长度字节到缓冲区buf中
{
	u8 largePage     = beginAddr/256;	//计算largePage,256字节为一大页
	u8 addressOffset = beginAddr%256;	//计算相对于largePage的偏移
	iic_start();				  		//起始信号
	iic_sendByte(0xa0|(largePage<<1));	//控制字,写
	iic_checkACK();						//处理应答信号
	iic_sendByte(addressOffset);		//要读取的目标地址偏移
	iic_checkACK();						//处理应答信号	
	iic_start();			   			//发送起始信号
	iic_sendByte(0xa1|(largePage<<1));	//控制字,读
	iic_checkACK();						//处理应答信号
	while(dataSize--)					//读取dataSize个字节,最大256个字节
	{									//dataSize用u16类型会暴掉ram的
		*buf++=iic_readByte();			//读取一个个字节并保存到缓冲区buf中
		iic_sendACK(dataSize);  		//发送应答,当dataSize为0时mcu发送非应答
	}
	iic_stop();							//发送停止信号
}



void main()//测试
{
	u8 buf[3];										//接受数据的缓冲区
	u8 arr[7]={0x06,1,2,3,4,0x55,0x33};				//待写入的数据
						
	iic_init();										//总线初始化
	AT24Cxx_writeData(0x00+256,sizeof(arr),arr);	//向指定地址处开始写入7字节的数据

	P1=0xff; 										//调试代码,用P1口的led显示
	delayms(1000);			 						//调试代码

	AT24Cxx_readData(0x00+256,sizeof(buf),buf);   	//从指定地址开始读3个字节
	P1=buf[2];	//也就是2									//led灯显示数值
											
	while(1)
	{
		P1=~P1;
		delayms(500);		
	} 
}


 

//my51.h中主要用到
#include <reg52.h>

#include "mytype.h"

void delayms(u16 ms)     //软延时函数
{
	u16 i,j;
	for(i=ms;i>0;i--)
	{
        for(j=113;j>0;j--)
        {}
	}
}

 

对代码进行了改进 
去掉了在写数据时的 
delayms(2);
这句软延时代码低效 ,而且没有保障 

改成加一个检测函数 
bool check_icWriteComplete()   //检测eeprom是否对内部擦写完成 
{ 
 iic_start(); 
 iic_sendByte(0xa0); 
 return iic_checkACK(); 
}

 

0
1
分享到:
评论

相关推荐

    24CXX系列EEPROM 51单片机读写程序

    I2C协议规定了起始信号、停止信号、地址帧、数据帧和应答位的格式,确保了主设备(51单片机)和从设备(24CXX EEPROM)之间的有效通信。 实现24CXX系列EEPROM的读写,首先需要在51单片机的程序中设置I2C总线的初始...

    AT24CXX和FM24CXX等eeprom的驱动程序

    AT24CXX和FM24CXX系列的EEPROM是常见的非易失性存储器,广泛应用于嵌入式系统、物联网设备以及各种需要长期存储数据的电子设备中。这两款EEPROM的主要功能是存储数据,即使在断电的情况下也能保持数据完整性。下面将...

    AT24CXX系列EEPROM应用笔记

    AT24CXX系列EEPROM是由Microchip公司生产的串行CMOS EEPROM,支持I2C总线数据传输协议。该系列EEPROM的主要特点包括: - 支持多种工作电压范围:4.5V至5.5V、2.7V至5.5V、2.5V至5.5V及1.8V至5.5V。 - 低功耗设计,...

    彩电存储器读写软件24CXX

    24CXX系列的存储器是广泛应用于彩电的一种I2C(Inter-Integrated Circuit)接口的串行EEPROM(Electrically Erasable Programmable Read-Only Memory)。本文将详细介绍这种存储器以及与其相关的W24CXX软件,帮助...

    cat24wcxx.zip_24C _24CXX_i2c_serial eeprom

    在电子工程领域,24CXX系列I2C串行EEPROM是一种广泛应用的非易失性存储器,广泛用于各种嵌入式系统和微控制器应用中。本文将详细探讨24CXX系列EEPROM的特性、工作原理以及如何通过I2C接口进行通信。 24CXX系列是由...

    I2C.rar_I2C proteus_hex 24CXX_i2c_i2c 单片机_proteus i2c

    标题"I2C.rar_I2C proteus_hex 24CXX_i2c_i2c 单片机_proteus i2c"所提及的核心内容是关于I2C通信协议的应用,特别是通过单片机与24CXX系列的I2C EEPROM进行数据交互,并且在Proteus软件中进行了仿真验证。24CXX系列...

    STM8S-_I2C读写EEPROM(硬件).zip

    常见的I2C EEPROM有24CXX系列,其中XX表示存储容量,例如24C02(2Kbit),24C04(4Kbit),24C08(8Kbit)等。这些设备具有标准的7位或10位I2C地址,并且可以以字节为单位进行读写操作。 三、STM8S与EEPROM的连接 ...

    24CXX.zip_24C02 24C256 兼容_24C02 stm32_24CXX stm32_STM32 24C02_s

    它具有丰富的外设接口,包括I2C,这使得STM32能够轻松地与24CXX系列的EEPROM通信。 在描述中提到的"基于STM32芯片的24C02~24C256驱动程序,测试过可用",意味着这个压缩包包含了为STM32编写的源代码,用于驱动这两...

    24CXX的存储器51驱动程序

    《24CXX系列EEPROM在51单片机中的驱动程序详解》 在电子工程领域,24CXX系列的EEPROM(电可擦除可编程只读存储器)常用于51单片机...这不仅涉及到硬件接口的设置,还涵盖了软件层面的I2C通信协议理解和驱动程序设计。

    24CXX串行EEPROM测试方式

    24CXX系列EEPROM遵循I²C总线协议,这是一种二线串行接口协议,通过SCL(时钟线)和SDA(数据线)进行通信。在SCL线处于高电平时,SDA线的下降沿标志通信开始,上升沿则表示通信结束,确保了数据传输的准确性和可靠...

    24CXX 93CXX 读写电路和读写软件

    24CXX和93CXX系列是I2C接口的电可擦可编程只读存储器(EEPROM),常用于数据存储,如设置参数、配置信息等。I2C是一种多主机、二线制的串行总线协议,由飞利浦(现为恩智浦半导体)开发,适用于低速、短距离通信。 ...

    STM32硬件I2C读写AT24Cxx

    STM32是一款广泛应用的微控制器,它具有内置的硬件I2C接口,可以方便地与各种外围设备进行通信,如AT24Cxx系列的I2C接口EEPROM。AT24Cxx是一组不同容量的电可擦可编程只读存储器(EEPROM),在嵌入式系统中常用于...

    AT24CXX存储器资料

    `AT24C01~24C256+++I2C中文资料(1).pdf`这份文档很可能是详细的AT24CXX系列的中文技术手册,包含原理介绍、电气特性、操作指南和应用实例等内容。通过阅读这份文档,开发者可以深入理解器件的工作原理,学习如何...

    I2C_.rar_24CXX

    总结来说,理解I2C协议和24CXX系列EEPROM的工作原理,能够帮助我们有效地进行数据的存储和读取。在实际项目中,正确配置地址线,编写可靠的I2C通信代码,是确保系统正常运行的关键。通过不断实践和调试,我们可以...

    i2ceeprom_24CXX_i2ceepromavr_AVRI2C_

    描述中提到的"AVR i2c/twi 24CXX eeprom libs"表明,这个项目提供了AVR微控制器通过I²C(Inter-Integrated Circuit,也称为TWI,Two-Wire Interface)总线与24CXX系列EEPROM进行通信的库文件。TWI是Atmel(现为...

    I2C.zip_H83_i2c_i2c eeprom

    标题"I2C.zip_H83_i2c_i2c eeprom"表明这是一个关于I2C通信协议和I2C EEPROM的教程或代码库,适用于H83系列微控制器。描述中提到"LPC2148 I2C",意味着内容可能涉及到基于Philips LPC2148微控制器的I2C接口实现,LPC...

    24CXX存储器读写软件及制作

    总结来说,24CXX系列存储器的读写软件制作涉及理解I²C通信协议、选择合适的编程语言和库、编写控制代码以及解决可能出现的问题。通过熟练掌握这些知识,你可以设计出能够高效读写24CXX存储器的软件,为各种电子项目...

    CH341的24,25系列存储器读写软件

    24和25系列存储器通常指的是I2C或SPI接口的EEPROM,例如24Cxx系列(I2C)和25xx系列(SPI)。这些器件有不同容量,如24C02(2Kb),24C04(4Kb),25L1606E(16Mbit)等,适用于存储小量数据,如配置参数、固件版本...

    EEPROM 24CXX 驱动

    8. **示例代码**:`I2C_EEPROM通用程序`这个文件很可能是包含I²C通信协议的示例代码,用于演示如何读写24CXX系列的EEPROM。代码中应该包含了初始化I²C、发送读写命令、处理响应等功能的实现。 理解并掌握以上知识...

    24CXX读写软件

    标题中的“24CXX读写软件”指的是用于读取和写入24CXX系列电可擦可编程只读存储器(EEPROM)的工具。24CXX系列是I2C通信协议下的器件,广泛应用在电子设备中,如嵌入式系统、智能家居、仪器仪表等,用于存储配置信息...

Global site tag (gtag.js) - Google Analytics