STC89C51、52内部都自带有2K字节的EEPROM,54、55和58都自带有16K字节的EEPROM,STC单片机是利用IAP技术实现的EEPROM,内部Flash擦写次数可达100,000 次以上,先来介绍下ISP与IAP的区别和特点。

知识点:ISP与IAP介绍
    ISP:In System Programable 是指在系统编程,通俗的讲,就是片子已经焊板子上,不用取下,就可以简单而方便地对其进行编程。比如我们通过电脑给STC单片机下载程序,或给AT89S51单片机下载程序,这就是利用了ISP技术。
IAP:In Application Programable 是指在应用编程,就是片子提供一系列的机制(硬件/软件上的)当片子在运行程序的时候可以提供一种改变flash数据的方法。通俗点讲,也就是说程序自己可以往程序存储器里写数据或修改程序。这种方式的典型应用就是用一小段代码来实现程序的下载,实际上单片机的ISP功能就是通过IAP技术来实现的,即片子在出厂前就已经有一段小的boot程序在里面,片子上电后,开始运行这段程序,当检测到上位机有下载要求时,便和上位机通信,然后下载数据到存储区。大家要注意千万不要尝试去擦除这段ISP引导程序,否则恐怕以后再也下载不了程序了。
STC单片机内部有几个专门的特殊功能寄存器负责管理ISP/IAP功能的,见表1。
表1 ISP/IAP相关寄存器列表
名称 地址 功能描述 D7 D6 D5 D4 D3 D2 D1 D0 复位值
ISP_DATA E2h Flash数据寄存器                 1111 1111
ISP_ADDRH E3h Flash高字节地址寄存器                 0000 0000
ISP_ADDRL E4h Flash低字节地址寄存器                 0000 0000
ISP_CMD E5h Flash命令模式寄存器 -- -- -- -- -- MS2 MS1 MS0 xxxx x000
ISP_TRIG E6h Flash命令触发寄存器                 xxxx xxxx
ISP_CONTR E7h ISP/IAP 控制寄存器 ISPEN SWBS SWRST -- -- WT2 WT1 WT0 000x x000
ISP_DATA:ISP/IAP操作时的数据寄存器。
ISP/IAP从Flash读出的数据放在此处,向Flash写入的数据也需放在此处。
ISP_ADDRH:ISP/IAP操作时的地址寄存器高八位。
ISP_ADDRL:ISP/IAP操作时的地址寄存器低八位。
ISP_CMD:ISP/IAP操作时的命令模式寄存器,须命令触发寄存器触发方可生效。命令模式如表2所示。
表2 ISP_CMD寄存器模式设置
D7 D6 D5 D4 D3 D2 D1 D0 模式选择
保留 命令选择  
-- -- -- -- -- 0 0 0 待机模式,无ISP操作
-- -- -- -- -- 0 0 1 对用户的应用程序flash区及数据flash区字节读
-- -- -- -- -- 0 1 0 对用户的应用程序flash区及数据flash区字节编程
-- -- -- -- -- 0 1 1 对用户的应用程序flash区及数据flash区扇区擦除
程序在系统ISP程序区时可以对用户应用程序区/数据Flash区(EEPROM)进行字节读/字节编程/扇区擦除;程序在用户应用程序区时,仅可以对数据Flash区(EEPROM)进行字节读/字节编程/扇区擦除。STC89C51RC/RD+系列单片机出厂时已经固化有ISP引导码,并设置为上电复位进入ISP程序区,并且出厂时就已完全加密。
ISP_TRIG:ISP/IAP操作时的命令触发寄存器。
在ISPEN(ISP_CONTR.7) =1时,对ISP_TRIG 先写入46h,再写入B9h,ISP/IAP命令才会生效。
STC89C52RC,STC89LE52RC单片机内部可用Data Flash(EEPROM)的地址如表3所示,其它型号单片机请查阅相关资料。
表3 STC89C52RC、STC89LE52RC单片机内部EEPROM地址表
第一扇区 第二扇区 第三扇区 第四扇区
起始地址 结束地址 起始地址 结束地址 起始地址 结束地址 起始地址 结束地址
2000H 21FFH 2200H 23FFH 2400H 25FFH 2600H 27FFH
第五扇区 第六扇区 第七扇区 第八扇区
起始地址 结束地址 起始地址 结束地址 起始地址 结束地址 起始地址 结束地址
2800H 29FFH 2A00H 2BFFH 2C00H 2DFFH 2E00H 2FFFH
每个扇区为512字节,建议大家在写程序时,将同一次修改的数据放在同一个扇区,方便修改,因为在执行擦除命令时,一次最少要擦除一个扇区的数据(需要提供扇区的首地址),每次在更新数据前都必须要擦除原数据方可重新写入新数据,不能直接在原来数据基础上更新内容。
     注意:上面的是数据存储区的地址,程序存储区地址是从0~1FFF,共8K,程序区只能是ISP编程。
 
