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);  
}

 

转载于:https://my.oschina.net/u/3776585/blog/1616775

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值