单片机的EEPROM功能
- 格式:pdf
- 大小:90.87 KB
- 文档页数:5
单片机内的 Flash 与 EEPROM 作用及区别单片机运行时的数据都存在于 RAM (随机存储器中, 在掉电后 RAM 中的数据是无法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用 EEPROM 或FLASHROM 等存储器来实现。
在传统的单片机系统中, 一般是在片外扩展存储器, 单片机与存储器之间通过 IIC 或 SPI 等接口来进行数据通信。
这样不光会增加开发成本,同时在程序开发上也要花更多的心思。
在 STC 单片机中内置了 EEPROM (其实是采用 IAP 技术读写内部 FLASH 来实现 EEPROM ,这样就节省了片外资源,使用起来也更加方便。
下面就详细介绍 STC 单片机内置 EEPROM 及其使用方法。
flash 是用来放程序的,可以称之为程序存储器,可以擦出写入但是基本都是整个扇区进行的 .一般来说单片机里的 flash 都用于存放运行代码,在运行过程中不能改; EEPROM 是用来保存用户数据,运行过程中可以改变,比如一个时钟的闹铃时间初始化设定为 12:00,后来在运行中改为 6:00,这是保存在 EEPROM 里, 不怕掉电,就算重新上电也不需要重新调整到 6:00下面是网上详细的说法,感觉不错:FLASH 和 EEPROM 的最大区别是 FLASH 按扇区操作, EEPROM 则按字节操作, 二者寻址方法不同,存储单元的结构也不同, FLASH 的电路结构较简单,同样容量占芯片面积较小,成本自然比 EEPROM 低,因而适合用作程序存储器, EEPROM 则更多的用作非易失的数据存储器。
当然用 FLASH 做数据存储器也行, 但操作比EEPROM 麻烦的多,所以更“人性化”的 MCU 设计会集成 FLASH 和 EEPROM 两种非易失性存储器,而廉价型设计往往只有 FLASH ,早期可电擦写型 MCU 则都是EEPRM 结构,现在已基本上停产了。
在芯片的内电路中, FLASH 和 EEPROM 不仅电路不同,地址空间也不同,操作方法和指令自然也不同, 不论冯诺伊曼结构还是哈佛结构都是这样。
单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RA M 中的数据是无法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPR OM或F LASHR OM 等存储器来实现。
在传统的单片机系统中,一般是在片外扩展存储器,单片机与存储器之间通过IIC或SPI等接口来进行数据通信。
这样不光会增加开发成本,同时在程序开发上也要花更多的心思。
在ST C 单片机中内置了E EPROM(其实是采用IAP技术读写内部FLAS H 来实现EEPR OM),这样就节省了片外资源,使用起来也更加方便。
下面就详细介绍STC单片机内置EEP ROM 及其使用方法。
f lash是用来放程序的,可以称之为程序存储器,可以擦出写入但是基本都是整个扇区进行的.一般来说单片机里的f lash都用于存放运行代码,在运行过程中不能改;EEPR OM是用来保存用户数据,运行过程中可以改变,比如一个时钟的闹铃时间初始化设定为12:00,后来在运行中改为6:00,这是保存在EE PROM里,不怕掉电,就算重新上电也不需要重新调整到6:00下面是网上详细的说法,感觉不错:F LASH和EEPR OM的最大区别是FL ASH按扇区操作,E EPROM则按字节操作,二者寻址方法不同,存储单元的结构也不同,FLA SH的电路结构较简单,同样容量占芯片面积较小,成本自然比EE PROM低,因而适合用作程序存储器,EE PROM则更多的用作非易失的数据存储器。
当然用FL ASH做数据存储器也行,但操作比EEPR OM麻烦的多,所以更“人性化”的MCU设计会集成F LASH和EEPRO M两种非易失性存储器,而廉价型设计往往只有 FLA SH,早期可电擦写型MCU则都是EEPR M结构,现在已基本上停产了。
单片机断电短暂记忆功能在一些应用场景下,单片机需要断电后能够保留一些重要的信息,例如电子秤需要保存当前称量的数值,温湿度传感器需要保存当前的环境信息等。
如果没有断电短暂记忆功能,每次断电后都需要重新初始化这些信息,这不仅浪费时间和资源,还可能导致数据丢失。
一种常用的实现方法是使用EEPROM(电可擦可编程只读存储器)来存储断电前的数据。
EEPROM是一种非易失性存储器,它可以在断电时保存数据,并且在电源重新上电后还能恢复这些数据。
EEPROM主要通过电场效应将数据存储在晶体管的栅极上,因此它不需要外部电源来保持数据的存储状态。
在单片机上,可以使用I2C或SPI接口与EEPROM通信,读写数据。
另一种常见的方法是使用闪存来实现断电短暂记忆功能。
闪存是一种非易失性存储器,通常用于存储程序代码和配置信息。
与EEPROM相比,闪存具有更高的存储密度和更快的读写速度,但相应的价格也更高。
在单片机上,可以通过SPI接口与闪存通信,将断电前的数据保存在闪存中,并在上电后恢复这些数据。
除了EEPROM和闪存外,还可以使用SD卡等外部存储器来实现断电短暂记忆功能。
SD卡是一种常见的存储介质,具有较大的存储容量和较快的读写速度。
在单片机上,可以通过SPI接口与SD卡通信,将断电前的数据保存在SD卡中,并在上电后从SD卡中读取这些数据。
无论是使用EEPROM、闪存还是SD卡,都需要在软件层面做一些工作来实现断电短暂记忆功能。
首先,需要定义一个数据结构,用于保存断电前的数据。
然后,需要在断电前将这些数据存储到外部存储器中,可以使用适当的协议或API来实现数据的读写。
在上电后,需要读取外部存储器中的数据,并将其恢复到相应的变量或寄存器中。
最后,需要在程序中处理可能出现的数据错误或异常情况,以确保数据的正确性和完整性。
总之,单片机断电短暂记忆功能是一种非常有用的功能,它可以保留断电前的信息,简化系统的初始化过程,并提高系统的可靠性和稳定性。
AVR 单片机内部EEPROM 应用方法
AVR 单片机内部集成了EEPROM,但是在GCC 写编写EEPROM 应用
程序的时候,经常会出现读写EEPROM 时程序出错,或重启等不正常现象。
在软件仿真时也许结果是正确的,但是在片上运行的时候就不正常。
困扰很
久,终于发现原因在于编译器,已经我们对EEPROM 操作说明的理解不正确
或不仔细。
操作EEPROM 对时序的要求较高。
更加Datasheet 里的写操作范例程序:while(EECR & (1EEAR = address; //设置地址和数据寄存器
EEDR = data;
EECR |= (1
EECR |= (1 以上代码在GCC 中的编译结果,发现EECR |= (1while(EECR & (1EEAR = address; //设置地址和数据寄存器
EEDR = data;
asm volatile(SBI 0x1C,2 \n\t);
asm volatile(SBI 0x1C,1 \n\t);。
Stc单片机eeprom使用心得STC单片机利用IAP技术实现了EEPROM功能,相比外置存储芯片而言,在操作上比较方便。
涉及STC单片机EEPROM操作的特殊功能寄存器有6个,地址分别是E2H、E3H、E4H、E5H、E6H和E7H。
在STC单片机使用手册中,作者分别将它们定义为:一、IAP_DATA(E2H)二、IAP_ADDRH(E3H)三、IAP_ADDRL(E4H)四、IAP_CMD(E5H)五、IAP_TRIG(E6H)六、IAP_CONTR(E7H)本人认为,手册中给每个地址单元定义的英文词组太长,而且有点哆嗦,占的篇幅又大,感觉对正常阅读和理解产生了一定的干扰,反倒不好了解作者的意图了,还不如让使用者自己定义为好。
我自己对这些单元分别定义为DA T ADDRH ADDRL CMD TRIG CONTR。
一、DAT(E2H)从EEPROM中读取到的数据首先进入这里。
要把数据写入EEPROM中,也要把数据放到这个单元中。
也就是说,这个单元起到了中转站的作用,写入和读出都要通过这个单元。
二、ADDRH、ADDRL分别是EEPROM地址单元高8位和低8位。
如要把数据存储到1000H 单元中,那么在程序中,ADDRH的数值为10H,ADDRL的数值为00H。
三、CMD表示操作类型。
数值为1是读,数值为2是写,数值为3是擦除。
简单点说,就是“1读2写3擦除”。
四、CONTR寄存器,说明书上作了好多功能表述,但对于一般使用者来说,寄存器的前5位可以不作过多了解,只要掌握后3位意义就可以了。
一般理解为,选择好后3位的数值,为的是确保在不同数值晶振下正确读写擦除EEPROM。
考虑到TRIG这个寄存器的要求,一般使用时,可将前5位设置为10000,后3位根据不同晶振频率来确定(这个见使用手册)。
五、TRIG这个寄存器,看了好长时间手册才了解它的一般使用,对这个寄存器理解应当放到最后。
说明书是这样写的:为isp/iap操作时的命令模式寄存器。
STC单片机EEPROM读写程序在单片机中,EEPROM(Electrically Erasable Programmable Read-Only Memory)是一种非易失性存储器,可以用于存储数据,即使在断电情况下,数据也会被保留。
因此,掌握STC单片机的EEPROM读写程序对于开发嵌入式系统非常重要。
一、EEPROM简介EEPROM是一种可重复擦写的存储器,可用于存储小量数据。
与Flash存储器相比,EEPROM具有更快的写入和擦除速度。
在STC单片机中,EEPROM的存储容量通常较小,一般在几个字节到几千字节之间。
二、EEPROM读操作在STC单片机中,进行EEPROM读操作需要按照以下步骤进行:1. 初始化I2C总线:STC单片机使用I2C总线进行EEPROM读写操作,因此需要先初始化I2C总线。
通过设置相关寄存器,设置I2C 总线的速度和地址。
2. 发送设备地址:确定要读取的EEPROM设备的地址,并发送到I2C总线。
3. 发送寄存器地址:确定要读取的EEPROM寄存器地址,并将其发送到I2C总线。
4. 发送读命令:向EEPROM发送读命令,以启动读操作。
5. 读取数据:从EEPROM中读取数据,并保存到变量中。
6. 结束读操作:完成读操作后,关闭I2C总线。
三、EEPROM写操作类似于读操作,进行EEPROM写操作也需要按照一定的步骤进行:1. 初始化I2C总线:同样地,首先需要初始化I2C总线。
2. 发送设备地址:确定要写入的EEPROM设备的地址,并发送到I2C总线。
3. 发送寄存器地址:确定要写入的EEPROM寄存器地址,并将其发送到I2C总线。
4. 发送写命令:向EEPROM发送写命令,以启动写操作。
5. 写入数据:将要写入EEPROM的数据发送到I2C总线。
6. 结束写操作:完成写操作后,关闭I2C总线。
四、注意事项在进行EEPROM读写操作时,需要注意以下几点:1. 确保正确的设备地址:要与EEPROM的地址匹配,否则无法进行有效的读写操作。
单片机STC89C52RC 内部EEPROM单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RAM 中的数据是无法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPROM 或FLASHROM 等存储器来实现。
在传统的单片机系统中,一般是在片外扩展存储器,单片机与存储器之间通过IIC 或SPI 等接口来进行数据通信。
这样不光会增加开发成本,同时在程序开发上也要花更多的心思。
在STC 单片机中内置了EEPROM(其实是采用ISP/IAP 技术读写内部FLASH 来实现EEPROM),这样就节省了片外资源,使用起来也更加方便。
下面就详细介绍STC 单片机内置EEPROM 及其使用方法STC 各型号单片机内置的EEPROM 的容量最小有2K,最大有16K,基本上很好地满足项目的需要,更方便之处就是节省了周边的EEPROM 器件,达到节省成本的目的,而且内部EEPROM 的速度比外部的EEPROM 的速度快很多。
STC 各型号单片机内置的EEPROM 是以512 字节为一个扇区,EEPROM 的起始地址=FALSH 容量值+1,那么STC89C52RC 的起始地址为0x2000,第一扇区的起始地址和结束地址0x2000~0x21FF,第二扇区的起始地址和结束地址0x2200~0x23FF,其他扇区如此类推。
深入重点:�传统的EEPROM 是电可擦可编程只读存储一种掉电后数据不丢失的存储芯片。
�STC89C52RC 的EEPROM 是通过ISP/IAP 技术读写内部FLASH 来实现EEPROM。
�STC89C52RC 的EEPROM 起始地址为0x2000,以512 字节为一个扇区,EERPOM 的大小为2K 字节。
STC89C52RC 与EEPORM 实现的寄存器有6 个,分别是ISP_DATA、ISP_ADDRH、ISP_ADDRLISP_TRIG、ISP_CMD、ISP_CONTR。
RAM、SRAM、SDRAM、ROM、EPROM、EEPROM、Flash存储器区别常见存储器概念:RAM、SRAM、SDRAM、ROM、EPROM、EEPROM、Flash存储器可以分为很多种类,其中根据掉电数据是否丢失可以分为RAM(随机存取存储器)和ROM(只读存储器),其中RAM的访问速度比较快,但掉电后数据会丢失,而ROM掉电后数据不会丢失。
在单片机中,RAM主要是做运行时数据存储器,FLASH主要是程序存储器,EEPROM主要是用以在程序运行保存一些需要掉电不丢失的数据.FLASH:单片机运行的程序存储的地方。
SRAM:存储单片机运行过程中产生的了临时数据。
EEPROM:视用户的需要而定,一般用来存储系统的一些参数,这些参数可能需要修改,也可能不会修改。
ROM和RAM指的都是半导体存储器,ROM是Read Only Memory的缩写,RAM是Random Access Memory的缩写。
ROM在系统停止供电的时候仍然可以保持数据,而RAM通常都是在掉电之后就丢失数据,典型的RAM就是计算机的内存。
另外,一些变量,都是放到RAM里的,一些初始化数据比如液晶要显示的内容界面,都是放到FLASH区里的(也就是以前说的ROM区),EEPROM可用可不用,主要是存一些运行中的数据,掉电后且不丢失RAM 又可分为SRAM(Static RAM/静态存储器)和DRAM(Dynamic RAM/动态存储器)。
SRAM 是利用双稳态触发器来保存信息的,只要不掉电,信息是不会丢失的。
DRAM是利用MOS(金属氧化物半导体)电容存储电荷来储存信息,因此必须通过不停的给电容充电来维持信息,所以DRAM 的成本、集成度、功耗等明显优于SRAM。
SRAM速度非常快,是目前读写最快的存储设备了,但是它也非常昂贵,所以只在要求很苛刻的地方使用,譬如CPU的一级缓冲,二级缓冲。
DRAM保留数据的时间很短,速度也比SRAM慢,不过它还是比任何的ROM都要快,但从价格上来说DRAM相比SRAM要便宜很多,计算机内存就是DRAM的。
STC单片机内部EEPROM的应用可以使单片机可以将数据写入到程序存储器中,使得数据如同烧入的程序一样,掉电不丢失。
当然写入数据的区域与程序存储区要分开来,以使程序不会遭到破坏。
上面提到了IAP,它的意思是“在应用编程”,即在程序运行时程序存储器可由程序自身进行擦写。
正是是因为有了IAP,从而可以使单片机可以将数据写入到程序存储器中,使得数据如同烧入的程序一样,掉电不丢失。
当然写入数据的区域与程序存储区要分开来,以使程序不会遭到破坏。
要使用IAP功能,与以下几个特殊功能寄存器相关:ISP_DATA:ISP/IAP操作时的数据寄存器。
ISP/IAP从Flash读出的数据放在此处,向Flash写的数据也需放在此处ISP_ADDRH:ISP/IAP操作时的地址寄存器高八位。
ISP_ADDRL:ISP/IAP操作时的地址寄存器低八位。
ISP_CMD:ISP/IAP操作时的命令模式寄存器,须命令触发寄存器触发方可生效。
ISP_TRIG:ISP/IAP操作时的命令触发寄存器。
当ISPEN(ISP_CONTR.7)=1时,对ISP_TRIG先写入0x46,再写入0xb9,ISP/IAP命令才会生效。
单片机芯片型号起始地址内置EEPROM容量(每扇区512字节)STC89C51RC,STC89LE51RC0x2000共八个扇区STC89C52RC,STC89LE52RC0x2000共八个扇区STC89C54RD+,STC89LE54RD+0x8000共五十八个扇区STC89C55RD+,STC89LE55RD+0x8000共五十八个扇区STC89C58RD+,STC89LE58RD+0x8000共五十八个扇区寄存器标识地址名称76543210初始值0xE2ISP/IAP闪存数据寄存器11111111ISP_DATAISP_DATA0xE2ISP_ADDRH0xE3ISP/IAP闪存地址高位00000000ISP_ADDRL0xE4ISP/IAP闪存地址低位00000000ISP_CMD0xE5ISP/IAP闪存命令寄存器MS2MS1MS0xxxxx000ISP_TRIG0xE6ISP/IAP闪存命令触发xxxxxxxxISP_CONTR0xE7ISP/IAP控制寄存器ISPEN SWBS SWRST WT2WT1WT000xx000B7B6B5B4B3B2B1B0命令/操作模式选择保留命令选择-----000待机模式,无ISP/IAP操作-----001对用户的应用程序Flash区及数据Flash区字节读-----010对用户的应用程序Flash区及数据Flash区字节编程-----011对用户的应用程序Flash区及数据Flash区扇区擦除ISP_CONTR:ISP/IAP控制寄存器。
51单⽚机EEprom的存取/****************************************************************************** *********************⼯程名称:IIC功能描述:每按下⼀次复位键或重新给系统上电,发光⼆极管表⽰的数据加1,实现记录开机次数。
硬件连接:⽤8位杜邦线将J8与J13连接,2位杜邦线分别将J11_7与J17_SDA、J11_6与J17_SCL连接维护记录:2011-8-22******************************************************************************* ********************/#include "reg51.h" //包含头⽂件#include"intrins.h" //_nop_();延时函数⽤sbit sda=P2^7; //数据线sbit scl=P2^6; //时钟线#define uchar unsigned char#define uint unsigned int//***************************************************************************** *********************//延时//***************************************************************************** *********************delay(uint time) //int型数据为16位,所以最⼤值为65535{uint i,j; //定义变量i,j,⽤于循环语句for(i=0;ifor(j=0;j<50;j++); //for循环,循环50次}//***************************************************************************** *********************//启动(SCL为⾼,SDA由⾼变为低是⼀个开始条件)//***************************************************************************** *********************void start(){sda=1; //数据线置⾼,_nop_(); //延时scl=1; //时钟线置⾼_nop_(); //延时sda=0; //数据线置低,由⾼变低_nop_(); //延时scl=0; //时钟线置低,准备发送或接收数据,总线进⼊忙状态(I2C总线在空闲状态时,SDA与SCL均被置⾼)//停⽌(SCL为⾼,SDA由低变为⾼是⼀个结束条件)//***************************************************************************** *********************void stop(){sda=0; //数据线置低_nop_(); //延时scl=1; //时钟线置⾼_nop_(); //延时sda=1; //数据线置⾼,由低变⾼_nop_(); //延时}//***************************************************************************** *********************//检测应答(所有的地址和数据字都是以8bit,在第9个时钟周期,从器件发出"0"信号来作为收到⼀个字的应答信号) //***************************************************************************** *********************void checkACK() //主器件检测从器件是否返回应答{scl=1; //时钟线置⾼_nop_(); //延时while(sda==1); //等待第9个时钟周期器件发出的响应信号"0"scl=0; //时钟线置低_nop_(); //延时}//***************************************************************************** *********************//发送应答(发送⽅为主器件,接收⽅为从器件,控制器作为从器件接收完1数据时,发送应答信号//***************************************************************************** *********************void sendACK(bit ACK){if(ACK)sda=1; //如果i位为1则发送1,即发送"⾮应答信号"else sda=0; //如果i位为0则发送0,即发送"应答信号"scl=1; //时钟线置⾼,给⼀个脉冲_nop_(); //延时scl=0; //时钟线置低//写⼀字节//***************************************************************************** ********************* void send_byte(uchar date) //写⼀个8位字{uchar i,temp; //定义局部变量temp=date; //待发8位数据赋予tempfor(i=0;i<8;i++) //循环8次,每次写⼊1位,从最⾼位开始发送{if(temp&0x80)sda=1; //如果temp最⾼位为1则发送1else sda=0; //如果temp最⾼位为0则发送0_nop_(); //延时scl=1; //给⼀个脉冲,发送sda当前这位数据_nop_(); //延时,需⼤于4us(参考数据⼿册时序图)_nop_();_nop_();_nop_();_nop_();scl=0; //时钟线置低,准备下⼀脉冲_nop_(); //延时,需⼤于4.7us(参考数据⼿册时序图)_nop_();_nop_();_nop_();_nop_();temp=temp<<1; //左移1位,准备好下1位待发送的数据}checkACK(); //查询是否返回应答信号}//***************************************************************************** ********************* //读⼀字节//***************************************************************************** ********************* uchar receive_byte() //读⼀个8位字{uchar i,temp; //定义局部变量sda=1; //设置数据线为输⼊_nop_(); //延时for(i=0;i<8;i++) //循环8次,每次读取1位,从最⾼位开始接收{scl=1; //给⼀脉冲,准备发送1位数据_nop_(); //延时,需⼤于4us(参考数据⼿册时序图)_nop_();_nop_();_nop_();_nop_();temp=(temp<<1)|sda; //读取1位数据,放在temp最低位scl=0; //准备给下1个脉冲_nop_(); //延时,需⼤于4.7us(参考数据⼿册时序图)_nop_();_nop_();_nop_();_nop_();}return temp; //返回读取的8位数据}//***************************************************************************** ********************* //向某I2C器件的某字地址写⼀字节数据//***************************************************************************** ********************* void write_word(uchar device_add,uchar word_add,uchar date) //写进去⼀个存储数据{start(); //启动send_byte(device_add); //选择从器件地址,RW位为0,即选择写命令send_byte(word_add); //写字地址send_byte(date); //写数据stop(); //停⽌}//***************************************************************************** ********************* //向某I2C器件的某字地址读⼀字节数据//***************************************************************************** ********************* uchar read_word(uchar device_add,uchar word_add) //读出⼀个存储的数据{uchar date;start(); //启动send_byte(device_add); //选择从器件地址,RW位为0,即选择写命令send_byte(word_add); //写字地址start(); //启动send_byte(device_add+1); //选择从器件地址,RW位为1,即选择读命令date=receive_byte(); //读数据sendACK(1); //发送⾮应答信号stop(); //停⽌return date; //返回读取结果数据}//***************************************************************************** *********************//主函数//***************************************************************************** *********************void main(){uchar temp; //定义中间变量temp=read_word(0xa0,0); //从I2C器件a0的第0个地址读出数据赋予temp write_word(0xa0,0,temp+1); //向I2C器件a0的第0个地址写temp+1delay(100); //延时while(1) //死循环{temp=read_word(0xa0,0); //从第0个地址读出⼀个数据delay(100); //延时P1=~temp; //送数据到P1⼝显⽰}}。
单片机内的Flash与EEPROM作用及区别一单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RAM中的数据是无法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPROM或FLASHROM 等存储器来实现。
在传统的单片机系统中,一般是在片外扩展存储器,单片机与存储器之间通过IIC或SPI等接口来进行数据通信。
这样不光会增加开发成本,同时在程序开发上也要花更多的心思。
在STC单片机中内置了EEPROM(其实是采用IAP技术读写内部FLASH来实现EEPROM),这样就节省了片外资源,使用起来也更加方便。
下面就详细介绍STC单片机内置EEPROM及其使用方法。
flash是用来放程序的,可以称之为程序存储器,可以擦出写入但是基本都是整个扇区进行的.一般来说单片机里的flash都用于存放运行代码,在运行过程中不能改;EEPROM是用来保存用户数据,运行过程中可以改变,比如一个时钟的闹铃时间初始化设定为12:00,后来在运行中改为6:00,这是保存在EEPROM里,不怕掉电,就算重新上电也不需要重新调整到6:00下面是网上详细的说法,感觉不错:FLASH和EEPROM的最大区别是FLASH按扇区操作,EEPROM则按字节操作,二者寻址方法不同,存储单元的结构也不同,FLASH的电路结构较简单,同样容量占芯片面积较小,成本自然比EEPROM低,因而适合用作程序存储器,EEPROM则更多的用作非易失的数据存储器。
当然用FLASH做数据存储器也行,但操作比EEPROM麻烦的多,所以更“人性化”的MCU设计会集成FLASH和EEPROM两种非易失性存储器,而廉价型设计往往只有FLASH,早期可电擦写型MCU则都是EEPRM结构,现在已基本上停产了。
在芯片的内电路中,FLASH和EEPROM不仅电路不同,地址空间也不同,操作方法和指令自然也不同,不论冯诺伊曼结构还是哈佛结构都是这样。
技术上,程序存储器和非易失数据存储器都可以只用FALSH结构或EEPROM结构,甚至可以用“变通”的技术手段在程序存储区模拟“数据存储区”,但就算如此,概念上二者依然不同,这是基本常识问题。
单片机片内大容量EEPROM的一种巧妙应用引言MCS-51 单片机是目前国内应用最广泛的一种单片机型。
全球各单片机生产厂商在MCS-51 内核基础上,派生了大量的51 内核系列单片机,极大地丰富了MCS-51 的种群。
其中STC 公司推出了STC89 系列单片机,增加了大量新功能,提高了51 的性能,是MCS-51 家族中的佼佼者。
早期的单片机控制系统,采用单片机加片外EEPROM 配合,来存储一些需要预置的重要参数,并在数码管上显示出来。
由于单片机控制的整流器要求实时性很强,而早期EEPROM 的写周期在10 ms 左右,因此运行参数的预置是在整流器待机的情况下进行的。
而很多情况下需要在运行的同时记录数据,如用单片机控制的12脉波汽车电泳整流器要求在运行的同时实时记录重要数据,而且在掉电时不丢失。
由于在12 脉波整流器中运行的单片机程序,其周期必须小于1.67 ms(交流电网的1 个周期是20 ms,除以12 就是l_67 ms),这就要求实时记录的时间在1ms 以下甚至更短(考虑到程序的执行时间)。
经查阅资料发现,目前很多EEPROM 达不到这个要求[1],即使时间最短的AT89S8252 单片机片内。
EEP- ROM 的写周期也是2.5 ms。
本文通过对EEPROM 的巧妙应用,实现了整流器在线记录数据的功能。
1 寻找符合要求的单片机设备使用的是Atmel 公司的AT89C52(40DIP 封装)单片机和EEPROM 芯片2817A。
要想在不改变原设备电路板的情况下完成要求的功能,就只能在兼容的MCS-51 系列单片机中想办法。
AT89S8252 片内含有2 KB 的EEPROM,经编程测试发现,它虽然能实时记录数据并且断电不丢失,但是在向片内EEPROM 中记录1 个数据时,能引起输出电压和电流的波动,不能满足实际运。
单片机存储用户方法
以下是一些常见的方法:
1. 内部存储器:大多数单片机都内置了一定容量的存储器,如RAM(随机存取存储器)和EEPROM(电可擦除可编程只读存储器)。
你可以使用这些内部存储器来存储用户数据。
- RAM:用于临时存储数据,掉电后数据会丢失。
适用于存储临时变量、运算结果等。
- EEPROM:可用于长期存储用户数据,即使掉电数据也不会丢失。
但写入次数有限,通常在几千次到十万次之间。
2. 外部存储器:如果需要存储大量用户数据或需要更长久的数据保存,可以考虑使用外部存储器,如Flash 存储器、EEPROM 芯片或SD 卡等。
- Flash 存储器:具有较大的存储容量,可擦写次数较多(通常在数万次到百万次之间),适合长期存储用户数据。
- EEPROM 芯片:与单片机内部的EEPROM 类似,但提供更大的存储容量。
- SD 卡:提供较大的存储容量,并且易于插拔和数据传输。
3. 文件系统:对于更复杂的应用,可以考虑在单片机上使用文件系统来组织和管理用户数据。
文件系统可以提供文件和文件夹的概念,方便数据的存储、读取和删除。
/*********************************************************本程序实现了利用STC12c5a16s2内部的EEPROM来存取数据的功能,这样的功能可以保证数据在掉电后不会丢失,上电后依然会保存。
在这个程序中,只是简单地演示了利用该单片机的一个扇区来存储数码管的值。
数码管的值每一秒增一,日后熟练地话,可以在单片机中存储许多重要的信息。
作者:让梦远航日期:2012年10月18日最后修改:2012年11月6日欢迎对程序的功能进行扩充。
*********************************************************/#include"STC12c5a16s2.h" //stc12c5a16s2单片机的头文件,可以从stc官网上下载#include<intrins.h>#define uchar unsigned char#define uint unsigned int#define RdCommand 0x01#define PrgCommand 0x02#define EraseCommand 0x03#define Error 1#define OK 0#define WaitTime 0x01uchar count,shu,shi,ge;sbit wela=P2^1;sbit wela1=P2^2;uchar code duanma[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};void delay(uint z){uint j,k;for(j=0;j<z;j++)for(k=0;k<110;k++);}void display(uchar shu){uchar shi,ge;shi=shu/10;ge=shu%10;wela1=0;P0=duanma[ge];delay(2);wela1=1;wela=0;P0=duanma[shi];delay(2);wela=1;}void ISP_IAP_enable(){EA=0;IAP_CONTR=IAP_CONTR&0x18;IAP_CONTR=IAP_CONTR|WaitTime;IAP_CONTR=IAP_CONTR|0x80;}void ISP_IAP_disable(){IAP_CONTR=IAP_CONTR&0x7f;IAP_TRIG=0x00;EA=1;}void ISPgoon(){ISP_IAP_enable();IAP_TRIG=0x5a;IAP_TRIG=0xa5;_nop_();}uchar byte_read(uint byte_addr){IAP_ADDRH =(uchar)(byte_addr>>8);IAP_ADDRL =(uchar)(byte_addr&0x00ff);IAP_CMD =IAP_CMD&0xf8;IAP_CMD =IAP_CMD|RdCommand;ISPgoon();ISP_IAP_disable();return(IAP_DA TA);}void SectorErase(uint sector_addr){uint iSectorAddr;iSectorAddr=(sector_addr&0xfe00);IAP_ADDRH =(uchar)(iSectorAddr>>8);IAP_ADDRL =0x00;IAP_CMD =IAP_CMD&0xf8;IAP_CMD =IAP_CMD|EraseCommand;ISPgoon();ISP_IAP_disable();}void byte_write(uint byte_addr,uchar original_data) {IAP_ADDRH =(uchar)(byte_addr>>8);IAP_ADDRL =(uchar)(byte_addr&0x00ff);IAP_CMD =IAP_CMD&0xf8;IAP_CMD =IAP_CMD|PrgCommand;IAP_DA TA=original_data;ISPgoon();ISP_IAP_disable();}void main(){// int i;TMOD=0x01;TH0=(65536-50000)/256;TL0=(65536-50000)%256;EA=1;ET0=1;TR0=1;shu=byte_read(0x0000); //我们在具体操作的时候,主要就是注意操作单片机的EEPROM 的扇区,0x0000是//第一扇区的起始地址,此单片机共有56个扇区,只需要把数据存到相应的扇区(每个扇//区都有自己的起始地址和结束地址,写程序的时候,只需更改括号里面的扇区地址值就行).while(1){if(count>=20){count=0;shu++;SectorErase(0x0000); //相应的在这里也要修改,比如第二扇区起始地址是200H,只需将0000改成200就行。