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. springMVC源码分析--FlashMap和FlashMapManager重定向数据保存

    在上一篇博客springMVC源码分析--页面跳转RedirectView(三)中我们看到了在RedirectView跳转时会将跳转之前的请求中的参数保存到fFlashMap中,然后通过FlashMa ...

  2. springMVC源码分析--页面跳转RedirectView(三)

    之前两篇博客springMVC源码分析--视图View(一)和springMVC源码分析--视图AbstractView和InternalResourceView(二)中我们已经简单的介绍了View相 ...

  3. myEclipse开发内存溢出解决办法myEclipse调整jvm内存大小java.lang.OutOfMemoryError: PermGen space及其解决方法

    摘要: tomcat部署多个项目后,启动tomcat正常,访问项目时却会出现该错误在网上查了查又试了好几次,才解决,将解决方法记录下来,以方便以后查看或让遇到同样问题的朋友有个参考 PermGen s ...

  4. python 全栈开发,Day130(多玩具端的遥控功能, 简单的双向聊天,聊天记录存放数据库,消息提醒,玩具主动发起消息,玩具主动发起点播)

    先下载github代码,下面的操作,都是基于这个版本来的! https://github.com/987334176/Intelligent_toy/archive/v1.3.zip 注意:由于涉及到 ...

  5. Thread类中的join方法

    package charpter06; //类实现接口public class Processor implements Runnable { // 重写接口方法 @Override public v ...

  6. Java编程的逻辑 (12) - 函数调用的基本原理

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...

  7. linux安装memcached安装以及memcache的php扩展

    https://blog.csdn.net/sshcnwold/article/details/79085082

  8. springboot+thymeleaf简单使用

    关于springboot想必很多人都在使用,由于公司项目一直使用的是SpringMVC,所以自己抽空体验了一下springboot的简单使用. 环境搭建 springbooot的环境搭建可以说很灵活, ...

  9. 一种使用pyinstaller时图标问题解决方案

    一种使用pyinstaller时图标问题解决方案 0x00 场景   使用pyinstaller将.py文件编译成.exe文件时,想要使用自己心仪的图标(.ico)比较麻烦.在使用pyinstalle ...

  10. 【jvm】来自于线上的fullGC分析

    系统最近老年代的内存上升的比较快,三到四天会发生一波fullGC.于是开始对GC的情况做一波分析. 线上老年代2.7G,年轻带1.3G老年代上升较快,3天一波fullGC,并且fullGC会把内存回收 ...