STC12C5A60S2 EEPROM 测试



/*
单片机内置的 EEPROM测试程序
适用 :
STC12C5A60S2  只有两个扇区 0x0000~0x01FF,0x0200~02FF
测试晶振:11.05926M 12M 都可以用 




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


*/

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

/******************EEPROM用到的sfr中的寄存器地址stc型号不同地址不同*****************************************/
sfr IAP_DATA    = 0xC2;   //IAP操作时的数据寄存器(从flash读数据和写数据都在此处)
sfr IAP_ADDRH   = 0xC3;   //IAP操作时的地址寄存器高8位
sfr IAP_ADDRL   = 0xC4;   // IAP操作时的地址寄存器低8位
sfr IAP_CMD     = 0xC5; //IAP命令模式寄存器(需命令触发寄存器触发方生效)3种模式
sfr IAP_TRIG    = 0xC6; //IAP命令触发寄存器,在IAP_CONTR.7=1时;对IAP_TRIG先写//入46h,再写入B9h,IAP命令生效
sfr IAP_CONTR   = 0xC7; //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<=600;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 = 0x5a;   //先送 46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xa5;   //送完 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 = 0x5a;   //先送 46h,再送B9h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xa5;   //送完 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 = 0x5a;   //先送 5ah,再送B9h 到ISP/IAP 触发寄存器,每次都需如此
    IAP_TRIG = 0xa5;   //送完 a5h 后,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 = 0x0000;  // 属于第一个扇区
unsigned int  address2 = 0x01FF;  // 属于第一个扇区

/************     系统初始化时  读取一次两个扇区状态 ******************************/	
P1 = Byte_Read(address1);     //显示出来
DELAY_MS(500);	
P1 = Byte_Read(address2);     //显示出来
DELAY_MS(500);	
	
/************     擦除这个扇区的512字节 并写入显得数据 读取一次两个扇区状态 ******************************/	
//Sector_Erase(address1);      //无论是擦除address1还是address2
Sector_Erase(address2);        //无论是擦除address1还是address2
Byte_Program(address1,mydata1);
Byte_Program(address2,mydata2);
P1 = Byte_Read(address1);     //显示出来
DELAY_MS(500);	
P1 = Byte_Read(address2);     //显示出来
DELAY_MS(500);	


/************     擦除这个扇区的512字节 并写入显得数据 读取一次两个扇区状态 ******************************/	
//Sector_Erase(address1);      //无论是擦除address1还是address2
Sector_Erase(address2);        //无论是擦除address1还是address2
P1 = Byte_Read(address1);      //P1 的led灯都不亮
DELAY_MS(500);	
P1 = Byte_Read(address2);      //P1 的led灯都不亮
DELAY_MS(500);	




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

while(1);	
}


本文出自 “魂斗罗” 博客,转载请与作者联系!

你可能感兴趣的:(测试,eeprom,STC12C5A60S2)