以下是自己写的这部分功能代码,因为风格问题,不太喜欢原著代码,感觉自己的还严谨一点。
 
 
/****************************************************************************/
/*                           IAP驱动                                        */
/****************************************************************************/
 
 
/************************************************************************************************************************/
/*ISP/IAP相关寄存器列表*/
/*名称地址功能描述D7D6D5D4D3D2D1D0复位值*/
/*ISP_DATAE2hFlash数据寄存器1111 1111*/
/*ISP_ADDRHE3hFlash高字节地址寄存器0000 0000*/
/*ISP_ADDRLE4hFlash低字节地址寄存器0000 0000*/
/*ISP_CMDE5hFlash命令模式寄存器----------MS2MS1MS0xxxx x000*/
/*ISP_TRIGE6hFlash命令触发寄存器xxxx xxxx*/
/*ISP_CONTRE7hISP/IAP 控制寄存器ISPENSWBSSWRST----WT2WT1WT0000x x000*/
/************************************************************************************************************************/
 
 
/************************************************************************************/
/* ISP_CMD寄存器模式设置*/
/* D7D6D5D4D3D2D1D0模式选择*/
/* 保留命令选择*/
/* ----------000待机模式,无ISP操作*/
/* ----------001对用户的应用程序flash区及数据flash区字节读*/
/* ----------010对用户的应用程序flash区及数据flash区字节编程*/
/* ----------011对用户的应用程序flash区及数据flash区扇区擦除*/
/************************************************************************************/
 
/*在ISPEN(ISP_CONTR.7) =1时,对ISP_TRIG 先写入46h,再写入B9h,ISP/IAP命令才会生效。*/
 
 
/* 定义常量 */
#define ERROR   0
#define OK      1
 
/* 定义Flash 操作等待时间 */
//#define WAIT_TIME   0x00     //mcu clock 40mhz
//#define WAIT_TIME   0x01     //mcu clock 20mhz
//#define WAIT_TIME   0x02     //mcu clock 10mhz
#define WAIT_TIME   0x03     //mcu clock 5mhz
 
sfr ISP_DATA= 0xe2;  // Flash数据寄存器
sfr ISP_ADDRH= 0xe3;// Flash高字节地址寄存器
sfr ISP_ADDRL= 0xe4;// Flash低字节地址寄存器
sfr ISP_CMD= 0xe5;// Flash命令模式寄存器
sfr ISP_TRIG= 0xe6;// Flash命令触发寄存器
sfr ISP_CONTR= 0xe7;// ISP/IAP 控制寄存器
 
#define CMD_READ 0x01 // 定义IAP的读字节操作
#define CMD_PRGM 0x02// 定义IAP的写字节操作
#define CMD_ERASE 0x03 // 定义IAP的擦除扇区操作
 
