STC89C51系列 EEPROM测试程序 证明扇区512个字节的擦除

1测试程序

2证明程序




1

/*
单片机内置的 EEPROM测试程序
适用 
STC89C51
STC89C52
STC89C53
STC89C54
STC89C58
STC89C510
STC89C512
STC89C514

测试晶振:11.05926M 12M 都可以用 

功能:
读取指定地址的一个字节内容,并显示在8 P1总线上

擦除一个扇区,修改取指定地址的一个字节内容,并显示在8 P1总线上


*/

#include <reg51.h>
#include <intrins.h>

/******************EEPROM用到的sfr中的寄存器地址stc型号不同地址不同*****************************************/
sfr IAP_DATA    = 0xE2;   //IAP操作时的数据寄存器(从flash读数据和写数据都在此处)
sfr IAP_ADDRH   = 0xE3;   //IAP操作时的地址寄存器高8位
sfr IAP_ADDRL   = 0xE4;   // IAP操作时的地址寄存器低8位
sfr IAP_CMD     = 0xE5; //IAP命令模式寄存器(需命令触发寄存器触发方生效)3种模式
sfr IAP_TRIG    = 0xE6; //IAP命令触发寄存器,在IAP_CONTR.7=1时;对IAP_TRIG先写//入46h,再写入B9h,IAP命令生效
sfr IAP_CONTR   = 0xE7; //IAP控制寄存器
 
/***********定义Flash 操作等待时间及允许IAP/ISP/EEPROM 操作的常数(属于IAP_CONTR寄存器)***********/
#define ENABLE_ISP 0x82     //实测  12M  11.0592M 都可以使用

void DELAY_MS (unsigned int a)
{
    unsigned int i;
    while ( --a != 0 )
    {
        for (i=0;i<=110;i++);
    }
}

/*************关闭IAP功能子程序*****************************/
void IAP_Disable()      //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
{                       //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关    
    IAP_CONTR = 0;      //关闭IAP 功能
    IAP_CMD   = 0;      //清命令寄存器,使命令寄存器无命令,此句可不用
    IAP_TRIG = 0;       //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
    IAP_ADDRH = 0;      //高八位地址清0
    IAP_ADDRL = 0;      //低八位地址清0
}
 
/**********EEPROM读一字节子程序***********************/
unsigned char Byte_Read(unsigned int add)      //读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节
{
    IAP_DATA = 0x00;             //IAP数据寄存器清0
    IAP_CONTR = ENABLE_ISP;      //打开IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x01;              //IAP/ISP/EEPROM 字节读命令
 
    IAP_ADDRH = (unsigned char)(add>>8);    //设置目标单元地址的高8 位地址
    IAP_ADDRL = (unsigned char)(add&0xff);    //设置目标单元地址的低8 位地址
 
    EA = 0;
    IAP_TRIG = 0x46;   //先送 46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xB9;   //送完 B9h 后,ISP/IAP 命令立即被触发起动
    _nop_();
    EA = 1;
    IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
    return (IAP_DATA);
}
 
 
/************EEPROM字节编程子程序**************************/
void Byte_Program(unsigned int add,unsigned char ch)  //字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据
{
    IAP_CONTR = ENABLE_ISP;         //打开 IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x02;                 //IAP/ISP/EEPROM 字节编程命令
 
 
    IAP_ADDRH = (unsigned char)(add>>8);    //设置目标单元地址的高8 位地址
    IAP_ADDRL = (unsigned char)(add&0xff);    //设置目标单元地址的低8 位地址
 
    IAP_DATA = ch;                  //要编程的数据先送进IAP_DATA 寄存器
    EA = 0;
    IAP_TRIG = 0x46;   //先送 46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xB9;   //送完 B9h 后,ISP/IAP 命令立即被触发起动
    _nop_();
    EA = 1;
    IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}
 
