找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6793|回复: 2
打印 上一主题 下一主题
收起左侧

51MCU ISP与IAP作用于内部EEPROM

[复制链接]
跳转到指定楼层
楼主
ID:94349 发表于 2015-11-10 02:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ISP和IAP:
ISP(In SystemProgramable):在系统编程,即在已经焊好的板子上,不用取下就可以对其进行编程。
IAP(In ApplicationProgramable):在应用编程。即片子提供一系列机制,当片子在运行程序时,了以提供一种改变Flash数据的方法。

也即:程序可以自己往程序存储器里面写数据或者更改程序,其典型应用就是使用boot或者叫做bootloader的一下段代码来进行跳转,从而进行程序的升级。

ISP/IAP相关寄存器列表:

ISP_DATA---ISP/IAP操作时的数据寄存器,包括:
ISP/IAP从Flash读出的数据放于此处,向Flash写入的数据也放于此处。

ISP_ADDRH---ISP/IAP操作时的地址寄存器高八位
ISP_ADDRL---ISP/IAP操作时的地址寄存器低八位


ISP_CMD---ISP/IAP操作时的命令模式寄存器,须命令触发寄存器触发方可生效,其模式设置如图:

程序在系统ISP程序区时,可以对用户应用程序/数据Flash区(EEPROM)进行字节读/字节编程/扇区擦除,
程序在用户应用程序区时,尽可以对数据Flash区(EEPROM)进行字节读/字节编程/扇区擦除
ST89C51RC/RD+系列MCU出场时已经固化有ISP引导码,并设置为上电复位进入ISP程序去,并且出厂时就已经完全加密。

ISP_TRIG---ISP/IAP操作时的命令触发寄存器。
在ISPEN(ISP_CONTR.7)=1时,对ISP_TRIG 写入46H,在写入B9H,ISP/IAP 命令才会生效。

STC89C52RC,STC89LE52RC内部可用data Flash(EEPROM)地址列表:

每个扇区为5112B,写程序时,将一次修改的数据放在同一个扇区,,因为擦除的时候,一次至少擦除一个扇区的数据。
更新数据前,必须先擦除原来的数据,不能再原来的数据基础上更新内容。

具体实现代码:
-----------------------------------------------------------------------------------------------------------------------
#include
#include

#define  uchar unsigned char
#define uint  unsigned int
-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------
#define RDCommand0X01         //定义ISP操作命令
#define PrgCommand 0X02
#define EraseCommand 0X03

#define    error 1
#define OK  0

#define WaitTime0x01         //定义CPU的等待时间
-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------
sfrISP_DATA=0XE2;            //寄存器声明
sfr ISP_ADDRH=0XE3;
sfr ISP_SDDRL=0XE4;
sfr ISP_CMD=0XE5;
sfr ISP_TRIG=0XE6;
sfr ISP_CONTR=0XE7;
-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------
//打开ISP/IAP功能
void ISP_IAP_Enable(void)
{
   EA=0;                      //关中断
   ISP_CONTR=ISPCONTR &0X18;       //00011000
   ISP_CONTR=ISPCONTR | WaitTime;  //写入硬件延时
   ISP_CONTR=ISPCONTR |0X80;      //ISPEN=1
}
-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------
//关闭ISP/IAP功能
void ISP_IAP_Disable(void)
{
   ISP_CONTR=ISP_CONTR &0X7F;      //ISPEN=0
   ISP_TRIG=0X00;
   EA=1;                     //开中断   
}
-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------
//触发代码
void ISP_Trig(void)
{
   ISP_IAP_Enable();             //打开ISP/IAP功能
    ISP_TRIG=0X46;               //触发ISP/IAP命令字节1
    ISP_TRIG=0XB9;               //触发ISP/IAP命令字节2
   _nop_();
}
-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------
//指定地址---字节读
uchar  Byte_Read(uint byte_addr)
{
    ISP_ADDRH=(uchar)(byte_addr>>8);           //地址赋值
    ISP_ADDRL=(uchar)(byte_addr&0X00FF);
    ISP_CMD=ISP_CMD &0XF8;               //清除低三位
    ISP_CMD=ISP_CMD |RDCommand;            //写入读命令
   ISP_Trig();                            //触发执行
   ISP_IAP_Disable();                      //关闭ISP/IAP功能
    return(ISP_DATA);                     //返回读到的数据
}
-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------
//指定地址---扇区擦除
void Sector_Erase(uint sector_addr)
{
    uintSector_Addr;
    Sector_Addr=sector_addr &0XFE00;         //取扇区地址
    ISP_ADDRH=(uchar)(Sector_Addr>>8);
    ISP_ADDRL=0X00;
    ISP_CMD=ISP_CMD &0XF8;               //清空低三位
    ISP_CMD=ISP_CMD |EraseCommand;         //擦出命令3
   ISP_Trig();                            //触发执行
   ISP_IAP_Disable();                     //关闭ISP/IAP功能
}
-----------------------------------------------------------------------------------------------------------------------

-----------------------------------------------------------------------------------------------------------------------
//指定地址---字节写
void Byte_Write(uint byte_addr,uchar original_data)
{
    ISP_ADDRH=(uchar)(byte_addr>>8);          //取地址
    ISP_ADDRL=(uchar)(byte_addr & 0X00FF);
    ISP_CMD=ISP_CMD &0XF8;               //清除低三位
    ISP_CMD=ISP_CMD |PrgCommand;             //写命令2
    ISP_DATA=original_data;               //写入数据准备
   ISP_Trig();                            //触发执行
   ISP_IAP_Disable();                     //关闭ISP/IAP功能
}
-----------------------------------------------------------------------------------------------------------------------

最后对于代码的一些部分做一定的解释

ISP_ADDRH= (uchar)(Sector_Addr>>8); //Sector_Addr右移8位,然后赋值给ISP_ADDRH
ISP_ADDRL= (uchar)(byte_addr & 0X00FF);//byte_addr与上0X00FF,赋值给ISP_ADDRL

次处:
dataFlash(EEPROM)的最小扇区的地址为:
2000H=0010 0000 0000 0000B ,
共计16为,而ISP_ADDRH共8位,
且为地址寄存器的高八位,右移8位,相当于舍去低8位,把地址寄存器的高8为赋予给ISP_ADDRH

对于寄存器地址,byte_addr与上0X00FF,取byte_addr的低8位,强制转换成uchar,然后赋值给ISP_ADDRL且ISP_ADDRL为地址寄存器的低8位.



评分

参与人数 1黑币 +5 收起 理由
秋葉原48 + 5 很给力!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:258924 发表于 2017-12-20 14:43 | 只看该作者
那个硬件延时什么意思啊
回复

使用道具 举报

板凳
ID:718987 发表于 2023-1-27 13:33 | 只看该作者
荆棘鸟1996 发表于 2017-12-20 14:43
那个硬件延时什么意思啊

就是需要配置运行这条指令CPU需要等待或消耗的时间,stc单片机说明书里规定了的。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表