?? 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 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 + -