RYMCU

Nebula Pi 开发板评测报告(十四)——内部EEPROM读写功能测试

ii11nnocent 2 年前
# EEPROM # Nebula Pi # 评测报告

内部 EEPROM 可以实现掉电保存数据,擦写次数大于 10 万次,可以有效解决数据丢失的问题,采用下面的程序可以读取单片机的上电次数:

eeprom.h:

#ifndef _EEPROM_H
#define	_EEPROM_H

#include "reg52.h"

/****定义读写EEPROM所需的特殊功能寄存器****/
sfr ISP_DATA 	= 0XE2;
sfr ISP_ADDRH = 0XE3;
sfr ISP_DARRL = 0XE4;
sfr ISP_CMD	 	= 0XE5;
sfr ISP_TRIG 	= 0XE6;
sfr ISP_CONTR = 0XE7;

/****定义命令字节****/
#define	Read_CMD	0x01
#define	Write_CMD	0x02
#define	Erase_CMD	0x03

#define	Enable_WaitTime	0x82;		//定义操作的等待时间

void ISP_IAP_Disable(void);
void ISP_IAP_Trigger(void);
void ISP_IAP_ReadData( unsigned int BeginAddr , unsigned char* Buf , unsigned int DataSize );
void ISP_IAP_WriteData( unsigned int BeginAddr , unsigned char* Data , unsigned int DataSize );
void ISP_IAP_Erase( unsigned int Addr );


#endif

eeprom.c:

#include "eeprom.h"

//关闭ISP/IAP函数
void ISP_IAP_Disable(void)		
{
	EA = 1;		//开中断
	ISP_CONTR = 0;
	ISP_CMD		= 0;
	ISP_TRIG	= 0;	//禁止ISP/IAP读、写、擦除操作
}

//触发ISP/IAP函数
void ISP_IAP_Trigger(void)	
{
	EA = 0;		//先关闭总中断,防止中断响应打断下面两条语句
	ISP_TRIG = 0x46;
	ISP_TRIG = 0xB9;		//发送两条命令,使能ISP/IAP
}

//读数据函数
void ISP_IAP_ReadData( unsigned int BeginAddr , unsigned char* Buf , unsigned int DataSize )
{
	ISP_DATA = 0;	//清零数据寄存器
	ISP_CMD = Read_CMD;		//发送读取指令
	ISP_CONTR = Enable_WaitTime;	//开启ISP_IAP,并发送等待时间
	
	while( DataSize -- )
	{
		ISP_ADDRH = ( unsigned char )( BeginAddr >> 8 );		//发送高8位
		ISP_DARRL = ( unsigned char )( BeginAddr & 0x00FF );//发送低8位
		ISP_IAP_Trigger();
		BeginAddr ++;	//地址+1
		*Buf++=ISP_DATA;	//将数据存储到接收缓冲区
	}
	ISP_IAP_Disable();		//关闭ISP_IAP功能
}

//写数据函数
void ISP_IAP_WriteData( unsigned int BeginAddr , unsigned char* Data , unsigned int DataSize )
{
	ISP_CONTR = Enable_WaitTime;	//开启ISP_IAP,并发送等待时间
	ISP_CMD = Write_CMD;		//发送写指令	
	
	while( DataSize -- )
	{
		ISP_ADDRH = ( unsigned char )( BeginAddr >> 8 );		//发送高8位
		ISP_DARRL = ( unsigned char )( BeginAddr & 0x00FF );//发送低8位
		ISP_DATA=*Data++;	//发送数据
		BeginAddr ++;	//地址+1
		ISP_IAP_Trigger();		
	}
	ISP_IAP_Disable();		//关闭ISP_IAP功能
}

//擦除扇区函数
void ISP_IAP_Erase( unsigned int Addr )
{
	ISP_CONTR = Enable_WaitTime;	//开启ISP_IAP,并发送等待时间
	ISP_CMD = Erase_CMD;		//发送擦除指令	
	ISP_ADDRH = ( unsigned char )( Addr >> 8 );		//发送高8位
	ISP_DARRL = ( unsigned char )( Addr & 0x00FF );//发送低8位
	ISP_IAP_Trigger();	
	ISP_IAP_Disable();		//关闭ISP_IAP功能	
}

main.c

#include "reg52.h"  
#include "LCD1602.h"  
#include "eeprom.h"  
  
unsigned char Buf[5];       //数据缓冲区,类似串口中断的SBUF  
unsigned char Str[8];       //存储字符变量  
unsigned char Title[] = "Times of PowerOn";  
  
  
void main(void)  
{  
    LCD_Init();     //初始化LCD1602      
    ISP_IAP_ReadData( 0x21f0 , Buf , sizeof(Buf) );     //获取内部存储器中的数值  
      
    Buf[0]++;  
      
    Str[0] = Buf[0]/100 + '0';                      //获取上电次数的百位  
    Str[1] = (Buf[0]%100)/10 + '0';             //获取上电次数的十位  
    Str[2] = Buf[0]%10 + '0';                           //获取上电次数的个位  
    Str[4] = '0';      //结束  
  
    LCD_WriteString(1,1,Title);  
    LCD_WriteString(2,4,Str);  
      
    ISP_IAP_Erase( 0x2000 );       //擦除扇区  
    ISP_IAP_WriteData( 0x21f0 , Buf , sizeof(Buf) );        //写入数据  
      
    while(1);  
}

eeprom.mp4

后发布评论