STC 单片机开发例程(IAP,ISP,KEIL工程)
部份内容
/****************************************************************
//MCS-51单片机底层EEPROM操作库。
//只在STC89C52单片机上实验过
****************************************************************/
//#include "define_stc_flash.h"
#include "../inc/MCS_X51.H"
#include<intrins.h>
bit gint;
/*************************************************
//-----使能IAP----------------
*************************************************/
void flsh_en()
{
gint = EA;
INT_GLOBAL(0); //DISABLE INTERUPT
set_flsh_wait; //set wait time
set_flsh_en; //enable flash operate
}
/**************************************************
//停止IAP
**************************************************/
void flsh_ds()
{
set_flsh_ds; //disable flash operate
set_flsh_trig(0); //dis trig
INT_GLOBAL(gint); //return global int
}
/*从flash中读出一个字节返回*/
UINT8 flsh_rd_byte(UINT16 addx)
{
set_flsh_addr(addx);
flsh_wr_cmd(CMD_READ);
set_flsh_trig(TRIG1);
set_flsh_trig(TRIG2);
_nop_;
return(flsh_rd_data);
}
/******************************************
//从一个扇区内读出一串数据。
//传送参数:扇区内地址,读出个数,读出地址
********************************************/
bit flsh_sector_rd(UINT16 addx,UINT8 num,UINT8 *p)
{
UINT8 i;
if(num > USED_SPACE)
return(0); //超出扇区范围,退出
flsh_en();
for(i = 0;i < num;i++)
{
*p=flsh_rd_byte(addx + i);
p++;
}
flsh_ds(); //禁止iap操作
return(1);
}
/***********************************************
//扇区擦除
***********************************************/
void flsh_sector_earse(UINT16 addx)
{
UINT16 sec_addr = 0xfe00;
sec_addr &= addx; //取得扇区首地址
set_flsh_addr(sec_addr);
flsh_en();
flsh_wr_cmd(CMD_SES); //扇区擦除命令
set_flsh_trig(TRIG1);
set_flsh_trig(TRIG2);
_nop_;
flsh_ds();
}
/***********************************************************
// 写一个字节并校验,如果写正确,返回1,否则返回0
***********************************************************/
bit flsh_wr_verify(UINT16 addx,UINT8 dax)
{
set_flsh_addr(addx);
flsh_wr_cmd(CMD_PGM);
flsh_wr_data(dax); //写数据到iap的数据寄存器。
set_flsh_trig(TRIG1);
set_flsh_trig(TRIG2);
_nop_;
flsh_wr_data(0); //使iap的数据寄存器改变,以便回读。
flsh_wr_cmd(CMD_READ);
set_flsh_trig(TRIG1);
set_flsh_trig(TRIG2);
_nop_;
if(flsh_rd_data == dax)
return(1);
else
return(0);
}
/**************************************************************************
//写一个扇区
//传送16位的目的地址,最好从扇区首地址开始,8位的数据长度,源数据的指针
**************************************************************************/
bit flsh_sector_wr(UINT16 addx,UINT8 num,UINT8 * pdax)
{
UINT8 i;
UINT16 addr;
if(num > USED_SPACE)
return(0); //超出扇区范围退出
addr = addx;
flsh_sector_earse(addx); //擦除目的扇区
flsh_en();
for(i=0;i<num;i++)
{
if(!flsh_wr_verify(addr,*pdax))
{
flsh_ds(); //操作出错,返回前禁止flash操作
return(0);
}
addr++;
pdax++;
}
flsh_ds(); //写完毕禁止FLASH 操作
return(1);
}