有時做一些小實驗或小應用,40pin的51實在太大很不方便,所以參考ATEML AT89C2051 spec 製作了一個AT89C2051 Programmer.
PS:12v,5v 取自 PC
PC Software(BCB)
PS1: 通訊使用串列元件
PS2: 有使用 HEX2BIN.EXE 將 hex,ihx 轉成 bin 格式檔
//--------------------------------------------------------------------------- #include
#pragma hdrstop #include "uMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "YbCommDevice"
#pragma resource "*.dfm"
TFormMain *FormMain;
//---------------------------------------------------------------------------
__fastcall TFormMain::TFormMain(TComponent* Owner)
: TForm(Owner)
{
cbxPort->ItemIndex=0;
}
//---------------------------------------------------------------------------
void __fastcall TFormMain::btnWriteClick(TObject *Sender)
{
if(Comm1->Active==false)
{
cbxPortChange(Sender);
if(Comm1->Active==false) return;
} if(!OpenDialog1->Execute()) return; AnsiString fformat=OpenDialog1->FileName.SubString(OpenDialog1->FileName.Length()-3+1,3);
fformat=fformat.LowerCase();
//if the file is hex format, convert it to bin format.
if((fformat=="ihx")|(fformat=="hex"))
{
AnsiString CmdLine="hex2bin ";
char ShortPath[256+1]={0};
DWORD dwExitCode;
STARTUPINFO StartupInfo={0};
PROCESS_INFORMATION ProcessInfo;
GetShortPathName(OpenDialog1->FileName.c_str(),ShortPath,256);
CmdLine=CmdLine+ShortPath;
if(!CreateProcess(0,CmdLine.c_str(),0,0,false,0,0,0,&StartupInfo,&ProcessInfo))
{
ShowMessage("Can not execute hex2bin!");
return;
}
CloseHandle(ProcessInfo.hThread);
if(WaitForSingleObject(ProcessInfo.hProcess,INFINITE)==WAIT_FAILED)
{
ShowMessage("Wait hex2bin failed!");
return;
}
GetExitCodeProcess(ProcessInfo.hProcess,&dwExitCode);
if(dwExitCode)
{
ShowMessage("Convert hex to bin failed!");
return;
}
OpenDialog1->FileName=ShortPath;
OpenDialog1->FileName=OpenDialog1->FileName.SubString(1,OpenDialog1->FileName.Length()-3)
+"bin";
}
//read binary code
TFileStream *file=new TFileStream(OpenDialog1->FileName,fmOpenRead);
int len=file->Read(wBuf,4096);
delete file; char response=0;
Comm1->Write("e",1);
while(!Comm1->Read(&response,1)){}
if(response!='y')
{ShowMessage("Erase failed!");
return;}
ShowMessage("Erased"); Comm1->Write("a",1);
while(!Comm1->Read(&response,1)){}
if(response!='y')
{ShowMessage("Setting addrress counter to 0 failed!");
return;}
ShowMessage("Set conunter to 0");
int i;
for(i=0;i<(len/16)+1;i++)//write 16 bytes per time
{
Comm1->Write("w",1);
Comm1->Write(wBuf+i*16,16); while(!Comm1->Read(&response,1)){}
if(response!='y')
{ShowMessage("Write failed!\n"+IntToStr(i*16)+"h");
return;}
} ShowMessage("Completed to write " +IntToStr(i*16)+"bytes");
}
//--------------------------------------------------------------------------- void __fastcall TFormMain::btnReadClick(TObject *Sender)
{
if(Comm1->Active==false)
{
cbxPortChange(Sender);
if(Comm1->Active==false) return;
} if(!SaveDialog1->Execute()) return; AnsiString slen;
int len;
InputQuery("Input Length","Length",slen);
len=slen.ToInt(); char response=0;
Comm1->Write("a",1);
while(!Comm1->Read(&response,1)){}
if(response!='y')
{ShowMessage("Setting addrress counter to 0 failed!");
return;}
ShowMessage("Set conunter to 0"); for(int i=0;i<(len/16)+1;i++)
{
Comm1->Write("r",1);
for(int j=0;j<16;)
j=j+Comm1->Read(rBuf+i*16+j,16-j);
} TFileStream *wfile=new TFileStream(SaveDialog1->FileName,fmCreate);
wfile->Write(rBuf,len);
delete wfile;
}
//--------------------------------------------------------------------------- void __fastcall TFormMain::FormDestroy(TObject *Sender)
{
if(Comm1->Active==true)
Comm1->Active=false;
}
//--------------------------------------------------------------------------- void __fastcall TFormMain::cbxPortChange(TObject *Sender)
{
if(Comm1->Active) Comm1->Active=false; Comm1->PortNo=cbxPort->ItemIndex+1; try
{
Comm1->Active=true;
}
catch(Exception &e)
{
ShowMessage(e.Message);
Comm1->Active=false;
return;
}
Comm1->Write("l",1);
char response=0;
Sleep(100);
Comm1->Read(&response,1);
if(response!='y')
{
Panel1->Caption="Programmer no response";
Comm1->Active=false;
return;
}
Panel1->Caption="Programmer linked";
}
//--------------------------------------------------------------------------- void __fastcall TFormMain::FormActivate(TObject *Sender)
{
cbxPortChange(Sender);
}
51 Software
#include #define rst P0_0
#define vs P3_6
#define xinc P3_7
#define prog P3_2 unsigned char combuf[16]; void com_init(void)
{
SCON=0x52;//8,n,1
TMOD=0x20;//timer1 mode1 auto-reload
TH1=0xfd;//11.0592MHZ xtal
TL1=0xfd;
TR1=1;//start timer1
} void com_putc(char c)
{
while(!TI){}
TI=0; SBUF=c;
}
void com_puts(char *p)
{
for(;*p!=0;p++)
com_putc(*p);
} char com_getc(void)
{
while(!RI){}
RI=0; return SBUF;
} void erase(void)
{
unsigned char i,i0;
prog=1;
P3_3=1;
P3_4=0;
P3_5=0;
vs=1;//set vpp to 12v
for(i=0;i<46;i++){}//delay 100us to wait 12v to rise.
prog=0;
for(i=0;i<200;i++)//delay 20ms
for(i0=0;i0<46;i0++){}
prog=1;
for(i=0;i<46;i++){}//delay 100us
vs=0;//set vpp to 5v
for(i=0;i<46;i++){}//delay 100us to wait 12v down to 5v
com_putc('y');
} void write(void)
{
unsigned char i,i0,i1;
for(i=0;i<16;i++)//get 16 bytes code from host
combuf[i]=com_getc();
prog=1;
P3_3=0;
P3_4=1;
P3_5=1;
for(i=0;i<16;i++)
{
P1=combuf[i];
vs=1;//raise vpp to 12v
for(i0=0;i0<46;i0++){}//delay 100us to wait 12v to rise
prog=0;
for(i0=0;i0<4;i0++){}//1us < prog width < 110us
prog=1;
for(i0=0;i0<23;i0++){}//delay 50us
vs=0;
for(i0=0;i0<46;i0++){}//delay 100us to wait 12v to fall
for(i0=0;i0<20;i0++) //twc=2ms
for(i1=0;i1<46;i1++){}
P3_4=0;
P1=0xff;
if(P1!=combuf[i])
{
com_putc('n');
return;
}
P3_4=1;
xinc=1;
xinc=0;
}
com_putc('y');
}
void read()
{
unsigned char i;
vs=0;
prog=1;
P3_3=0;
P3_4=0;
P3_5=1;
P3_2=1;
for(i=0;i<16;i++)//read 16 bytes code and send them to host
{
//P1=0xff;
com_putc(P1);
xinc=1;
xinc=0;
}
} void resetaddr()
{
unsigned char i0,i1;
vs=0;
rst=1;
for(i0=0;i0<20;i0++) //delay 2ms
for(i1=0;i1<46;i1++){}
rst=0;
vs=0;
com_putc('y');
} void main(void)
{
unsigned char cmd;
vs=0;
prog=1;
xinc=0;
rst=0;
com_init();
while(1)
{
cmd=com_getc();
if(cmd=='l') com_putc('y');//link test
if(cmd=='e') erase();
if(cmd=='w') write();
if(cmd=='r') read();
if(cmd=='a') resetaddr();
}
}
此 project 旨在 示範,有任何不適當之處,請自行修改。