/*********************** 打开 ISP,IAP 功能 ***********************/
static void ISPIAPEnable(void)
{
  //EA = 0;       // 关中断
  ISP_CONTR = ISP_CONTR & 0x18;       // 0001,1000
  ISP_CONTR = ISP_CONTR | WAIT_TIME; // 写入硬件延时
  ISP_CONTR = ISP_CONTR | 0x80;       // ISPEN = 1
}
 
 
/*********************** 关闭 ISP,IAP 功能 ***********************/
static void ISPIAPDisable(void)
{
  ISP_CONTR = ISP_CONTR & 0x7f; // ISPEN = 0
  ISP_TRIG = 0x00;
  //EA   = 1;   // 开中断
}
 
/************************* 触发Flash操作 *************************/
static ActiveOperate(void)
{
  bit eacpy;
  eacpy = EA;
  EA = 0;
  ISPIAPEnable();
  ISP_TRIG = 0x46;  // 触发ISP_IAP命令字节1
  ISP_TRIG = 0xb9;  // 触发ISP_IAP命令字节2
  {UINT8 i=2; while(i--);}
  ISPIAPDisable();
  EA = eacpy;
}
 
 
/**************************** 读一字节 ****************************/
static UINT8 IAPReadByte(const UINT16 uiAddr)
{
  ISP_ADDRH = (UINT8)(uiAddr >> 8);// 写地址
  ISP_ADDRL = (UINT8)(uiAddr&0xFF);
  ISP_CMD   = ISP_CMD & 0xf8;// 清低三位
  ISP_CMD   = ISP_CMD | CMD_READ; // 写入读命令
 
  ActiveOperate();// 触发执行
  return (ISP_DATA);    // 返回读到的数据
}
 
/**************************** 写一字节 ****************************/
static void IAPWriteByte(const UINT16 uiAddr, const UINT8 ucData)
{
  ISP_ADDRH = (UINT8)(uiAddr >> 8);// 写地址
  ISP_ADDRL = (UINT8)(uiAddr&0xFF);
  ISP_CMD   = ISP_CMD & 0xf8;// 清低三位
  ISP_CMD   = ISP_CMD | CMD_PRGM; // 写入写命令
  ISP_DATA = ucData;   // 写入数据准备
 
  ActiveOperate();// 触发执行
}
 
/**************************** 擦除一扇区 ****************************/
static void IAPEarseSection(const UINT16 uiAddr)
{
  UINT16uiSecAddr;
 
  uiSecAddr = (uiAddr & 0xfe00); // 取扇区地址
  ISP_ADDRH = (UINT8)(uiSecAddr >> 8);// 写地址
  ISP_ADDRL = 0x00;
  ISP_CMD = ISP_CMD & 0xf8;   // 清低三位
  ISP_CMD = ISP_CMD | CMD_ERASE; // 写入擦除命令
 
  ActiveOperate();// 触发执行
}
 
 
------------------------------------------------------------------------------------------------------------------------
 
 

#include<stc12c5410ad.h>//到宏晶网站下载头文件或自己在现有的头文件上加上相应的寄存器定义即可。
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
         
/****************uart init***********/
void UART_inti(void)
{
AUXR=0x40;//定时器1速度是普通8051的12倍,不分频
TMOD=0x20;//定时器1工作在方式2,用来产生波特率
SCON=0x50;//串口工作在方式1,允许接收
TL1=0xF7;//波特率为38400;FB为115200
TH1=0xF7;
PCON=0x00;//SMOD=0
TR1=1;   //产生波特率 
}

void ISP_write(uint ISP_addr,uchar ISP_data)//stc12c5404启始地址2800h ;IAP_CMD 1读,2写,3擦除
{
ISP_DATA=ISP_data; //送数据
ISP_ADDRL=ISP_addr%256;
ISP_ADDRH=ISP_addr/256;//送高低地址
ISP_CONTR=0x83;//IAP ENABLE ,SET CPU WAIT TIME
ISP_CMD=2;//写字节模式
ISP_TRIG=0x46;
ISP_TRIG=0xB9;//触发启动ISP
_nop_();//等待写入
ISP_CONTR=0x00;//禁止ISP/IAp操作
ISP_CMD=0;
ISP_TRIG=0x00;
}

