?? w78e516b_iap.c
字號(hào):
//5.1看門狗禁止以改寫完畢。
#include <reg54.h>
#include <absacc.h>
#define PROMCSLOW DECD=1;DECC=0;DECB=1;DECA=0;
#define PROMCSHIGH DECD=0;DECC=0;DECB=0;DECA=0;
sbit DOUT=P1^5; //原系統(tǒng)的din/dout定義與datasheet相反。
sbit DIN=P1^4;
sbit SCLK=P1^6;
sbit LED1=P4^3;
sbit LED2=P4^2;
sbit A16=P1^7;
sbit PROMSO=P1^5;
sbit PROMSI=P1^4;
sbit PROMSCK=P1^6;
sfr CHPCON=0xBF; //在編程特殊寄存器定義;
sfr CHPENR=0xF6;
sfr SFRAL=0xC4;
sfr SFRAH=0xC5;
sfr SFRFD=0xC6;
sfr SFRCN=0xC7;
sbit DECA=P1^0; //DECODER ,譯碼器;
sbit DECB=P1^1;
sbit DECC=P1^2;
sbit DECD=P1^3;
unsigned char TLOW,THIGH; //在定時(shí)器0與各iap函數(shù)間傳遞定時(shí)參數(shù);
unsigned char receiveflag=3; //在主函數(shù)與外部中斷0之間傳遞數(shù)據(jù)接收完成標(biāo)志; //3:接收程序數(shù)據(jù)低位,2:接收程序數(shù)據(jù)高位,1:數(shù)據(jù)0:接收完畢;
unsigned char sizelow,sizehigh; //下載程序大小高低位
unsigned int size; //下載程序總大小;
unsigned int cursor; // 下載數(shù)據(jù)存入外存地址,每次中斷后保存,所以定義為全局變量;
unsigned char byt8(unsigned char tx) //向擴(kuò)3100寫入一個(gè)字節(jié)同時(shí)接收一個(gè)字節(jié);
{
unsigned char i;
unsigned char mask;
unsigned char rx;
DOUT=1;
mask=0x80;
rx=0;
for(i=0;i<8;i++) //移位;
{
if(tx & mask)
DIN=1;
else
DIN=0;
SCLK=1;
mask=mask/2;
if(DOUT)
{
rx=rx*2;
rx=rx | 0x01;
}
else
rx=rx*2;
SCLK=0;
}
return(rx);
}
unsigned char utlk(unsigned char tx1,unsigned char tx2) //talk to uart;
{
unsigned char c;
EX0=0;
DECD=1; DECC=0; DECB=0; DECA=0;
c=byt8(tx1);
c=byt8(tx2);
DECD=0; DECC=0; DECB=0; DECA=0;
EX0=1;
return(c);
}
void WatchdogDisable() //此程序中延時(shí)全部從原函數(shù)中去掉了;
{
unsigned char i;
PROMSCK=0;
PROMCSLOW //WREN
for(i=0;i<5;i++) //"00000"
{
PROMSI=0;
PROMSCK=1; //時(shí)鐘上升沿輸入數(shù)據(jù)
PROMSCK=0;
}
for(i=0;i<2;i++) //"11"
{
PROMSI=1;
PROMSCK=1;
PROMSCK=0;
}
PROMSI=0; //"0"
PROMSCK=1;
PROMSCK=0;
PROMCSHIGH
PROMCSLOW //WRSR
for(i=0;i<7;i++) //"0000000"
{
PROMSI=0;
PROMSCK=1;
PROMSCK=0;
}
PROMSI=1; //"1";
PROMSCK=1;
PROMSCK=0;
PROMSI=0; //"0"
PROMSCK=1;
PROMSCK=0;
PROMSI=0; //"0"
PROMSCK=1;
PROMSCK=0;
//"11" for watchdog disable
PROMSI=1;
PROMSCK=1;
PROMSCK=0;
PROMSI=1;
PROMSCK=1;
PROMSCK=0;
for(i=0;i<4;i++) //"0000"
{
PROMSI=0;
PROMSCK=1;
PROMSCK=0;
}
PROMCSHIGH //看門狗片選為高,片外ram片選為低,選中;
}
void Flash() //指示燈1閃爍;
{
unsigned int i;
LED1=0;
for(i=0;i<30000;i++);
LED1=1;
for(i=0;i<30000;i++);
}
void Light() //兩燈同步閃爍;
{
unsigned int i;
LED1=0;
LED2=0;
for(i=0;i<35000;i++);
LED1=1;
LED2=1;
for(i=0;i<35000;i++);
}
void Erase() //64flash擦除;
{
SFRCN=0x22;
TL0=0x3C;
TH0=0xB0;
TCON=0x10;
PCON=0x01;
}
bit BlankCheck() //64k flash 空白檢查;
{
bit flag=1;
unsigned int index;
SFRCN=0x00;
SFRAH=0x00;
SFRAL=0x00;
TLOW=0xFB;
THIGH=0xFF;
for(index=0;index<0xFFFF;index++)
{
TR0=1;
PCON=0x01;
if(SFRFD!=0xFF)
{
flag=0;
break;
}
else
{
SFRAL++;
if(SFRAL==0)
SFRAH++;
}
}
return(flag);
}
void Program() //編程函數(shù)兩分支共用,外存由A16區(qū)分,
{
unsigned int index;
SFRCN=0x21; //設(shè)定為寫操作;
SFRAL=0x00;
SFRAH=0x00;
TLOW=0x5A; //iap時(shí)間設(shè)定; 比標(biāo)準(zhǔn)時(shí)間略長(zhǎng);
THIGH=0xFF;
for(index=0;index<0xFFFF;index++)
{
SFRFD=XBYTE[index];
TR0=1;
PCON=0x01;
SFRAL++;
if(SFRAL==0)
SFRAH++;
}
SFRAL=0x00; //第一個(gè)數(shù)據(jù)重新寫過,否則出錯(cuò),沒搞懂;
SFRAH=0x00;
TLOW=0x5A; //iap時(shí)間設(shè)定; 比標(biāo)準(zhǔn)時(shí)間略長(zhǎng);
THIGH=0xFF;
SFRFD=XBYTE[0x00];
TR0=1;
PCON=0x01;
}
bit Verify() //編程數(shù)據(jù)驗(yàn)證;
{
bit flag=1;
unsigned int index;
SFRCN=0x00;
SFRAH=0x00;
SFRAL=0x00;
TLOW=0xFB;
THIGH=0xFF;
for(index=0;index<0xFFFF;index++)
{
TR0=1;
PCON=0x01;
if(SFRFD!=XBYTE[index])
{
flag=0;
break;
}
else
{
SFRAL++;
if(SFRAL==0)
SFRAH++;
}
}
return(flag);
}
void main()
{
bit iapokflag=0; //編程標(biāo)志位;
unsigned int i; //情外存地址信息;
unsigned char pcon; //chpcon;
unsigned char times=3; //在編程失敗重復(fù)次數(shù);
unsigned j; //for test
WatchdogDisable(); //此函數(shù)出來(lái),已選中片外ram
TCON=0x00;
TMOD=0x01;
IP=0x00;
IE=0x82;
CHPENR=0x87;
CHPENR=0x59;
pcon=CHPCON;
pcon=pcon&0x80;
for(j=0;j<60000;j++)
LED2=0;
LED2=1;
////////////////////////////////////////////////////////////////////////////
if(pcon==0)// not f04k boot mode;從主程序轉(zhuǎn)來(lái)
{
Flash();
CHPENR=0;
//從64k 進(jìn)入,數(shù)據(jù)已準(zhǔn)備好在片外ram地址高端
A16=1;
while((iapokflag!=1)&&(times!=0))
{
Erase(); //擦除片內(nèi)64k flash;
Flash();
if(BlankCheck()==0)
{
times--;
continue;
}
Flash();
Program();
Flash();
if(Verify()==0)
{
times--;
continue;
}
Flash();
iapokflag=1;
}
if(iapokflag==1) //在編程成功,軟件重啟,執(zhí)行64k程序;
{
Flash();
Flash();
CHPENR=0x87;
CHPENR=0x59;
CHPCON=0x83;
}
while(1) //如果再編程未成功,等常閃;
Light();
}
///////////////////////////////////////////////以下為f04k boot mode 處理,硬啟動(dòng)處理;
else
{
A16=0; //選中片外ram低端;
for(i=0;i<0xFFFF;i++)
XBYTE[i]=0xFF;
Flash();
//外存清空,閃爍指示;
EX0=1; //中斷設(shè)置;
SCLK=0;
utlk(0xC4,0x00); //下載串口3100初始化
sizelow=0;
sizehigh=0;
size=0;
cursor=0;
while(receiveflag!=0); //等所有數(shù)據(jù)接收完畢
EX0=0;
utlk(0x80,sizehigh); //數(shù)據(jù)接收完畢,返回?cái)?shù)據(jù)長(zhǎng)度;
utlk(0x80,sizelow);
CHPCON=0x03;
CHPENR=0x00;
//開始編程,數(shù)據(jù)位于片外ram低端;
while((iapokflag!=1)&&(times!=0))
{
Erase(); //擦除片內(nèi)64k flash;
Flash();
if(BlankCheck()==0)
{
times--;
continue;
}
Flash();
//從串口再編程操作
Program();
Flash();
if(Verify()==0) //這個(gè)函數(shù)有問題!
{
times--;
continue;
}
Flash();
iapokflag=1;
}
if(iapokflag==1)
{
Flash();
Flash();
Flash();
while(1)
{
LED1=0; //兩燈常亮,編程完畢;
LED2=0;
}
}
else
{
LED2=0; //一燈閃,一燈常亮,編程失敗;
while(1)
Flash();
}
}
}
void DownLoad() interrupt 0 //下載串口中斷服務(wù)程序;
{
unsigned char temp;
temp=utlk(0x00,0x00);
if(receiveflag==1)
{
XBYTE[cursor]=temp;
cursor++;
if(cursor==size) //程序數(shù)據(jù)扔到外存;
receiveflag=0; //所有數(shù)據(jù)接收完畢,置標(biāo)志位為零;
return;
}
else
if(receiveflag==3)
{
sizelow=temp; //程序數(shù)據(jù)長(zhǎng)度低位;
receiveflag--;
}
else
if(receiveflag==2)
{
sizehigh=temp;
receiveflag--;
size=sizehigh*256+sizelow;
}
}
void Timer0() interrupt 1 //定時(shí)器1中斷服務(wù)程序;
{
TR0=0;
TL0=TLOW;
TH0=THIGH;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -