标题:
stc单片机IAP读写规则
[打印本页]
作者:
hujia
时间:
2015-2-18 00:58
标题:
stc单片机IAP读写规则
/*IAP读写规则******************************************
1:EEPROM读取没有规则,按地址读取就可以了.
2:并不需要按地址顺序读取和写入,两种操作都可以设置随机地址.
3:除非进行IAP过程,否则写入EEPROM的数据即使在刷程序后仍然存
在.
4:写操作时,如果当前地址已经写入过一次,则没有进行擦除操作时
,写操作将在原数据上叠加,结果会造成读取错误.
5:擦除操作的地址是扇区地址,而非字节地址,例如60S2有两个扇区
,擦除0x0000H将擦除从0x0000H到0x01FFH的所有512字节数据擦
除0x0001H将擦除从0x0200H到0x03FFH地址内的所有数据
******************************************************/
#include "intrins.h"
//IAP相关端口定义(备忘,不须写)
/*
sfr IAP_DATA = 0xC2; //Flash 数据寄存器
sfr IAP_ADDRH = 0xC3; //Flash 高位地址
sfr IAP_ADDRL = 0xC4; //Flash 低位地址
sfr IAP_CMD = 0xC5; //Flash 命令寄存器
sfr IAP_TRIG = 0xC6; //Flash 命令触发
sfr IAP_CONTR = 0xC7; //Flash 控制寄存器
*/
//IAP命令常数
#define CMD_IDLE 0 //待机
#define CMD_READ 1 //位-读
#define CMD_WRITE 2 //位-程序
#define CMD_ERASE 3 //扇区-擦除
//IAP时间常数
#define ENABLE_IAP 0x80 //如果系统时钟<30MHz
//#define ENABLE_IAP 0x81 //如果系统时钟<24MHz
//#define ENABLE_IAP 0x82 //如果系统时钟<20MHz
//#define ENABLE_IAP 0x83 //如果系统时钟<12MHz
//#define ENABLE_IAP 0x84 //如果系统时钟<6MHz
//#define ENABLE_IAP 0x85 //如果系统时钟<3MHz
//#define ENABLE_IAP 0x86 //如果系统时钟<2MHz
//#define ENABLE_IAP 0x87 //如果系统时钟<1MHz
#define IAP_ADDRESS 0x0000 //STC12C5A60S2 系列 EEPROM 起点地址
//void Delay(unsigned char n);
void IapIdle(); //退出IAP过程
unsigned char IapReadByte(unsigned int addr); //IAP读
void IapWriteByte(unsigned int addr, unsigned char dat); //IAP写
void IapEraseSector(unsigned int addr); //擦除扇区
/**********************************************************
** 函数名称: void IapIdle();
** 功能描述: 退出IAP过程
**********************************************************/
void IapIdle()
{
IAP_CONTR = 0; //关闭 IAP 功能
IAP_CMD = 0; //清除命令寄存器进入待机模式
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0xFF; //IAP指针移动到非 EEPROM 区域
IAP_ADDRL = 0xFF;
}
/**********************************************************
** 函数名称: unsigned char IapReadByte(unsigned int addr);
** 功能描述: 读EEPROM
** 输 入: unsigned int addr 地址
** 输 出: unsigned char dat 数据
**********************************************************/
unsigned char IapReadByte(unsigned int addr)
{
unsigned char dat; //数据缓冲
IAP_CONTR = ENABLE_IAP; //打开 IAP 过程, 并设置等待时间
IAP_CMD = CMD_READ; //设置 ISP/IAP/EEPROM 为读命令
IAP_ADDRL = addr; //设置 ISP/IAP/EEPROM 低位地址
IAP_ADDRH = addr >> 8; //设置 ISP/IAP/EEPROM 高位地址
IAP_TRIG = 0x5a; //发送触发命令 1 (0x5a)
IAP_TRIG = 0xa5; //发送触发命令 2 (0xa5)
_nop_(); //MCU 延迟等待 ISP/IAP/EEPROM 作业完成
_nop_(); //兼容15F104E一个bug,NOP3次
_nop_(); //
dat = IAP_DATA; //读取 ISP/IAP/EEPROM 数据
IapIdle(); //关闭 ISP/IAP/EEPROM 过程
return dat; //返回 Flash 数据
}
/**********************************************************
** 函数名称: void IapWriteByte(unsigned int addr, unsigned char dat);
** 功能描述: 写EEPROM扇区
** 输 入: unsigned int addr 写地址
unsigned char dat 写数据
**********************************************************/
void IapWriteByte(unsigned int addr, unsigned char dat)
{
IAP_CONTR = ENABLE_IAP; //打开 IAP 过程, 并设置等待时间
IAP_CMD = CMD_WRITE; //设置 ISP/IAP/EEPROM 为写命令
IAP_ADDRL = addr; //设置 ISP/IAP/EEPROM 低位地址
IAP_ADDRH = addr >> 8; //设置 ISP/IAP/EEPROM 高位地址
IAP_DATA = dat; //写 ISP/IAP/EEPROM 数据
IAP_TRIG = 0x5a; //发送触发命令 1 (0x5a)
IAP_TRIG = 0xa5; //发送触发命令 2 (0xa5)
_nop_(); //MCU 延迟等待 ISP/IAP/EEPROM 作业完成
_nop_(); //兼容15F104E一个bug,NOP3次
_nop_(); //
IapIdle(); //关闭 ISP/IAP/EEPROM 过程
}
/**********************************************************
** 函数名称: void IapEraseSector(unsigned int addr);
** 功能描述: 擦除EEPROM扇区
** 输 入: unsigned int addr 擦除地址
**********************************************************/
void IapEraseSector(unsigned int addr)
{
IAP_CONTR = ENABLE_IAP; //打开 IAP 过程, 并设置等待时间
IAP_CMD = CMD_ERASE; //设置 ISP/IAP/EEPROM 为擦除命令
IAP_ADDRL = addr; //设置 ISP/IAP/EEPROM 低位地址
IAP_ADDRH = addr >> 8; //设置 ISP/IAP/EEPROM 高位地址
IAP_TRIG = 0x5a; //发送触发命令 1 (0x5a)
IAP_TRIG = 0xa5; //发送触发命令 2 (0xa5)
_nop_(); //MCU 延迟等待 ISP/IAP/EEPROM 作业完成
_nop_(); //兼容15F104E一个bug,NOP3次
_nop_(); //
IapIdle(); //关闭 ISP/IAP/EEPROM 过程
}
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1