- 积分
- 3553
- 下载分
- 分
- 威望
- 点
- 原创币
- 点
- 下载
- 次
- 上传
- 次
- 注册时间
- 2014-11-13
- 精华
|
马上注册,获取阅读精华内容及下载权限
您需要 登录 才可以下载或查看,没有帐号?注册
x
/*---------------------------------------------------------------------*/
/* --- STC MCU Limited ------------------------------------------------*/
/* --- STC15F4K60S4 系列 内部EEPROM举例--------------------------------*/
/* --- Mobile: (86)13922805190 ----------------------------------------*/
/* --- Fax: 86-755-82905966 -------------------------------------------*/
/* --- Tel: 86-755-82948412 -------------------------------------------*/
/* --- Web: www.STCMCU.com --------------------------------------------*/
/* 如果要在程序中使用此代码,请在程序中注明使用了宏晶科技的资料及程序 */
/* 如果要在文章中应用此代码,请在文章中注明使用了宏晶科技的资料及程序 */
/*---------------------------------------------------------------------*/
//本示例在Keil开发环境下请选择Intel的8058芯片型号进行编译
//假定测试芯片的工作频率为18.432MHz
#include "reg51.h"
#include "intrins.h"
typedef unsigned char BYTE;
typedef unsigned int WORD;
//-----------------------------------------------
sfr IAP_DATA = 0xC2; //IAP数据寄存器
sfr IAP_ADDRH = 0xC3; //IAP地址寄存器高字节
sfr IAP_ADDRL = 0xC4; //IAP地址寄存器低字节
sfr IAP_CMD = 0xC5; //IAP命令寄存器
sfr IAP_TRIG = 0xC6; //IAP命令触发寄存器
sfr IAP_CONTR = 0xC7; //IAP控制寄存器
#define CMD_IDLE 0 //空闲模式
#define CMD_READ 1 //IAP字节读命令
#define CMD_PROGRAM 2 //IAP字节编程命令
#define CMD_ERASE 3 //IAP扇区擦除命令
#define URMD 0 //0:使用定时器2作为波特率发生器
//1:使用定时器1的模式0(16位自动重载模式)作为波特率发生器
//2:使用定时器1的模式2(8位自动重载模式)作为波特率发生器
sfr T2H = 0xd6; //定时器2高8位
sfr T2L = 0xd7; //定时器2低8位
sfr AUXR = 0x8e; //辅助寄存器
//#define ENABLE_IAP 0x80 //if SYSCLK<30MHz
//#define ENABLE_IAP 0x81 //if SYSCLK<24MHz
#define ENABLE_IAP 0x82 //if SYSCLK<20MHz
//#define ENABLE_IAP 0x83 //if SYSCLK<12MHz
//#define ENABLE_IAP 0x84 //if SYSCLK<6MHz
//#define ENABLE_IAP 0x85 //if SYSCLK<3MHz
//#define ENABLE_IAP 0x86 //if SYSCLK<2MHz
//#define ENABLE_IAP 0x87 //if SYSCLK<1MHz
//测试地址
#define IAP_ADDRESS 0x0400
void Delay(BYTE n);
void IapIdle();
BYTE IapReadByte(WORD addr);
void IapProgramByte(WORD addr, BYTE dat);
void IapEraseSector(WORD addr);
void InitUart();
BYTE SendData(BYTE dat);
void main()
{
WORD i;
P1 = 0xfe; //1111,1110 系统OK
InitUart(); //初始化串口
Delay(10); //延时
IapEraseSector(IAP_ADDRESS); //扇区擦除
for (i=0; i<512; i++) //检测是否擦除成功(全FF检测)
{
if (SendData(IapReadByte(IAP_ADDRESS+i)) != 0xff)
goto Error; //如果出错,则退出
}
P1 = 0xfc; //1111,1100 擦除成功
Delay(10); //延时
for (i=0; i<512; i++) //编程512字节
{
IapProgramByte(IAP_ADDRESS+i, (BYTE)i);
}
P1 = 0xf8; //1111,1000 编程完成
Delay(10); //延时
for (i=0; i<512; i++) //校验512字节
{
if (SendData(IapReadByte(IAP_ADDRESS+i)) != (BYTE)i)
goto Error; //如果校验错误,则退出
}
P1 = 0xf0; //1111,0000 测试完成
while (1);
Error:
P1 &= 0x7f; //0xxx,xxxx IAP操作失败
while (1);
}
/*----------------------------
软件延时
----------------------------*/
void Delay(BYTE n)
{
WORD x;
while (n--)
{
x = 0;
while (++x);
}
}
/*----------------------------
关闭IAP
----------------------------*/
void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
/*----------------------------
从ISP/IAP/EEPROM区域读取一字节
----------------------------*/
BYTE IapReadByte(WORD addr)
{
BYTE dat; //数据缓冲区
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_READ; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
dat = IAP_DATA; //读ISP/IAP/EEPROM数据
IapIdle(); //关闭IAP功能
return dat; //返回
}
/*----------------------------
写一字节数据到ISP/IAP/EEPROM区域
----------------------------*/
void IapProgramByte(WORD addr, BYTE dat)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_PROGRAM; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写ISP/IAP/EEPROM数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
/*----------------------------
扇区擦除
----------------------------*/
void IapEraseSector(WORD addr)
{
IAP_CONTR = ENABLE_IAP; //使能IAP
IAP_CMD = CMD_ERASE; //设置IAP命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //等待ISP/IAP/EEPROM操作完成
IapIdle();
}
/*----------------------------
初始化串口
----------------------------*/
void InitUart()
{
SCON = 0x5a; //设置串口为8位可变波特率
#if URMD == 0
T2L = 0xd8; //设置波特率重装值
T2H = 0xff; //115200 bps(65536-18432000/4/115200)
AUXR = 0x14; //T2为1T模式, 并启动定时器2
AUXR |= 0x01; //选择定时器2为串口1的波特率发生器
#elif URMD == 1
AUXR = 0x40; //定时器1为1T模式
TMOD = 0x00; //定时器1为模式0(16位自动重载)
TL1 = 0xd8; //设置波特率重装值
TH1 = 0xff; //115200 bps(65536-18432000/4/115200)
TR1 = 1; //定时器1开始启动
#else
TMOD = 0x20; //设置定时器1为8位自动重装载模式
AUXR = 0x40; //定时器1为1T模式
TH1 = TL1 = 0xfb; //115200 bps(256 - 18432000/32/115200)
TR1 = 1;
#endif
}
/*----------------------------
发送串口数据
----------------------------*/
BYTE SendData(BYTE dat)
{
while (!TI); //等待前一个数据发送完成
TI = 0; //清除发送标志
SBUF = dat; //发送当前数据
return dat;
}
这个是手册上的例程,但是在串口调试中却没有效果。什么原因呢?
|
|
|