uchar ISP_read(uint ISP_addr)//stc12c5404启始地址2800h ;IAP_CMD 1读,2写,3擦除
{uchar recivedata;
ISP_ADDRL=ISP_addr%256;
ISP_ADDRH=ISP_addr/256;//送高低地址
ISP_CONTR=0x83;//IAP ENABLE ,SET CPU WAIT TIME
ISP_CMD=1;//写字节模式
ISP_TRIG=0x46;
ISP_TRIG=0xB9;//触发启动ISP
_nop_();//等待读
recivedata=ISP_DATA;
ISP_CONTR=0x00;//禁止ISP/IAp操作
ISP_CMD=0;
ISP_TRIG=0x00;
return recivedata;
}

void ISP_erase(uint ISP_addr)//stc12c5404启始地址2800h ;IAP_CMD 1读,2写,3擦除
{ISP_ADDRL=ISP_addr%256;
ISP_ADDRH=ISP_addr/256;//送高低地址
ISP_CONTR=0x83;//IAP ENABLE ,SET CPU WAIT TIME
ISP_CMD=3;//写字节模式
ISP_TRIG=0x46;
ISP_TRIG=0xB9;//触发启动ISP
_nop_();//等待擦除
ISP_CONTR=0x00;//禁止ISP/IAp操作
ISP_CMD=0;
ISP_TRIG=0x00;
}

//主程序只为测试时随意编写的,可以根据需要做相应的修改即可。
void main(void)
{
uchar returndata;
uint textdata=0x2660;
UART_inti();
while(1)
{SBUF=5;
while(!TI);
TI=0;
while(!RI);
RI=0;
ISP_erase(0x2800);
ISP_write(0x2800,textdata%256);
ISP_write(0x2801,textdata/256);
returndata=ISP_read(0x2800);
SBUF=returndata;       
while(!TI);
TI=0;
returndata=ISP_read(0x2801);
SBUF=returndata;
while(!TI);
TI=0;
}

}

//声明下这是应用在STC的单片机中的。不同的型号地址不一样,改下IAP的地址即可。新出的产品像STC12C5A60S2等,触发的命令也不一样ISP_TRIG=0x46;ISP_TRIG=0xB9;也就是这两条要根据手册修改下即可。。

https://www.cnblogs.com/sky1991/archive/2012/07/01/2572168.html

