?? e51pro.c
字號:
//////////////////////////////////////////////////////////////////////////////////////////////////
//E51Pro.c
//Easy 51Pro編程器主程序,負責通訊,管理編程操作
///////////////////////////////////////////////////////////////////////////////////////////////////
#include <E51Pro.h>
BYTE ComBuf[18];//串口通訊數據緩存,發送和接收都使用
UINT nAddress;//ROM中地址計數
UINT nTimeOut;//超時計數
ProWork pw;//編程器一般操作
void Delay_us(BYTE nUs)//微秒級延時<255us
{
TH0=0;
TL0=0;
TR0=1;
while(TL0<nUs)//利用T0做定時計數器,循環采樣,直到達到定時值
{
}
TR0=0;
}
void Delay_ms(UINT nMs)//豪秒級的延時<65535ms
{
UINT n=0;
TR0=1;
while(n<nMs)////利用T0做定時計數器,循環采樣,直到達到定時值
{
TH0=0;
TL0=20;
while(TH0<4)
{
}
n++;
}
TR0=0;
}
BOOL WaitComm()//等待上位機的命令,18字節
{
BYTE n=0;
RI=0;
while(!RI){}//等待第一個字節
ComBuf[n]=SBUF;
RI=0;
n++;
for(n;n<=17;n++)
{
nTimeOut=0;
while(!RI)
{
nTimeOut++;
if(nTimeOut>10000)//后17個字節都有超時限制
return 0;
}
ComBuf[n]=SBUF;
RI=0;
}
return 1;
}
BOOL WaitResp()//等待上位機回應,1字節,有超時限制
{
nTimeOut=0;
RI=0;
while(!RI)
{
nTimeOut++;
if(nTimeOut>50000)
{
return 0;
}
}
RI=0;
ComBuf[0]=SBUF;
return 1;
}
BOOL WaitData()//寫器件時等待上位機數據,18字節,有超時限制
{
BYTE n;
RI=0;
for(n=0;n<=17;n++)
{
nTimeOut=0;
while(!RI)
{
nTimeOut++;
if(nTimeOut>10000)
{
return 0;
}
}
RI=0;
ComBuf[n]=SBUF;
}
return 1;
}
void SendData()//發送數據或回應操作完成,18字節
{
BYTE n=0;
for(n;n<=17;n++)
{
TI=0;
SBUF=ComBuf[n];
while(!TI){}
TI=0;
}
}
void SendResp()//回應上位機1個字節,在寫器件函數中使用
{
TI=0;
SBUF=ComBuf[0];
while(!TI){}
TI=0;
}
void SetVpp5V()//設置Vpp為5v
{
P3_4=0;
P3_3=0;
}
void SetVpp0V()//設置Vpp為0v
{
P3_3=0;
P3_4=1;
}
void SetVpp12V()//設置Vpp為12v
{
P3_4=0;
P3_3=1;
}
void RstPro()//編程器復位
{
pw.fpProOver();//直接編程結束
SendData();//通知上位機,表示編程器就緒,可以直接用此函數因為協議號(ComBuf[0])還沒被修改,下同
}
void ReadSign()//讀特征字
{
pw.fpReadSign();
SendData();//通知上位機,送出讀出器件特征字
}
void Erase()//擦除器件
{
pw.fpErase();
SendData();//通知上位機,擦除了器件
}
void Write()//寫器件
{
BYTE n;
pw.fpInitPro();//編程前的準備工作
SendData();//回應上位機表示進入寫器件狀態,可以發來數據
while(1)
{
if(WaitData())//如果等待數據成功
{
if(ComBuf[0]==0x07)//判斷是否繼續寫
{
for(n=2;n<=17;n++)//ComBuf[2~17]為待寫入數據塊
{
if(!pw.fpWrite(ComBuf[n]))//<<<<<<<<<<<<<<<<<<<調用寫該器件一個單元的函數
{
pw.fpProOver();//出錯了就結束編程
ComBuf[0]=0xff;
SendResp();//回應上位機一個字節,表示寫數據出錯了
WaitData();//等待上位機的回應后就結束
return;
}
nAddress++;//下一個單元
}
ComBuf[0]=1;//回應上位機一個字節,表示數據塊順利完成,請求繼續
SendResp();
}
else if(ComBuf[0]==0x00)//寫器件結束
break;
else//可能是通訊出錯了
{
pw.fpProOver();
return;
}
}
else//等待數據失敗
{
pw.fpProOver();
return;
}
}
pw.fpProOver();//編程結束后的工作
Delay_ms(50);//延時等待上位機寫線程結束
ComBuf[0]=0;//通知上位機編程器進入就緒狀態
SendData();
}
void Read()//讀器件
{
BYTE n;
pw.fpInitPro();//先設置成編程狀態
SendData();//回應上位機表示進入讀狀態
while(1)
{
if(WaitResp())//等待上位機回應1個字節
{
if(ComBuf[0]==0)//ComBuf[0]==0表示讀結束
{
break;
}
else if(ComBuf[0]==0xff)//0xff表示重發
{
nAddress=nAddress-0x0010;
}
for(n=2;n<=17;n++)//ComBuf[2~17]保存讀出的數據塊
{
ComBuf[n]=pw.fpRead();//<<<<<<<<<<<<<<<<<<<調用寫該器件一個單元的函數
nAddress++;//下一個單元
}
ComBuf[0]=6;//向上位機發送讀出的數據塊
SendData();
}
else
break;//等待回應失敗
}
pw.fpProOver();//操作結束設置為運行狀態
ComBuf[0]=0;//通知上位機編程器進入就緒狀態
SendData();
}
void Lock()//寫鎖定位
{
pw.fpLock();
SendData();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
//所支持的FID,請在這里繼續添加
///////////////////////////////////////////////////////////////////////////////////////////////////
extern void PreparePro00();//FID=00:AT89C51編程器
extern void PreparePro01();//FID=01:AT89C2051編程器
extern void PreparePro02();//FID=02:AT89S51編程器
void main()
{
SP=0x60;
SetVpp5V();//先初始化Vpp為5v
SCON=0x00;
TCON=0x00;
//PCON=0x00;//波特率*2
IE=0x00;
//TMOD: GATE|C/!T|M1|M0|GATE|C/!T|M1|M0
// 0 0 1 0 0 0 0 1
TMOD=0x21;//T0用于延時程序
TH1=0xff;
TL1=0xff;//波特率28800*2,注意PCON
//SCON: SM0|SM1|SM2|REN|TB8|RB8|TI|RI
// 0 1 0 1 0 0 0 0
SCON=0x50;
TR1=1;
Delay_ms(1000);//延時1秒后編程器自舉
ComBuf[0]=0;
SendData();
while(1)//串口通訊采用查詢方式
{
if(!WaitComm())//如果超時,通訊出錯
{
Delay_ms(500);
ComBuf[0]=0;//讓編程器復位,使編程器就緒
}
switch(ComBuf[1])//根據FID設置(ProWork)pw中的函數指針
{
case 0://at89c51編程器
PreparePro00();
break;
case 1://at89c2051編程器
PreparePro01();
break;
case 2://at89s51編程器
PreparePro02();
break;
//case 3:支持新器件時,請繼續向下添加
// break;
//case 4:
// break;
default:
ComBuf[0]=0xff;
ComBuf[1]=0xff;//表示無效的操作
break;
}
switch(ComBuf[0])//根據操作ID跳到不同的操作函數
{
case 0x00:
RstPro();//編程器復位
break;
case 0x01:
ReadSign();//讀特征字
break;
case 0x02:
Erase();//擦除器件
break;
case 0x03:
Write();//寫器件
break;
case 0x04:
Read();//讀器件
break;
case 0x05:
Lock();//寫鎖定位
break;
default:
SendData();
break;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -