基于51单片机的EEPROM读写

本讲内容:

      对存储器的基本知识进行介绍。介绍EEPROM芯片AT24C02;通过例程展示EEPROM的读写。

      存储器是应用于各种嵌入式场合的存储部件,按功能可分为只读存储器(ROM)和随机存取存储器(RAM)两大类,分别用作固定数据存储和临时数据缓存。

RAM(Random Access Memory),随机存取存储器:

      RAM的特点是:上电运行时,操作系统和应用程序的所有正在运行的数据和程序都会放置其中,并且随时可以对存放在里面的数据进行修改和存取。它的工作需要由持续的电力提供,一旦系统断电,存放在里面的所有数据和程序都会自动清空掉,并且再也无法恢复。

使用得比较多的RAM种类有: 

DRAM(Dynamic RAM,动态随机存取存储器):

      这是最普通的RAM,一个电子管与一个电容器组成一个位存储单元,DRAM将每个内存位作为一个电荷保存在位存储单元中,用电容的充放电来做储存动作,但因电容本身有漏电问题,因此必须每几微秒就要刷新一次,否则数据会丢失。存取时间和放电时间一致,约为2~4ms。因为成本比较便宜,通常都用作计算机内的主存储器。

SRAM(Static RAM,静态随机存取存储器):

      静态,指的是内存里面的数据可以长驻其中而不需要随时进行存取。每6颗电子管组成一个位存储单元,因为没有电容器,因此无须不断充电即可正常运作,因此它可以比一般的动态随机处理内存处理速度更快更稳定,往往用来做高速缓存。

SDRAM(Synchronous DRAM,同步动态随机存取存储器):

       这是一种与CPU实现外频Clock同步的内存模式,工作电压为3.3V。 所谓clock同步是指内存能够与CPU同步存取资料,这样可以取消等待周期,减少数据传输的延迟,因此可提升计算机的性能和效率。

DDR SDRAM(Double Data Rate二倍速率同步动态随机存取存储器):

      作为SDRAM的换代产品,它具有两大特点:

      其一,速度比SDRAM有一倍的提高;

      其二,采用了DLL(Delay Locked Loop:延时锁定回路)提供一个数据滤波信号。这是目前内存市场上的主流模式。

只读存储器(read-only memory --- ROM)可以分为以下两大类:

     (1)掩模编程ROM,它所存储的固定逻辑信息是由生产厂家通过光刻掩模版来决定的。

     (2)现场可编程ROM(programmable read-only memory)。

        a:PROM(可编程ROM)。此类ROM通常采用溶丝结构,用户可根据编程的需要,把无用的溶丝烧断来完成编程工作(即把信息写入到存储器中)。但一旦编程完毕,就无法再变更,故用户只可编程(写)一次。

        b:EPROM(可擦除可编程ROM-erasable programmable read only memory)。

此类ROM存储单元中存贮信息的管子采用浮栅结构,可用紫外线或X-射线把原来存的信息一次全部擦除。

        c:EEPROM(电可擦除可编程ROM,也叫E2PROM-electrically erasable programmable read only memory)。

        d: Flash Memory(快闪存储器)

这是一种可以直接在主机板上修改内容而不 需要将IC拔下的内存,当电源关掉后储存在里面的资料并不会流失掉,在写入资料时必须先将原本的资料清除掉,然后才能再写入新的资料,缺点为写入资料的速度太慢。

EEPROM芯片AT24C02介绍:

 

 

例程:

