📄 copyer.c
字号:
#include "STC5X.H"
#include <intrins.h>
#include <absacc.h>
sbit SFLS = P4^1; //FLASH选择
sbit CHIP = P3^2; //外接跳线芯片选择,置0为4MbitFLASH,置1为2MbitFLASH,可由程序自定义不同的FLASH
sbit BUZ = P1^7; //指示灯
sbit STAR = P1^3; //启动按钮
sbit A16 = P1^0; //FLASH高于bit15地址
sbit A17 = P1^2;
sbit A18 = P1^1;
#define S_HZK SFLS = 0
#define S_SAV SFLS = 1
#define PAGE0 A18=0; A17=0; A16=0;
#define PAGE1 A18=0; A17=0; A16=1;
#define PAGE2 A18=0; A17=1; A16=0;
#define PAGE3 A18=0; A17=1; A16=1;
#define PAGE4 A18=1; A17=0; A16=0;
#define PAGE5 A18=1; A17=0; A16=1;
#define PAGE6 A18=1; A17=1; A16=0;
#define PAGE7 A18=1; A17=1; A16=1;
#define PAGER A18=1; A17=1; A16=0;
#define PAGEM A18=1; A17=1; A16=1;
#define BAUT9600 0xf4 //9600@22.1184M/6T
#define FALSE 0
#define TRUE 1
#define false 0
#define true 1
//这里如果有字符串写起来会更简洁
unsigned char code EraseChip[18] = {0x0d,0x0a,'E','r','a','s','e',' ','c','h','i','p','.','.','.','.','.','.'};
unsigned char code StartProgrammer[21] = {0x0d,0x0a,'S', 't', 'a','r','t',' ','p','r','o','g','r','a','m','.','.','.','.','.','.'};
unsigned char code VerifyChip[19] = {0x0d,0x0a,'V','e','r','i','f','y',' ','c','h','i','p','.','.','.','.','.','.'};
unsigned char code ProSuc[22] = {0x0d,0x0a,'V','e','r','i','f','y',' ','s','u','c','c','e','s','s','f','u','l','l','y','.'};
unsigned char code ProFail[16] = {0x0d,0x0a,'V','e','r','i','f','y',' ','f','a','i','l','e','d','.'};
unsigned char code Dot[1] = '.';
unsigned char ledlen,ledfls,ledon;
/*================================================================
* 函 数 名: inichip
* 参 数: none
* 功能描述:
* 初始寄存器
* 返 回 值: none
* 作 者: uCore
* 修改日期: 2008-10-21 00:21
===================================================================*/
void inichip(void)
{
SCON = 0x50; //SCON: serail mode 1, 8-bit UART, enable ucvr (REN=1)
TMOD = 0x21; //TMOD: timer 1, mode 2, 8-bit reload
TH1 = BAUT9600; //Baud:4800 fosc=11.0592MHz
IE = 0xA0; //EA - ET2 ES ET1 EX1 ET0 EX0
TCON = 0x54; //TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 //外部中断1为跳变触发
T2CON=0x04;
TH2 = 0x4b; // 定时器初值
TL2 = 0xfd;
TR2 = 1;
AUXR=0x03; //禁用内部扩展RAM
}
/*================================================================
* 函 数 名: timer2Int
* 参 数: none
* 功能描述:
* 定时器2中断处理
* 返 回 值: none
* 作 者: uCore
* 修改日期: 2008-10-21 00:21
===================================================================*/
void timer2Int(void) interrupt 5
{
TF2 = 0; // 溢出标志必须由软件清零
EXF2 = 0; // 捕获标志必须由软件清零
TH2 = 0x4b; // 定时器初值50mS
TL2 = 0xfd;
if(ledlen) //这里由于不缺资源,这几句效率可能不高,呵呵
--ledlen;
else
{
if(ledon)
{
BUZ = !BUZ;
ledlen = ledfls;
}
}
}
/*================================================================
* 函 数 名: SendPackageToCom
* 参 数: dat: 要发送的数据指针; slen: 长度
* 功能描述:
* 查询方式发送数据串
* 返 回 值: none
* 作 者: uCore
* 修改日期: 2008-10-21 00:22
===================================================================*/
void SendPackageToCom(unsigned char *dat, unsigned char slen)
{
unsigned char i;
TI=0;
i=0;
while(i<slen)
{
SBUF=dat[i];
while(!TI); //Sending.......
TI=0;
++i;
}
}
/*================================================================
* 函 数 名: TurnChipAdr
* 参 数: cadr: FLASH高于A15地址
* 功能描述:
* 选择高地址
* 返 回 值: none
* 作 者: uCore
* 修改日期: 2008-10-21 00:22
===================================================================*/
void TurnChipAdr(unsigned char cadr)
{
switch(cadr)
{
case 0:
PAGE0;
break;
case 1:
PAGE1;
break;
case 2:
PAGE2;
break;
case 3:
PAGE3;
break;
case 4:
PAGE4;
break;
case 5:
PAGE5;
break;
case 6:
PAGER;
break;
case 7:
PAGEM;
break;
}
}
/*================================================================
* 函 数 名: Delay_1_0Milli_Seconds
* 参 数: none
* 功能描述:
* 延时10mS
* 返 回 值: none
* 作 者: ucore
* 修改日期: 2006.11.29
===================================================================*/
void Delay_10_Milli_Seconds()
{
unsigned int i;
// WDT_CONTR = 0x34;
i=4000;
while(i)--i; //10ts
}
/*================================================================
* 函 数 名: Check_Toggle_Ready
* 参 数: dst: 地址
* 功能描述:
* 查询FLASH忙状态
* 返 回 值: none
* 作 者: uCore
* 修改日期: 2008-10-21 00:22
===================================================================*/
void Check_Toggle_Ready (unsigned int Dst)
{
unsigned char Loop = TRUE;
unsigned char PreData;
unsigned char CurrData;
unsigned long TimeOut = 0;
PAGE0;
PreData = XBYTE[Dst];
PreData = PreData & 0x40;
while ((TimeOut< 0x07FFFFFF) && (Loop))
{
CurrData = XBYTE[Dst];
CurrData = CurrData & 0x40;
if (PreData == CurrData)
Loop = FALSE; //ready to exit the while loop
PreData = CurrData;
// WDT_CONTR = 0x34;
TimeOut++;
}
}
/*================================================================
* 函 数 名: Program_One_Byte
* 参 数: SrcByte: 数据 hadr:地址16-18 Dst: 地址A0-A15
* 功能描述:
* 往FLASH写入一个字节
* 返 回 值: none
* 作 者: uCore
* 修改日期: 2008-10-21 00:26
===================================================================*/
void Program_One_Byte(unsigned char SrcByte,unsigned char hadr,unsigned int Dst)
{
PAGE0;
XBYTE[0x5555]=0xaa;
XBYTE[0x2aaa]=0x55;
XBYTE[0x5555]=0xa0;
TurnChipAdr(hadr);
XBYTE[Dst] = SrcByte; // transfer the byte to destination
Check_Toggle_Ready(Dst); //wait for TOGGLE bit to get ready
}
/*================================================================
* 函 数 名: Erase_One_Sector
* 参 数: e_adr: 扇区地址 (39SF040:128,39SF020:64)
* 功能描述:
* 擦除一个扇区
* 返 回 值: none
* 作 者: uCore
* 修改日期: 2008-10-21 00:22
===================================================================*/
int Erase_One_Sector(unsigned char e_adr)
{
unsigned int tmp;
/* Issue the Sector Erase command to 39VF040 */
PAGE0;
tmp=(e_adr%16)*0x1000;
TurnChipAdr(e_adr/16);
XBYTE[0x5555]=0xaa;
XBYTE[0x2aaa]=0x55;
XBYTE[0x5555]=0x80;
XBYTE[0x5555]=0xaa;
XBYTE[0x2aaa]=0x55;
XBYTE[tmp] =0x30; /* write data 0x30 to the address */
Delay_10_Milli_Seconds(); /* check DATABOOK for the most */
Delay_10_Milli_Seconds(); /* check DATABOOK for the most */
Delay_10_Milli_Seconds(); /* check DATABOOK for the most */
/* accurate value -- Tse */
}
/*================================================================
* 函 数 名: main
* 参 数: none
* 功能描述:
* 主函数
* 返 回 值: none
* 作 者: uCore
* 修改日期: 2008-10-21 00:15
===================================================================*/
void main(void)
{
unsigned char sectors;
unsigned int raddr,waddr;
unsigned char idata datbuf[128];
unsigned char i,j;
unsigned char pages;
inichip();
if(CHIP) //FLASH型号查询
sectors = 64; //256K,64扇区
else
sectors = 128; //512K
BUZ = 1;
while(1)
{
STAR = 1;
if(!STAR) //启动
{
ledon = 1; //点亮LED,
ledfls = 20; //每秒开关一次
SendPackageToCom(EraseChip,18);
for(i=0; i<sectors; ++i) //擦除
{
Erase_One_Sector(i);
SendPackageToCom(Dot,1);
}
SendPackageToCom(StartProgrammer,21);
pages = sectors/16;
for(i=0; i<pages; ++i) //写入
{
raddr = 0;
waddr = 0;
do{
//read;
TurnChipAdr(i);
S_HZK; //选择源
j = 0;
while(j<128) //读128byte
{
datbuf[j] = XBYTE[raddr+j];
++j;
}
raddr = raddr + 128;
//write
S_SAV; //选中目标
j = 0;
while(j<128) //读128byte
{
Program_One_Byte(datbuf[j],i,waddr+j);
++j;
}
waddr = waddr + 128;
if(raddr%4096==0)
SendPackageToCom(Dot,1);
}while(raddr != 0);
}
SendPackageToCom(VerifyChip,19);
pages = sectors/16;
for(i=0; i<pages; ++i) //校验
{
raddr = 0;
TurnChipAdr(i);
do{
//read;
S_HZK;
j = 0;
while(j<128) //读128byte
{
datbuf[j] = XBYTE[raddr+j];
++j;
}
//write
S_SAV;
j = 0;
while(j<128) //读128byte
{
if(datbuf[j] != XBYTE[raddr+j])goto FAIL; //校验失败,退出
++j;
}
raddr = raddr + 128;
if(raddr%4096==0)
SendPackageToCom(Dot,1);
}while(raddr != 0);
}
FAIL:
if((i == pages) && (raddr == 0)) //成功
{
SendPackageToCom(ProSuc,22);
ledon = 0; //关闭LED
}
else
{
SendPackageToCom(ProFail,16);
ledfls = 10; //出错,LED闪烁速度加快
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -