贰拾壹:EEPROM的操作

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_17017545/article/details/82356450

EEPROM概述

电可擦除只读存储器 EEPROM 可以长期非易失地保存信息,又可以随时用电改写。EEPROM的种类很多,它们大致可以分为并行、串行、加密型3种。

  1. 并行 EEPROM:速度快,可做到高度集成。但是引脚多,使用不方便。
  2. 串行 EEPROM:引脚少,应用方便。但结构复杂,难以做到了高度集成,所以单片机一般容量不大。
  3. 加密型 EEPROM:可以对写入的数据进行加密,避免越权存取,保密功能强。但加密型EEPROM的操作步骤比较复杂,成本高。

这里写图片描述

通信时序

这里写图片描述
1.起停信号
时钟线保持高电平期间,数据线电平从高到低的跳变为I2C总线的起始信号。时钟线保持高电平期间,数据线电平从低到高的跳变为I2C总线的停止信号。
2.设备选址
主器件通过发送1个起始信号启动发送过程,然后发送它所需要寻址的从器件地址,8位从器件地址的高4位固定为1010,接下来的3位(A10,A9,A8)为器件的地址位。
3.应答信号
I2C总线传送数据时,每成功传送1Byte,接收器都必须产生1个应答信号,应答的器件在第9个时钟周期将SDA线拉低表示其已收到1个8位数据。

写操作

1.字节写
这里写图片描述

2.页写(一页,即16Byte,16个字节)
这里写图片描述

读操作

1.从当前地址读
这里写图片描述
2.随机地址读
这里写图片描述

实验

这里写图片描述
#代码

	
*   【课程22】 ****EEPROM的读写***********
*
*   【说  明】 ****使用CAT24WC16芯片,掉电数据非易失
*		
*   【描  述】 ****往CAT24WC16芯片写入一个数据后,然后再从同一个
				地址取出数据,看两个数据是否相等?
*
******************************************************************/

#include<reg52.h>
#include <intrins.h>

//---------常用的两个宏定义-------------- 
#define uint8	unsigned char
#define uint16  unsigned int


/*--24WC16功能引脚设置-----*/
sbit  WC16_SCL=P2^2;
sbit  WC16_SDA=P2^3;


/********************************************************
** 名称 :void DelayMS(uint16 dly)
** 功能 :毫秒级延时(24M的晶振)
** 入口参数 :dly
					用户的延时参数   
** 出口参数 :无   
*********************************************************/
void DelayMS(uint16 dly)
{
	uint16 x,y;
	for(x=dly;x>0;x--)
		for(y=247;y>0;y--);
}


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

功能:短延时函数,保持时钟的电平信号
*********************************************/
void nNop()
{
	uint8 i;
	for(i=0;i<15;i++);
}

/********************************************
函数名:IIC_Start()
功能:总线协议的起始信号
备注:Scl=1期间,数据线(Sda)电平从高到低的跳
			变作为I2C 总线的起始信号
**********************************************/
void IIC_Start()
{	   	
	WC16_SDA=1;
	nNop();
	WC16_SCL=1;
	nNop();
	WC16_SDA=0;
	nNop();
	WC16_SCL=0;
}

/********************************************
函数名:IIC_Stop()
功能:总线协议的停止信号 
备注:Scl=0期间,数据线(Sda)电平从低到高的跳
		变作为I2C 总线的停止信  号        
**********************************************/
void IIC_Stop()
{
	 WC16_SDA=0;
	 nNop();
	 WC16_SCL=1;
	 nNop();
	 WC16_SDA=1;
	 nNop();
}


/********************************************
函数名:WC16Data_Write(uint8 temp)
功能:总线写数据.地址函数         
入口参数:temp 为要写的数据或地址    
**********************************************/
void WC16Data_Write(uint8 temp)
{
	 uint8 i;
	 WC16_SCL=0;
	 for(i=0;i<8;i++)
		{
		 	WC16_SDA=(bit)(temp&0x80);  //实现从高位到低位传递  
		 	temp=temp<<1;
		 	nNop();
		 	WC16_SCL=1;
		 	nNop();
		 	WC16_SCL=0;
		}
	 nNop();
	 WC16_SCL=1;
	 while(WC16_SDA);  //当WC16_SDA 为低时为 从机的应答信号 
	 nNop();
	 WC16_SCL=0;
}



/********************************************
函数名: WC16Data_Read(void)
功能:总线读数据函数      
出口参数:temp 为要读的数据  
**********************************************/

 WC16Data_Read(void)
{
	 uint8 i,temp=0;
	 for(i=0;i<8;i++)
	{
		 WC16_SCL=0;
		 WC16_SDA=1;
		 nNop();
		 WC16_SCL=1;
		 nNop();
		 temp=(temp<<1)|WC16_SDA;	//八次循环读出EEPROM中的数,放入temp变量中
	}
	WC16_SCL=0;
	nNop();
	WC16_SDA=1;   //读完数据后主机发给从机的非应答信号 
	nNop();
	WC16_SCL=1;
	WC16_SCL=0;
	return(temp);
}
/********************************************
函数名:WC16Data_Put(uint8 sla,uint8 slaaddr,uint8 Data) 
功能:按照总线协议,  单片机将数据写进rom指定地址
入口参数:uint8 sla
		  uint8 slaaddr
	  	  uint8 Data
出口参数:无
**************************************************/
WC16Data_Put(uint8 sla,uint8 slaaddr,uint8 Data)
{
	 IIC_Start();
	 WC16Data_Write(sla);  //sla为 从地址+R/W 
	 WC16Data_Write(slaaddr);// slaaddr为从地址
	 WC16Data_Write(Data);  //Data为要写的数据
	 IIC_Stop();
}


/********************************************
函数名:WC16Data_Rev(uint8 sla,uint8 slaaddr,uint8 Data) 
功能:按照总线协议,单片机在指定地址读数据
入口参数:uchar sla   
		  uchar slaaddr
出口参数:无
**************************************************/
WC16Data_Rev(uint8 sla,uint8 slaaddr)
{
	 uint8 temp;
	 IIC_Start();
	 WC16Data_Write(sla);
	 WC16Data_Write(slaaddr);
	 IIC_Start();
	 WC16Data_Write(sla+1);
	 temp=WC16Data_Read();
	 IIC_Stop();
	 return(temp);
}

void  main()
{
	uint8 temp=0;
	WC16_SDA=1;   //对两功能引脚进行初始化
	WC16_SCL=1;
	WC16Data_Put(0xa0,0x00,0x55);
	DelayMS(50);				//此延时非常重要,数据写进EEPROM后要延迟一段时间才能进行读。
	temp=WC16Data_Rev(0xa0,0x00);
	while(1)
	{		
		P0 = temp;
		DelayMS(5000);
	}
}

猜你喜欢

转载自blog.csdn.net/qq_17017545/article/details/82356450