/*****************EEPROM读写*******************

*单片机型号:STC89C52RC

*开发环境:KEIL

*功能:向IIC总线器件24c02EEPROM中地址为1的存储单元中写入数据50

            并将其读出,显示于数码管上。   

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

#include<reg51.h>

#define uint unsigned int

#define uchar unsigned char

sbit sda=P2^0;sbit scl=P2^1;sbit LE1=P2^6;sbit LE2=P2^7;sbit LED=P1^0;

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,

0x5e,0x79,0x71};

void delay1(uint z)

{

 uchar x,x1;

 for(;z>0;z--)

 {for(x=0;x<114;x++){for(x1=0;x1<1;x1++);}}

}

void delay_5us()

{

 int i;

 for(i=0;i<1;i++){;}

}

void delay(int In,int Out)                                                                                          //定义延时函数 

{

 int i,j;

 for(i=0;i<In;i++)

 {for(j=0;j<Out;j++){;}}

}

void star()

{

 sda=1;delay_5us();

 scl=1;delay_5us();

 sda=0;delay_5us();

}

void stop()

{

 sda=0;delay_5us();

 scl=1;delay_5us();

 sda=1;delay_5us();

}

void ack()

{

 uchar z=0;

 while((sda==1)&&(z<50))z++;

 scl=0;

 delay_5us();

}

void write(uchar slave_write_address,uchar byte_address,uchar data_data)

{

 uchar temp,temp1,i,ii;

 star();

 for(ii=0;ii<3;ii++)

 {

  if(ii==0)

  {temp=slave_write_address;temp1=slave_write_address;}

  else if(ii==1)

  {temp=byte_address;temp1=byte_address;}

  else if(ii==2)

  {temp=data_data;temp1=data_data;}

  for(i=0;i<8;i++)

  {

   scl=0;

   delay_5us();

   temp=temp1;

   temp=temp&0x80;

   if(temp==0x80)sda=1;

   else sda=0;

   delay_5us();

   scl=1;delay_5us();

   scl=0;delay_5us();

   temp1=temp1<<1;

  }

  sda=1;delay_5us();

  scl=1;delay_5us();

  ack();

 }

 stop();

}

uchar read(uchar slave_write_address,uchar byte_address,uchar slave_read_address)

{

 uchar temp,temp1,i,ii,x,data_data;

 star();

 for(ii=0;ii<3;ii++)

 {

  if(ii==0)

  {temp=slave_write_address;temp1=slave_write_address;}

  else if(ii==1)

  {temp=byte_address;temp1=byte_address;}

  else if(ii==2)

  {star();temp=slave_read_address;temp1=slave_read_address;}

  for(i=0;i<8;i++)

  {

   scl=0;delay_5us();

   temp=temp1;temp=temp&0x80;

   if(temp==0x80)sda=1;

   else sda=0;

   delay_5us();

  

   scl=1;delay_5us();

   scl=0;delay_5us();

   temp1=temp1<<1;

  }

  sda=1;delay_5us();

  scl=1;delay_5us();

  ack();

  }

  for(x=0;x<8;x++)

  {

   data_data=data_data<<1;

   sda=1;delay_5us();

   scl=0;delay_5us();

   scl=1;delay_5us();

   if(sda==1)data_data|=0x01;

  }

  ack();

  stop();

  return data_data;

}

                      

void display(uchar a,uchar b)

{

 LE1=0;

 P0=table[a];LE1=1;LE1=0;       //显示百位

 LE2=0;

 P0=0xfe;LE2=1;LE2=0;

 delay(5,100);

 LE1=0;

 P0=table[b];LE1=1;LE1=0;       //显示十位

 LE2=0;

 P0=0xfd;LE2=1;LE2=0;

 delay(5,100);

}

void main()

{

 unsigned char num;

 unsigned char buffer;

 unsigned char a,b;

 num = 0x32;

 loop1:write(0xa0,0x01,num);

 delay1(20);

 buffer=read(0xa0,0x01,0xa1);

 delay1(20);

 if(buffer!=num){goto loop1;}

 a=buffer/10;

 b=buffer%10;

 LED=0;delay(5,1000);

 LED=1;delay(5,1000);

 LED=0;delay(5,1000);

 LED=1;delay(5,1000);

 while(1){display(a,b);}

}

最后,求求看到的此文的小伙伴点赞关注支持一下下哦。毕竟,码字不容易哦,您的支持是我最大的动力呀!!!呜呜呜~~~

  • 11
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
STC8单片机读写内部EEPROM KEIL工程文件源码: /* STC8 内部EEPROM测试 从手册717页上可以看出 STC8的 EEPROM空间为1k 地址在0000h-03ffh 地址也是1024的大小 次程序结合手册 编写 大同小异 程序的主要目的是 先清楚地址0 到512 (一个扇区)的数据 然后读取 清楚扇区的数据 如果清楚成功 则读到的数据都为0xff 然后在向里写入 1-ff 1-ff 512个这样的字节 然后在读里面的字节 判断是否和写入的一样 整个过程都是通过串口在不停的上传给电脑 重点强调 更新数据一定是要先擦除整个扇区 才能更新 这是和外部E2的比较大的区别 但是和flash的写法差不多 要求 下载时 STC8 内部晶振为11.0592 电脑打开串口的波特率为9600 */ #include "stc8.h" #define u8 unsigned char #define u16 unsigned int #define CMD_IDLE 0 //空闲模式 #define CMD_READ 1 //IAP字节读命令 #define CMD_PROGRAM 2 //IAP字节编程命令 #define CMD_ERASE 3 //IAP字节擦除命令 #define ENABLE_IAP 0X82 //if SYSCLK<20MHz //测试地址 #define IAP_ADDRESS 0X0000 //从手册上可以看出 STC15F2K60S2的EEPROM地址是0x0000- 0x03ff 正好是1k的地址空间 sbit led=P5^5; //P3.5口LED灯定义 //延时函数 void delay(u8 n) { while(n--); } //关闭IAP void IapIdle() { IAP_CONTR=0; //关闭IAP功能 IAP_CMD =0; //清除命令寄存器 IAP_TRIG =0; //清楚触发寄存器 IAP_ADDRH=0X80; //将地址设置到非IAP区域 IAP_ADDRL=0; } //从ISP/IAP/EEPROM区域读取一个字节 u8 IapReadByte(u16 addr) { u8 dat; //数据缓冲区 IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_READ; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDRH=addr>>8; //设置IAP高地址 IAP_TRIG=0X5a; //写触发命令(0x5a) 写触摸命令以后 命令才会生效 手册713页 IAP_TRIG=0Xa5; //写触发命令(0xa5) delay(10); //等待ISP/IAP/EEPROM操作完成 dat=IAP_DATA; //读ISP/IAP/EEPROM数据 IapIdle(); //关闭IAP功能 return dat; //返回 } //写一个字节数据到ISP/IAP/EEPROM区域 void IapProgramByte(u16 addr,u8 dat) { IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_PROGRAM; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDRH=addr>>8; //设置IAP高地址 IAP_DATA=dat; //写ISP/IAP/EEPROM数据 IAP_TRIG=0X5a; //写触发命令(0x5a) 写触摸命令以后 命令才会生效 手册713页 IAP_TRIG=0Xa5; //写触发命令(0xa5) delay(10); //等待ISP/IAP/EEPROM操作完成 IapIdle(); //关闭IAP功能 } //扇区擦除 void IapEraseSector(u16 addr) { IAP_CONTR=ENABLE_IAP; //使能IAP 同时设置等待时间 IAP_CMD=CMD_ERASE; //设置IAP命令 IAP_ADDRL=addr; //设置IAP低地址 IAP_ADDR
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式硬件与代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值