完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
#define uchar unsigned char
#define uint unsigned int sfr ISP_DATA = 0Xe2; sfr ISP_ADDH = 0Xe3; sfr ISP_ADDL = 0Xe4; sfr ISP_CMD = 0Xe5; sfr ISP_TRIG = 0Xe6; sfr ISP_CONTR= 0Xe7; #define RED_ISP 0X01 #define WITE_ISP 0x02 #define ERASE_ISP 0X03 #define MCU_CLOCK_5MHz 0x04 #define MCU_CLOCK_12MHz 0x03 #define MCU_CLOCK_20MHz 0x02 #define MCU_CLOCK_24MHz 0x01 void delayms(uchar x) { uchar i,j; for(i=x;i>0;i--) for(j=110;j>0;j--); } void isp_off() { ISP_CONTR=ISP_CONTR&0X7F; //ISPEN=0; ISP_TRIG=0X00; } void isp_on() { ISP_CONTR=ISP_CONTR&0X18; //0001,1000 ISP_CONTR=ISP_CONTR|0X01; ISP_CONTR=ISP_CONTR|0x80; //ISPEN=1 } void isp_goon() { isp_on(); ISP_TRIG=0x46;//0X46; ISP_TRIG=0xb9;//0XB9; delayms(1); } uchar EEPROM_read(uint add) { uchar num; EA=0; ISP_ADDH=(uchar)(add>>8); ISP_ADDL=(uchar)(add&0x00ff); ISP_CMD=ISP_CMD&0XF8; ISP_CMD=ISP_CMD|RED_ISP; isp_goon(); isp_off(); num=ISP_DATA; EA=1; return(num); } void EEPROM_chachu(uint add) { EA=0; ISP_ADDH=(uchar)(add>>8); ISP_ADDL=(uchar)(add&0x00ff); ISP_CMD=ISP_CMD&0XF8; ISP_CMD=ISP_CMD|ERASE_ISP; isp_goon(); isp_off(); EA=1; } void EEPROM_wirte(uint add,uchar add1) { EA=0; ISP_ADDH=(uchar)(add>>8); ISP_ADDL=(uchar)(add&0x00ff); ISP_CMD=ISP_CMD&0XF8; ISP_CMD=ISP_CMD|WITE_ISP; ISP_DATA=add1; isp_goon(); isp_off(); EA=1; } |
|
相关推荐
1个回答
|
|
要从原理上来理解,看下下面这个,在对比下你的:
单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RAM 中的数据是无 法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPROM 或FLASHROM 等 存储器来实现。在传统的单片机系统中,一般是在片外扩展存储器,单片机与存储器之间通 过IIC 或SPI 等接口来进行数据通信。这样不光会增加开发成本,同时在程序开发上也要花 更多的心思。在STC 单片机中内置了EEPROM(其实是采用IAP 技术读写内部FLASH 来 实现EEPROM),这样就节省了片外资源,使用起来也更加方便。下面就详细介绍STC 单 片机内置EEPROM 及其使用方法。 STC 各型号单片机内置的EEPROM 的容量各有不同,见下表: (内部EEPROM 可以擦写100000 次以上) 上面提到了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,STC89LE51RC 0x2000 共八个扇区 STC89C52RC,STC89LE52RC 0x2000 共八个扇区 STC89C54RD+,STC89LE54RD+ 0x8000 共五十八个扇区 STC89C55RD+,STC89LE55RD+ 0x8000 共五十八个扇区 STC89C58RD+,STC89LE58RD+ 0x8000 共五十八个扇区 寄存器标识地址名称7 6 5 4 3 2 1 0 初始值 ISP_DATA 0xE2 ISP/IAP闪存数据寄存器11111111 ISP_ADDRH 0xE3 ISP/IAP 闪存地址高位00000000 ISP_ADDRL 0xE4 ISP/IAP 闪存地址低位00000000 ISP_CMD 0xE5 ISP/IAP闪存命令寄存器MS2 MS1 MS0 xxxxx000 ISP_TRIG 0xE6 ISP/IAP 闪存命令触发xxxxxxxx ISP_CONTR 0xE7 ISP/IAP 控制寄存器ISPEN SWBS SWRST WT2 WT1 WT0 00xx000 B7 B6 B5 B4 B3 B2 B1 B0 命令/操作模式选择 保留命令选择 - - - - - 0 0 0 待机模式,无ISP/IAP 操作 - - - - - 0 0 1 对用户的应用程序Flash 区及数据Flash 区字节读 - - - - - 0 1 0 对用户的应用程序Flash 区及数据Flash 区字节编程 - - - - - 0 1 1 对用户的应用程序Flash 区及数据Flash 区扇区擦除 ISP_CONTR:ISP/IAP 控制寄存器。 ISPEN:ISP/IAP 功能允许位。0:禁止ISP/IAP 编程改变Flash,1:允许编程改变Flash SWBS:软件选择从用户主程序区启动(0),还是从ISP 程序区启动(1)。 SWRST:0:不操作,1:产生软件系统复位,硬件自动清零。 ISP_CONTR 中的SWBS 与SWRST 这两个功能位,可以实现单片机的软件启动,并 启动到ISP 区或用户程序区,这在“STC 单片机自动下载”一节,亦有所应用。 如: ISP_CONTR=0x60? 则可以实现从用户应用程序区软件复位到ISP 程序区开始运行 程序。 ISP_CONTR=0x20? 则可以实现从ISP 程序区软件复位到用户应用程序区开始运行 程序。 用IAP 向Flash 中读写数据,是需要一定的读写时间的,读写数据命令发出后,要等待 一段时间才可以读写成功。这个等待时间就是由WT2、WT1、WT0 与晶体振荡器频率决定 的。 (以上的建议时钟是(WT2、WT1、WT0)取不同的值时的标称时钟,用户系统中的时钟 不要过高,否则可能使操作不稳定。) #include "reg52.h" #include "eeprom.h" //****************** 关闭 ISP,IAP 功能 ************** void ISP_IAP_Disable(void) { ISP_CONTR = 0x00; ISP_CMD = 0X00; ISP_TRIG = 0x00; EA =1; //开中断 } //*******************字节读*************************** uchar Byte_read(uint byte_addr) { ISP_CONTR =En_Wait_TIME; //开启ISP/IAP;并送等待时间 ISP_CMD =Read_COM; //送字节读命令字 ISP_ADDRH = (uchar)(byte_addr>>8); //送地址高字节 ISP_ADDRL = (uchar)(byte_addr &0X00FF); //送地址低字节 EA =0; //关中断 ISP_TRIG =0X46; //送触发命令字0X46、0XB9 ISP_TRIG = 0XB9; _nop_(); ISP_IAP_Disable(); //关闭ISP/IAP功能 EA =1; //开中断 return ((unsigned char)ISP_DATA); } //********************字节编程*********************** void Byte_program(uint byte_addr, ucharisp_iap_data) { ISP_CONTR =En_Wait_TIME; //开启ISP/IAP;并送等待时间 ISP_CMD =Prog_COM; //送字节编程命令字 ISP_ADDRH = (uchar)(byte_addr>>8); //送地址高字节 ISP_ADDRL = (uchar)(byte_addr &0X00FF); //送地址低字节 ISP_DATA =isp_iap_data; //送数据进ISP_DATA EA =0; //关中断 ISP_TRIG =0X46; //送触发命令字0X46、0XB9 ISP_TRIG = 0XB9; _nop_(); ISP_IAP_Disable(); //关闭ISP/IAP功能 EA =1; //开中断 } //********************* 扇区擦除********************* void Sector_erase(uint sector_addr) { ISP_CONTR =En_Wait_TIME; //开启ISP/IAP;并送等待时间 // ISP_CONTR=0xc1; ISP_CMD =Dele_COM; //送扇区擦除命令字 ISP_ADDRH = (uchar)(sector_addr>>8); //送地址高字节 ISP_ADDRL = (uchar)(sector_addr &0X00FF); //送地址低字节 EA =0; //关中断 ISP_TRIG =0X46; //送触发命令字0X46、0XB9 ISP_TRIG = 0XB9; _nop_(); ISP_IAP_Disable(); //关闭ISP/IAP功能 EA = 1; } #ifndef _eeprom_h #define _eeprom_H //*********************EEPROM定义命令字节****************** #defineRead_COM 0X01 //字节读数据存储区 #defineProg_COM 0X02 //字节编程数据存储区 #defineDele_COM 0X03 //扇区擦除数据存储区 #define En_Wait_TIME 0X81 //设置等待时间 ,并使能ISP/IAP //从用户区启动程序 //0X00==40MHZ以下,0X01==20MHZ以下 //0X02==10MHZ以下,0X03==5MHZ以下,现在设置了20MHZ以下的, // #defineStart_ADDRH 0X20 //扇区地址高位,STC89C/LE52RC #defineStart_ADDRL 0X00 //扇区地址低位 #endif 注意了,要写数据时,一定要对该扇区先擦除后写数据的,所以要写的数据尽量不要多,也可以对不同功能的数据存在不同的扇区里。如: Sector_erase(0X2e00); //扇区擦除,第八个扇区 Byte_program(0X2e00,Eeprom_ReadCode);//写EEPROM,保存可读命令 要读数据时,就直接读就可以了。 ReadData=Byte_read(0X2002);//读取该地址的数据 读一个字节、编程一个字节、擦除一个扇区分别用时10us、60us、10ms |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-使用AHT20进行环境监测之AHT20传感器介绍
828 浏览 0 评论
824 浏览 0 评论
861 浏览 1 评论
基于瑞萨FPB-RA4E2智能床头灯项目——1编译环境搭建与点亮驱动ws2812全彩LED
836 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之介绍mmap
1292 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11824 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-29 18:05 , Processed in 0.699946 second(s), Total 73, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号