版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_17017545/article/details/82356450
EEPROM概述
电可擦除只读存储器 EEPROM 可以长期非易失地保存信息,又可以随时用电改写。EEPROM的种类很多,它们大致可以分为并行、串行、加密型3种。
- 并行 EEPROM:速度快,可做到高度集成。但是引脚多,使用不方便。
- 串行 EEPROM:引脚少,应用方便。但结构复杂,难以做到了高度集成,所以单片机一般容量不大。
- 加密型 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);
}
}