多语言展示
当前在线:616今日阅读:3今日分享:40

如何用STC89C52RC内部的EEPROM实现记忆功能

以前学习51单片机写的程序都是直接将程序下载到单片机里边运行,断电后直接又重头开始,根本都每有考虑到记忆的功能,今天突然看到太阳能热水器和淘宝上的一个简单的温控器,他们都是设置好参数后,即使断电后他们还按着以前设置的参数或者是模式运行。这不由的让我想到其实他们都是有记忆功能的,至于他们具体是怎么实现的我不知道,后来我在网上查了一下单片机记忆功能实现的方法,大概有如下几种方法:     1、给RAM用电池供电 可以实现记忆     2、用单片机自身带的EEPROM,     3、用外扩的EEPROM,     4、用外扩的FLASH,     5、很多I2C总线和SPI总线的时钟芯片都有EEPROM。我个人觉得用单片机自身带的EEPROM这种方法可能是最方便的,当然芯片自身不带EEPROM那就得用其它方法了,EEPROM (Electrically Erasable Programmable Read-Only Memory),电可擦可编程只读存储器--一种掉电后数据不丢失的存储芯片。 EEPROM 可以在电脑上或专用设备上擦除已有信息,重新编程。一般用在即插即用。接下来就是介绍我用STC89C52RC内部的EEPROM实现记忆功能的一个实例。
工具/原料
1

电脑一台

2

用STC89C52RC单片机的开发板(当然只要是51系列的开发板都行,只要确保芯片是STC89C52RC就行,因为有的51芯片是不带EEPROM的,当然也可以自己焊一个)

方法/步骤
1

首先是编写程序,EEPROM的操作顺序如下:  1.擦除EEPROM  2.写EEPROM  3.读EEPROM打开keil开发环境(我用是keil4)建一个工程,编写程序用按键输入控制LED等的亮灭情况键k1是led1亮,k2是led1和led2亮。

2

以下是我在知道上看到的一个程序,几乎都是照着他这个这么来的。  链接:https://zhidao.baidu.com/question/3.html  源码:若找不到头文件,可以在网上搜,下载。#include #include #define uchar unsigned char    #define uint unsigned int sbit LED1 = P1^1;sbit LED2 = P1^2;sbit K1   = P3^2;   //按钮1sbit K2   = P3^3;   //按钮2void  cc(uint addr);void  xcx(uint addr,uchar dat);uchar dcx(uint addr);void  Q0();/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈函数:主程序┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/void main(void){   uchar V;   V = dcx(0x2002);  // 开机读取EEPROM区2002h数据,还原关电前LED的亮灭状况   if(V == 2)  {LED1=0;LED2=1;}   else if(V == 6){LED1=0;LED2=0;}    while(1)     {      if(!K1)    {      while(!K1);      LED1=0;LED2=1;      cc(0x2000);  // 擦除第1个扇区(2000h~21FFh)      xcx(0x2002,2);  // 对EEPROM区2002h写入2    }  if(!K2)    {      while(!K2);      LED1=0;LED2=0;      cc(0x2000);  // 擦除第1个扇区(2000h~21FFh)      xcx(0x2002,6);  // 对EEPROM区2002h写入6    }     }}/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈函数:擦除某一扇区(每个扇区512字节)入口:addr = 某一扇区首地址  ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/void cc(uint addr){          // 0x83(晶振<5M)   0x82(晶振<10M)   0x81(晶振<20M)   0x80(晶振<40M)    ISP_CONTR = 0x81;      // 打开 IAP 功能(ISPEN(ISP_CONTR.7)=1:允许编程改变Flash, 设置 Flash 操作等待时间。    ISP_CMD   = 0x03;  // 用户可以对"Data Flash/EEPROM区"进行扇区擦除    ISP_ADDRL = addr;         // ISP/IAP操作时的地址寄存器低八位,    ISP_ADDRH = addr>>8;      // ISP/IAP操作时的地址寄存器高八位。  EA =0;       ISP_TRIG = 0x46;          // 在ISPEN(ISP_CONTR.7)=1时,对ISP_TRIG先写入46h,    ISP_TRIG = 0xB9;          // 再写入B9h,ISP/IAP命令才会生效。    _nop_();    Q0();  // 关闭ISP/IAP}/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈函数:写一字节入口:addr = 扇区单元地址 , dat = 待写入数据┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/void xcx(uint addr,uchar dat){    ISP_CONTR = 0x81;      ISP_CMD   = 0x02;      // 用户可以对"Data Flash/EEPROM区"进行字节编程    ISP_ADDRL = addr;            ISP_ADDRH = addr>>8;          ISP_DATA  = dat;          // 数据进ISP_DATA    EA = 0;    ISP_TRIG = 0x46;              ISP_TRIG = 0xB9;              _nop_();    Q0();  // 关闭ISP/IAP}/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈函数:读一字节入口:addr = 扇区单元地址出口:dat  = 读出的数据┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/uchar dcx(uint addr){       uchar dat; ISP_CONTR = 0x81;      ISP_CMD   = 0x01;         // 用户可以对"Data Flash/EEPROM区"进行字节读    ISP_ADDRL = addr;             ISP_ADDRH = addr>>8;          EA = 0;    ISP_TRIG = 0x46;              ISP_TRIG = 0xB9;              _nop_();    dat = ISP_DATA;  // 取出数据 Q0();  // 关闭ISP/IAP           return dat;}/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈函数:关闭ISP/IAP操作┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/void Q0(){    ISP_CONTR = 0;            // 关闭IAP功能    ISP_CMD   = 0;            // 待机模式,无ISP操作    ISP_TRIG  = 0;            // 关闭IAP功能, 清与ISP有关的特殊功能寄存器 }

3

程序编译成功后利用STC-ISP下载编译好的hex 文件,下载好程序后led1和led2都不亮,关闭电源重开,两等不亮;按下k1,led1亮,led2不亮,关闭电源重开led1亮,led2不亮;按下k2,两灯亮,关闭电源重,两灯亮;说明测试成功。所以用此法可以实现记忆功能。

推荐信息