/*************EEPROM擦除扇区子程序**************************/
void Sector_Erase(unsigned int add)       //擦除扇区, 入口:DPTR = 扇区地址
{
    IAP_CONTR = ENABLE_ISP;         //打开IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x03;                 //IAP/ISP/EEPROM 扇区擦除命令
 
    IAP_ADDRH = (unsigned char)(add>>8);    //设置目标单元地址的高8 位地址
    IAP_ADDRL = (unsigned char)(add&0xff);    //设置目标单元地址的低8 位地址
 
    EA = 0;
    IAP_TRIG = 0x46;   //先送 46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xB9;   //送完 B9h 后,ISP/IAP 命令立即被触发起动
    _nop_();
    EA = 1;
    IAP_Disable();     //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                       //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}


void main (void){
	
unsigned char mydata  = 0x0F;
unsigned int  address = 0x2000;

P1 = Byte_Read(address);     //读取当前地址存储的8个bit,并显示出来
DELAY_MS(1000);	
	
Sector_Erase(address);       //擦除这个地址所在的扇区
Byte_Program(address,mydata);//写入新的8个bit
P1 = Byte_Read(address);      //读取当前地址存储的8个bit,并显示出来
	

while(1);	
}



2

/*
单片机内置的 EEPROM测试程序
适用 
STC89C51
STC89C52
STC89C53
STC89C54
STC89C58
STC89C510
STC89C512
STC89C514

测试晶振:11.05926M 12M 都可以用 

功能:
读取指定地址的一个字节内容,并显示在8 P1总线上

擦除一个扇区,修改取指定地址的一个字节内容,并显示在8 P1总线上


*/

#include <reg51.h>
#include <intrins.h>

/******************EEPROM用到的sfr中的寄存器地址stc型号不同地址不同*****************************************/
sfr IAP_DATA    = 0xE2;   //IAP操作时的数据寄存器(从flash读数据和写数据都在此处)
sfr IAP_ADDRH   = 0xE3;   //IAP操作时的地址寄存器高8位
sfr IAP_ADDRL   = 0xE4;   // IAP操作时的地址寄存器低8位
sfr IAP_CMD     = 0xE5; //IAP命令模式寄存器(需命令触发寄存器触发方生效)3种模式
sfr IAP_TRIG    = 0xE6; //IAP命令触发寄存器,在IAP_CONTR.7=1时;对IAP_TRIG先写//入46h,再写入B9h,IAP命令生效
sfr IAP_CONTR   = 0xE7; //IAP控制寄存器
 
/***********定义Flash 操作等待时间及允许IAP/ISP/EEPROM 操作的常数(属于IAP_CONTR寄存器)***********/
#define ENABLE_ISP 0x82     //实测  12M  11.0592M 都可以使用

void DELAY_MS (unsigned int a)
{
    unsigned int i;
    while ( --a != 0 )
    {
        for (i=0;i<=110;i++);
    }
}

/*************关闭IAP功能子程序*****************************/
void IAP_Disable()      //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
{                       //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关    
    IAP_CONTR = 0;      //关闭IAP 功能
    IAP_CMD   = 0;      //清命令寄存器,使命令寄存器无命令,此句可不用
    IAP_TRIG = 0;       //清命令触发寄存器,使命令触发寄存器无触发,此句可不用
    IAP_ADDRH = 0;      //高八位地址清0
    IAP_ADDRL = 0;      //低八位地址清0
}
 
/**********EEPROM读一字节子程序***********************/
unsigned char Byte_Read(unsigned int add)      //读一字节,调用前需打开IAP 功能,入口:DPTR = 字节地址,返回:A = 读出字节
{
    IAP_DATA = 0x00;             //IAP数据寄存器清0
    IAP_CONTR = ENABLE_ISP;      //打开IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x01;              //IAP/ISP/EEPROM 字节读命令
 
    IAP_ADDRH = (unsigned char)(add>>8);    //设置目标单元地址的高8 位地址
    IAP_ADDRL = (unsigned char)(add&0xff);    //设置目标单元地址的低8 位地址
 
    EA = 0;
    IAP_TRIG = 0x46;   //先送 46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xB9;   //送完 B9h 后,ISP/IAP 命令立即被触发起动
    _nop_();
    EA = 1;
    IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
    return (IAP_DATA);
}
 
 
/************EEPROM字节编程子程序**************************/
void Byte_Program(unsigned int add,unsigned char ch)  //字节编程,调用前需打开IAP 功能,入口:DPTR = 字节地址, A= 须编程字节的数据
{
    IAP_CONTR = ENABLE_ISP;         //打开 IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x02;                 //IAP/ISP/EEPROM 字节编程命令
 
 
    IAP_ADDRH = (unsigned char)(add>>8);    //设置目标单元地址的高8 位地址
    IAP_ADDRL = (unsigned char)(add&0xff);    //设置目标单元地址的低8 位地址
 
    IAP_DATA = ch;                  //要编程的数据先送进IAP_DATA 寄存器
    EA = 0;
    IAP_TRIG = 0x46;   //先送 46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xB9;   //送完 B9h 后,ISP/IAP 命令立即被触发起动
    _nop_();
    EA = 1;
    IAP_Disable(); //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                    //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}
 
/*************EEPROM擦除扇区子程序**************************/
void Sector_Erase(unsigned int add)       //擦除扇区, 入口:DPTR = 扇区地址
{
    IAP_CONTR = ENABLE_ISP;         //打开IAP 功能, 设置Flash 操作等待时间
    IAP_CMD = 0x03;                 //IAP/ISP/EEPROM 扇区擦除命令
 
    IAP_ADDRH = (unsigned char)(add>>8);    //设置目标单元地址的高8 位地址
    IAP_ADDRL = (unsigned char)(add&0xff);    //设置目标单元地址的低8 位地址
 
    EA = 0;
    IAP_TRIG = 0x46;   //先送 46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xB9;   //送完 B9h 后,ISP/IAP 命令立即被触发起动
    _nop_();
    EA = 1;
    IAP_Disable();     //关闭IAP 功能, 清相关的特殊功能寄存器,使CPU 处于安全状态,
                       //一次连续的IAP 操作完成之后建议关闭IAP 功能,不需要每次都关
}


void main (void){
	
unsigned char mydata1  = 0xF0;
unsigned char mydata2  = 0x0F;
unsigned int  address1 = 0x2000;
unsigned int  address2 = 0x21FF;
	
Sector_Erase(address1);        //为了数据的写入
Byte_Program(address1,mydata1);
Byte_Program(address2,mydata2);
	
P1 = Byte_Read(address1);     //显示出来
DELAY_MS(500);	
P1 = Byte_Read(address2);     //显示出来
DELAY_MS(500);	

	
//Sector_Erase(address1);       //无论是擦除address1还是address2
Sector_Erase(address2);       
P1 = Byte_Read(address1);     //读取到的是0xFF
DELAY_MS(500);	
P1 = Byte_Read(address2);     //读取到的是0xFF
DELAY_MS(500);	

/*
可以证明:
A和B属于用一个扇区
擦除A或者B 字节的地址
再次读取A或B 都已经改变为0xFF
*/
	

while(1);	
}


你可能感兴趣的:(stc,89C51系列,EEPROM测试程序)