用的STC89C52RC
用的串口助手,把数据写到EEPROM的地址0x2000中后再读取,返回值显示0x2000中已经是输入的值了
但是把
电源关掉后再打开,读取的值却是0xFF。求教!
我是根据这个改的
times New Roman">#include <intrins.h>#include <reg52.h> //52系列单片机头文件#define uchar unsigned char#define uint unsigned int #define RdCommand 0x01 //定义ISP的操作命令#define PrgCommand 0x02#define EraseCommand 0x03 #define Error 1#define Ok 0#define WaitTime 0x01 //定义CPU的等待时间sfr ISP_DATA=0xe2; //寄存器申明sfr ISP_ADDRH=0xe3;sfr ISP_ADDRL=0xe4;sfr ISP_CMD=0xe5;sfr ISP_TRIG=0xe6;sfr ISP_CONTR=0xe7;sbit dula=P2^6; //申明U1锁存器的锁存端sbit wela=P2^7; //申明U2锁存器的锁存端uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};uchar num;void delayms(uint xms) { uint i,j; for(i=xms;i>0;i--) //i=xms即延时约xms毫秒 for(j=110;j>0;j--);}void display(uchar shi,uchar ge) //显示子函数{ dula=1; P0=table[shi]; //送十位段选数据 dula=0; P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时 wela=1; //原来段选数据通过位选锁存器造成混乱 P0=0xfe; //送位选数据 wela=0; delayms(5); //延时 dula=1; P0=table[ge]; //送个位段选数据 dula=0; P0=0xff; wela=1; P0=0xfd; wela=0; delayms(5);}/* ================ 打开 ISP,IAP 功能 ================= */void ISP_IAP_enable(void){ EA = 0; /* 关中断 */ ISP_CONTR =ISP_CONTR & 0x18; /* 0001,1000*/ ISP_CONTR =ISP_CONTR | WaitTime; /* 写入硬件延时 */ ISP_CONTR =ISP_CONTR | 0x80; /* ISPEN=1 */}/* =============== 关闭 ISP,IAP 功能 ================== */void ISP_IAP_disable(void){ ISP_CONTR =ISP_CONTR & 0x7f; /*ISPEN = 0 */ ISP_TRIG = 0x00; EA = 1; /* 开中断 */}/* ================ 公用的触发代码==================== */void ISPgoon(void){ ISP_IAP_enable(); /* 打开 ISP,IAP 功能 */ ISP_TRIG =0x46; /* 触发ISP_IAP命令字节1 */ ISP_TRIG =0xb9; /* 触发ISP_IAP命令字节2 */ _nop_();}/* ==================== 字节读======================== */unsigned char byte_read(unsigned int byte_addr){ ISP_ADDRH =(unsigned char)(byte_addr >> 8);/* 地址赋值 */ ISP_ADDRL =(unsigned char)(byte_addr & 0x00ff); ISP_CMD = ISP_CMD & 0xf8; /* 清除低3位 */ ISP_CMD = ISP_CMD | RdCommand; /* 写入读命令 */ ISPgoon(); /* 触发执行 */ ISP_IAP_disable(); /* 关闭ISP,IAP功能 */ return(ISP_DATA); /* 返回读到的数据 */}/* ================== 扇区擦除======================== */void SectorErase(unsigned int sector_addr){ unsigned intiSectorAddr; iSectorAddr =(sector_addr & 0xfe00); /* 取扇区地址 */ ISP_ADDRH =(unsigned char)(iSectorAddr >> 8); ISP_ADDRL =0x00; ISP_CMD =ISP_CMD & 0xf8; /* 清空低3位 */ ISP_CMD = ISP_CMD| EraseCommand; /* 擦除命令3 */ ISPgoon(); /* 触发执行 */ ISP_IAP_disable(); /* 关闭ISP,IAP功能 */}/* ==================== 字节写======================== */void byte_write(unsigned int byte_addr, unsigned charoriginal_data){ ISP_ADDRH =(unsigned char)(byte_addr >> 8); /* 取地址 */ ISP_ADDRL =(unsigned char)(byte_addr & 0x00ff); ISP_CMD = ISP_CMD & 0xf8; /* 清低3位 */ ISP_CMD = ISP_CMD | PrgCommand; /* 写命令2 */ ISP_DATA =original_data; /* 写入数据准备 */ ISPgoon(); /* 触发执行 */ ISP_IAP_disable(); /* 关闭IAP功能 */}void main(){ uchar a,b,num1; TMOD=0x01; //设置定时器0为工作方式1(0000 0001) TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1; ET0=1; TR0=1; num1=byte_read(0x2000);//程序开始时读取EEPROM中数据 if(num1>=60)//防止首次上电时读取出错 num1=0; while(1) { if(num>=20) { num=0; num1++; SectorErase(0x2000);//擦除扇区 byte_write(0x2000,num1);//重新写入数据 if(num1==60) { num1=0; } a=num1/10; b=num1%10; } display(a,b); }}void timer0() interrupt 1{ TH0=(65536-50000)/256; TL0=(65536-50000)%256; num++; }
前面加延时,上电电压不稳造成的
谢谢,辛苦了
我改一下试试
一周热门 更多>