STC单片机 IAP(EEPROM)的使用的更多相关文章

  1. STC单片机Flash做EEPROM的代码

    STC官方给出的建议: /***************************************************************Author:Liming*** * @brie ...

  2. 单片机成长之路(51基础篇) - 021 STC89C51系列单片机 内部EEPROM 驱动

    最近又看了一下关于stc单片机的知识,感觉在使用中EEPROM是个经常用到的东西,特地学习了一下,给大家分享一下心得,如有不足,多多包涵,废话不多说,一图解千言,先上图: /*------------ ...

  3. 单片机成长之路(51基础篇) - 002 STC单片机冷启动和复位有什么区别

    STC单片机简介 STC单片机是一款增强型51单片机,完全兼容MCS-51,还增加了新的功能,比如新增两级中断优先级,多一个外中断,内置EEPROM,硬件看门狗,具有掉电模式,512B内存等.还支持I ...

  4. STC单片机串口输出ADXL335角度值

    STC单片机串口输出ADXL335角度值: //***************************************************** //名称:单片机串口输出ADXL335角度值 ...

  5. STC 单片机ADC实现原理

    模数转换器原理 数模转换器( analog to digitI converter,ADC),简称为A/D,ADC是链接模拟世界和数字世界的桥梁.它用于将连续的模拟信号转换为数字形式离散信号.典型的, ...

  6. STC单片机控制28BYJ-48步进电机

    STC单片机4*4按键控制步进电机旋转 28BYJ-48型步进电机说明 四相永磁式的含义 28BYJ-48工作原理 让电机转起来 最简单的电机转动程序 电机转速缓慢的原因分析 便于控制转过圈数的改进程 ...

  7. STC单片机掉电断电失电瞬间EEPROM数据保存处理办法(转)

    由于客户在请人设计开发一设备,但是设备用户处总停电,造成设备及其周边耗材损耗严重,因此请我司在现有STC为主要芯片的基础上做掉电瞬间EEPROM里的20个参数保存,上电后通过读取EEPROM中的参数回 ...

  8. STC89C52单片机内部EEPROM驱动

    STC89C52单片机自身带有4K的存储空间,分为8个扇区,每个扇区512字节,第一扇区起始地址为:0x2000, 结束地址为:21FF, 第八扇区起始地址为0x2E00,结束地址是2FFF #inc ...

  9. STM32L系列单片机内部EEPROM的读写

    STM32L系列单片机内部提供了EEPROM存储区域,但实质上,其FLASH也是EEPROM类型,只不过有一块区域被开放出来专门用作EEPROM操作而已.STM32L的EEPROM使用寿命设计为100 ...

随机推荐

  1. (七)dubbo服务集群实现负载均衡

    当某个服务并发量特别大的时候,一个服务延迟太高,我们就需要进行服务集群,例如某个项目一天注册量10万,这个注册功能就必须要进行集群了,否则一个服务无法应付这么大的并发量: dubbo的服务集群很简单, ...

  2. 性能测试四十:Mysql存储过程造数据

    性能测试是基于大量数据的,而进行性能测试之前肯定没那么多数据,所以就要自己准备数据 数据构造方法: 1.业务接口 -- 适合数据表关系复杂 -- 优点:数据完整性比较好2.存储过程 -- 适合表数量少 ...

  3. 【APUE | 08】进程控制

    函数fork 博文链接: 1. 代码示例: #include "apue.h" ; char buf[] = "a write to stdout\n"; in ...

  4. 怎么用pr(Premiere)给视频添加水印

    自己辛辛苦苦剪切的视频,不添加水印,别人肯定会搬走的,作为对视频付出时间的你肯定不想看见这样的事情,下面一起来看看怎么用pr给视频添加水印吧   工具/原料   水印 pr 方法/步骤     首先打 ...

  5. (第1篇)什么是hadoop大数据?我又为什么要写这篇文章?

    摘要: hadoop是什么?hadoop是如何发展起来的?怎样才能正确安装hadoop环境? 这些天,有很多人咨询我大数据相关的一些信息,觉得大数据再未来会是一个朝阳行业,希望能尽早学会.入行,借这个 ...

  6. [转] JavaScript:彻底理解同步、异步和事件循环(Event Loop)

    一. 单线程 我们常说“JavaScript是单线程的”. 所谓单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个.不妨叫它主线程. 但是实际上还存在其他的线程.例如:处理A ...

  7. Eclipse-debug时提示absent line number information的解决办法

    unable to install breakpoint in ...(file name) due to miss line number attributes. midify compliter ...

  8. thinkphp3.2自定义success及error跳转页面

    首先我们需要配置目录 在conf下新建一个config文件 <?php return array( 'TMPL_ACTION_SUCCESS'=>'Public:dispatch_jump ...

  9. Python高级正则

    import re p = re.compile("^[0-9]") m = p.match('13435aSAdb') print(m.group()) 一.上面的第二行和第三行 ...

  10. MySQL安装详细图解整理

    MySQL安装详细图解 2018-08-19  08:32:33 一.MYSQL的安装 1.打开下载的mysql安装文件mysql-5.0.27-win64.zip,双击解压缩,运行“setup.ex ...