這篇文章將讓你很快掌握如何擴充Easy 51Pro對器件的支持。當然首先你必須先了解Keil C(如果擴充Easy 51Pro串行編程器)或VC(如果擴充Easy Isp下載線)。本文只介紹基本原理,至于串口通訊的細節和程序界面的制作請看源代碼,里面有詳細的注釋。如果你正在學習單片機與PC的串口通訊,那么這套資料將對你非常有用。
本人編程水平有限,如果你發現了任何問題,歡迎指正。可以Email通知我(nie_zq@163.net)。常見問題我會貼在留言版。如果你是真心的想擴充器件,那么我們可以用QQ討論(QQ:3813420)。如果你想用它作為商業用途,請先與本人聯系。
首先介紹一下我常掛在嘴變的“FID”。FID=“Function IDentification”,我E文不是很好,所以只能取出個這樣的名字。它標識一種器件的編程方法(包括讀,寫,擦等編程操作)。AT89C51和AT89C52,AT89C55的編程方法是一樣的,所以可以用同一個FID,我把他們的FID定義為0,還有AT89CS51與AT89S52的FID=2,AT89C2051的FID=1。編程方法實際上就是控制編程過程的程序吧,C語言里面的程序不是叫Function嗎?
Easy 51Pro串行編程器的擴充
編程器和上位機能協調的工作肯定是要有個通訊協議的。Easy 51Pro的通訊協議很簡單。每次編程操作,上位機發給編程器18個字節,編程器完成編程操作后再回應上位機18個字節(讀,寫過程略有不同,請看源程序)。這18個字節是什么東西呢?
0 | 1 | 2-17 |
編程操作的標識 | FID | 該操作相關的數據 |
編程操作標識是如何定義的?可以從源程序找到答案。
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;
}
FID已經解釋過的,但是如何通過FID調用到控制器件編程操作的子程序呢?還是用程序說話:
在e51pro.h中定義了這樣一個結構:
struct _prowork
//定義編程器的一般操作
{
void (*fpInitPro)();
//編程前的準備工作
void (*fpReadSign)();
//讀特征字
void (*fpErase)();
//擦除器件
BOOL (*fpWrite)(BYTE);
//寫器件
BYTE (*fpRead)();
//讀器件
void (*fpLock)();
//寫鎖定位
void (*fpProOver)();
//編程結束后的工作
};
typedef struct _prowork ProWork;
ProWork
pw;
//編程器一般操作
看見沒有,里面都是一堆函數的指針。沒辦法,Keil C里面沒有class,在struct里面弄一堆函數指針也別有一方風味。
在調用編程操作(就是最上面那一堆程序switch(ComBuf[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;
default:
ComBuf[0]=0xff;
ComBuf[1]=0xff;
//表示無效的操作
break;
}
看看AT89C51PRO.C中的PreparePro00()函數里面搞了些什么?
void PreparePro00()
//設置pw中的函數指針,讓主程序可以調用上面的函數
{
pw.fpInitPro=InitPro00;
pw.fpReadSign=ReadSign00;
pw.fpErase=Erase00;
pw.fpWrite=Write00;
pw.fpRead=Read00;
pw.fpLock=Lock00;
pw.fpProOver=ProOver00;
}
其中InitPro00(),ReadSign00()…..ProiOver00()這些函數都寫在了AT89C51PRO.C中,他們實現了控制編程器對AT89C51編程的具體細節。例如,再看看擦除AT89C51和插除AT89S51的Flash Rom是如何實現的。
void Erase00()//擦除AT89C51
{
InitPro00();
//-----------------------------------------------------------------------------
//根據器件的DataSheet,設置相應的編程控制信號
P2_6=1;
P2_7=0;
P3_6=0;
P3_7=0;
Delay_ms(1);
SetVpp12V();
Delay_ms(1);
P3_2=0;
Delay_ms(10);
P3_2=1;
Delay_ms(1);
//-----------------------------------------------------------------------------
ProOver00();
}
就是根據這個來的:
再看看AT89S51PRO.C中的:
void Erase02()//擦除AT89S51
{
InitPro02();
//-----------------------------------------------------------------------------
//根據器件的DataSheet,設置相應的編程控制信號
OutBuf[0]=0xac;//<<<<<<<<<<<<<<<看下表中的紅框
OutBuf[1]=0x80;//<<<<<<<<<<<<<<<看下表中的紅框
SendInstrc(4);
Delay_ms(500);
//-----------------------------------------------------------------------------
ProOver02();
}
根據這個來的:
在Erase02()中看到調用了SendInstrc(4)這樣一個函數,有必要解釋一下
void SendInstrc(BYTE nByte)
//用MOSI串行發送命令的同時用MISO接收相關數據
{
BYTE n;
for(n=0;n<nByte;n++)
//發送nByte個字節
{
ACC=OutBuf[n];
SCK=0;
MOSI=A_7;
//SCK低電平時輸出一位
SCK=1;
B_7=MISO;
//SCK高電平時接收一位
SCK=0;
MOSI=A_6;
…
…
MOSI=A_1;
SCK=1;
B_1=MISO;
SCK=0;
MOSI=A_0;
SCK=1;
B_0=MISO;
SCK=0;
InBuf[n]=B;
}
}
貼個圖來解釋:
最后來看一個擴充器件的全過程:
1.
看懂器件手冊上Programming的原理和過程細節。
2.
評估一下Easy 51Pro的硬件是否可以實現,包括編程電壓,編程控制信號。一般可以用Isp編程的都沒問題。
3.
讓軟件能識別出器件,這就要用傳說中的“ChipManager”編輯了。用這個程序打開程序目錄下的ChipList.chip文件,然后“增加器件”。也可以在空白列表上直接“增加器件”,然后保存為*.chip文件,再把這個文件合并到ChipList.chip,這就是使用“從文件導入”。
如果你發現編程方法和列表中的某FID一樣,那么就直接用這個FID吧,這是最幸福的。注意:如果特征字沒有3個字節,可以用ff補充。
4.
最關鍵的部分,要你編程解決問題了。如果器件能ISP的盡量用ISP吧。建一個*.c文件,里面實現這些函數:
#include <e51pro.h>
void InitProXX()
//編程前的準備工作
{
…
}
void ProOverXX()
//編程結束后的工作,設置合適的引腳電平
{
…
}
void ReadSignXX()
//讀特征字
{
…
}
void EraseXX()
//擦除器件
{
…
}
BOOL WriteXX(BYTE Data)
//向器件寫一個字節
{
…
}
BYTE ReadXX()
//從器件讀一個字節
{
…
}
void LockXX()
//寫鎖定位
{
…
}
void PrepareProXX()
//設置pw中的函數指針,讓主程序可以調用上面的函數
{
pw.fpInitPro=InitProXX;
pw.fpReadSign=ReadSignXX;
pw.fpErase=EraseXX;
pw.fpWrite=WriteXX;
pw.fpRead=ReadXX;
pw.fpLock=LockXX;
pw.fpProOver=ProOverXX;
}
“XX”就是FID。其實你不必寫太多程序,如果發現它的編程方法與AT89C51相似,那就直接復制AT89C51PRO.C中的源程序,修改一下即可。如果與AT89S51相似呢,那就更好辦了:
void Erase02()//擦除器件
{
InitPro02();
//-----------------------------------------------------------------------------
//根據器件的DataSheet,設置相應的編程控制信號
OutBuf[0]=0xac;//<<<<<<<<<<<<<<<<<<修改這個
OutBuf[1]=0x80;//<<<<<<<<<<<<<<<<<<修改這個
SendInstrc(4);//<<<<<<<<<<<<<<<<<<<<注意要用幾個字節
Delay_ms(500);
//-----------------------------------------------------------------------------
ProOver02();
}
最后把PrepareProXX()添交到e51Pro.C中:
///////////////////////////////////////////////////////////////////////////////////////////////////
//所支持的FID,請在這里繼續添加
///////////////////////////////////////////////////////////////////////////////////////////////////
extern void PreparePro00();//FID=00:AT89C51編程器
extern void PreparePro01();//FID=01:AT89C2051編程器
extern void PreparePro02();//FID=02:AT89S51編程器
extern void PrepareProXX();//<<<<<<<<<<<<<<<<<<<<<<<<<<<添加到末尾
還有:
switch(ComBuf[1])
//根據FID設置(ProWork)pw中的函數指針
{
case 0:
//at89c51編程器
PreparePro00();
break;
case 1:
//at89c2051編程器
PreparePro01();
break;
case 2:
//at89s51編程器
PreparePro02();
break;
//case 3:
//擴充器件時,請繼續向下添加
//
PrepareProXX();<<<<<<<<<<<<<<<<<<<<<<<<添加到末尾
//
break;
default:
ComBuf[0]=0xff;
ComBuf[1]=0xff;//表示無效的操作
break;
}
5.測試你的程序,成功后把它貼出來與大家分享,可以先發個Email給我。
如果你看完了《Easy 51Pro編程器的原理與擴充》,那么你看這篇文章將更加容易。你會發現ProWork和class CIsPro的原理完全一樣,其實ProWork就是模仿了CIsPro。我管CIsPro叫“ISP編程方法類”。
看本文,你可能需要一點C++的基礎知識。本文主要是幫助用戶掌握對EasyISP進行擴充的原理和方法,所以討論重點將放在CParlPro和CIsPro,需要了解其他細節可以去看源程序。另外附VC源代碼,在VC6.0上就可以編譯出一個EPro.exe的可執行文件。不過本程序使用了Code Jock的Xtreme Toolkit界面解決方案,需要先下載安裝(至少要裝15分鐘)。如果編譯時提示找不到dll,請把winio.dll,winio.sys,hook.dll,XT2000Lib.dll拷貝到程序所在的目錄
Easy 51Pro的應用程序框架:
CEProDlg:對話框界面接收用戶操作,把用戶操作轉換成對CPro對象中的函數調用 | |
CPro:根據用戶的選擇,建立CParlPro對象(如果使用并口下載線)或CSerialPro對象(如果使用串行編程器);管理CParlPro對象和CSerialPro對象,為它們提供與用戶界面的通訊;建立兩快64k的緩沖1和緩沖2,提供一些管理緩沖的函數;管理器件列表,可以通過特征字查詢到與之匹配的器件。 | |
CParlPro派生自CParallelPort CParallelPort:負責安裝驅動程序,提供豐富的函數方便對并口進行操作。 CParlPro:封裝了ISP編程的一般流程,通過CIsPro的派生類對象控制并口對器件進行編程。 | CSerialPro派生自CSerialPort CSerialPort:提供豐富的函數方便串口通訊 CSerialPort:把CPro傳遞過來的用戶操作信息轉換成編程命令按照協議發送給編程器 |
由于CParallelPort中設計了這樣一些函數:
BOOL SetPinLogic(int nPin,BOOL bLogic);
//設置指定引腳,bLogic=1高電平,bLogic=0低電平
BOOL GetPinLogic(int nPin);
//得到指定引腳的電平
BOOL SetPinL(int nPin);
//設置指定引腳為低電平
BOOL SetPinH(int nPin);
//設置指定引腳為高電平
他們可以通過并口引腳號對并口的某個引腳進行操作,這就使Easy ISP天生具備支持任何下載線的能力。看看是怎么支持的:
int
m_nPinMosi;
//控制MOSI所用的并口引腳
int
m_nPinMiso;
//控制MISO所用的并口引腳
int
m_nPinRst;
//控制RST所用的并口引腳
int
m_nPinSck;
//控制SCK所用的并口引腳
int
m_nPinLe;
//控制器件鎖存所用的并口引腳
int
m_nPinOe;
//控制器件OE所用的并口引腳
int
m_nPinR1;
//保留引腳1
int
m_nPinR2;
//保留引腳2
BOOL m_bLe;
//鎖存有效時的電平
BOOL m_b2Le;
//鎖存無效時的電平
BOOL m_bOe;
//OE有效時的電平
BOOL m_b2Oe;
//OE無效時的電平
上面這一些變量保存了下載線用到的所有并口引腳號。這么多引腳資源,應該夠用了吧。要知道MOSI,MISO,SCK這些引腳的用途可以看《Easy 51Pro編程器的原理與擴充》。在初始化的時候會把這些變量賦予設定的值。
if(nProType==1)//Easy ISP下載線
{
CString strEasyIspIni;
strEasyIspIni=m_strAppPath+"EasyIsp.ini";//從EasyIsp.ini文件獲得引腳配置信息
//如果不存在"EasyIsp.ini"文件,則使用默認的下載線配置(老版本的)
m_nPinMosi=GetPrivateProfileInt("引腳控制","MOSI",14,strEasyIspIni);
m_nPinMiso=GetPrivateProfileInt("引腳控制","MISO",15,strEasyIspIni);
m_nPinSck=GetPrivateProfileInt("引腳控制","SCK",1,strEasyIspIni);
m_nPinRst=GetPrivateProfileInt("引腳控制","RST",16,strEasyIspIni);
m_nPinLe=GetPrivateProfileInt("引腳控制","LE",17,strEasyIspIni);
m_nPinOe=GetPrivateProfileInt("引腳控制","OE",2,strEasyIspIni);
m_nPinR1=GetPrivateProfileInt("引腳控制","R1",3,strEasyIspIni);
m_nPinR2=GetPrivateProfileInt("引腳控制","R2",4,strEasyIspIni);
m_bLe=GetPrivateProfileInt("鎖存控制(LE)","Enable",1,strEasyIspIni);
m_b2Le=GetPrivateProfileInt("鎖存控制(LE)","Disable",0,strEasyIspIni);
m_bOe=GetPrivateProfileInt("輸出控制(OE)","Enable",0,strEasyIspIni);
m_b2Oe=GetPrivateProfileInt("輸出控制(OE)","Disable",1,strEasyIspIni);
}
如果在設置“編程器”中,選擇了EasyISP,那么程序將從EasyIsp.ini中載入引腳的配置信息。
如果程序目錄不存在該文件呢?那就是支持默認的下載線,這個下載線是原來設計的,這樣就解決了程序向上兼容的問題。如果設置“編程器”中選擇了Atmel ByteBlaster下載線或Altera ByteBlaster下載線,那么就會進行下面這些配置。
else if(nProType==2)
//Atmel ByteBlaster下載線
{
m_nPinRst=PIN_SELIN;
//PIN_SELIN這些在ParllelPort.h中做了定義,這是并口引腳的功能號
m_nPinMosi=PIN_D0;
m_nPinMiso=PIN_ACK;
m_nPinSck=PIN_STROBE;
m_nPinLe=PIN_D2;
//不用LE,為了延時假定一個不起作用的引腳
m_bLe=0;
m_b2Le=0;
m_nPinOe=0;
//不用OE
m_nPinR1=m_nPinAf=PIN_AUTO;
//保留
m_nPinR2=m_nPinIni=PIN_INIT;
//保留
}
else if(nProType==3)
//Altera ByteBlaster下載線
{
m_nPinRst=3;
m_nPinMosi=8;
m_nPinMiso=11;
m_nPinSck=2;
m_nPinLe=14;
//控制74244的LE
m_bLe=0;
m_b2Le=0;
//LE常置低電平
SetPinL(14);
//先預置74244'LE為低電平
m_nPinOe=0;
//沒有OE
m_nPinR1=0;
m_nPinR2=0;
//無保留引腳
}
有些東西要提示一下。m_nPinOe是控制器件鎖存的并口引腳號,但74244沒有OE怎么辦呢,那就把m_nPinOe賦為0吧,并口是沒有PIN 0的。還有就是對器件LE的控制。m_bLe表示鎖存有效時的電平,例如74373的LE高電平有效,所以m_bLe=1,
m_b2Le表示鎖存無效時的電平,所以74373的m_b2Le=0;如果需要74373的LE常開啟怎么辦呢?m_bLe=1,m_b2Le=1不就解決問題了嗎!同樣還有m_bOe,m_b2Oe。看看m_nPinLe主要用在了哪里吧。
void CParallelPro::SetSck(BOOL bLogic)
//設置SCK引腳的電平
{
if(bLogic)
SetPinH(m_nPinSck);
else
SetPinL(m_nPinSck);
if(m_nIspSpd==2)
//如果性能設置為“最快”
{
return;
}
else if(m_nIspSpd==1)
//如果性能設置為“較快”
{
SetPinLogic(m_nPinLe,m_bLe);
//開啟鎖存
return;
}
else
//如果性能設置為“一般”
{
SetPinLogic(m_nPinLe,m_bLe);
//開啟鎖存
for(int n=0;n<=1000;n++)
//延時,在LE產生脈沖寬度
{
}
SetPinLogic(m_nPinLe,m_b2Le);
//關閉鎖存
}
}
這段程序的意思是如果性能設置為“一般”,SCK上的信號改變一次,就鎖存一次。如果性能設置為“較快”則把LE開啟,但不關閉。你肯定要問為什么每次都要開啟呢,即使LE重來沒有關閉過?因為這樣可以多一次對并口的訪問,訪問一次并口的會消耗一定的時間,這樣就可以當作極短的延時。所以即使器件沒有LE,或者74244的LE接到了GND,也可以假定一個嗎!如果設置為“最快”呢,就不用鎖存了。性能設置為“一般”時,有一個鎖存過程,鎖存后可以增強抗干擾。
下面這段程序可以參照一下《Easy 51Pro的原理與擴充》中對void SendInstrc(BYTE nByte)的解釋,原理都是一樣,不過這里的程序要獲得“位”就沒有單片機里那么容易了。
void CParallelPro::SckBytes(int nBytes)
//通過下載線與器件通信
{
for(int n=0;n<nBytes;n++)
//要輸出的字節數
{
SetSck(0);
SetMosi((OutBuf[n] & 0x80));
//SCK為低電平時,發送一位
SetSck(1);
if(GetMiso())
//SCK為高電平時,接收一位
{
InBuf[n]=InBuf[n] | 0x80;
}
else
{
InBuf[n]=InBuf[n] & 0x7f;
}
SetSck(0);
SetMosi((OutBuf[n] & 0x40));
SetSck(1);
…
…
}
上面那些程序主要是關于對并口控制的,主要是方便你應用。下面介紹一下CParlPro控制編程的主思路。先介紹一下CIsPro是什么?剛說過CIsPro是“ISP編程方法類”。它是一個純虛類,只有函數定義,沒有函數實現,就像還沒填數額的支票,當然兌不到錢。
class CIsPro
{
public:
BYTE FID;
//該類所支持的FID
CParallelPro* m_pParlPro;
//方便調用到CParallelPro中的資源
virtual void InitIsPro(CParallelPro* pParlPro);
virtual void PreparePro()=0;
//編程前的工作
virtual void ReadSign(BYTE* pBuf)=0;
//讀特征字
virtual void Erase()=0;
//擦除器件
virtual BOOL Write(BYTE Data,int nAddr)=0;
//寫一個單元
virtual BYTE Read(int nAddr)=0;
//讀一個單元
virtual BOOL LockBit(int nBit)=0;
//寫鎖定位
virtual void ProOver()=0;
//編程結束后的工作
CIsPro();
virtual ~CIsPro();
};
這個類定義了對器件編程的一般操作,是不是和串行編程器中的ProWork很相似?從這個類派生出對器件編程的具體方法。再看看這個CIsPro類是怎么被應用的。以AT89S51為例(因為我手頭上只有這種芯片)。現在就是給支票填數額了。
//At89s51Isp.h
class CAt89s51Isp : public CIsPro
{
public:
CAt89s51Isp();
virtual ~CAt89s51Isp();
virtual void InitIsPro(CParallelPro* pParlPro);
virtual void PreparePro();
//編程前的工作
virtual void ReadSign(BYTE* pBuf);
//讀特征字
virtual void Erase();
//擦除器件
virtual BOOL Write(BYTE Data,int nAddr);
//寫一個單元
virtual BYTE Read(int nAddr);
//讀一個單元
virtual BOOL LockBit(int nBit);
//寫鎖定位
virtual void ProOver();
//編程結束后的工作
};
還是挑幾個出來看看究竟吧,最好對照一下DataSheet上的那個表。
//At89s51Isp.cpp
void CAt89s51Isp::Erase()//擦除器件
{
m_pParlPro->OutBuf[0]=0xac;
//根據器件手冊上規定的命令協議
m_pParlPro->OutBuf[1]=0x80;
m_pParlPro->SckBytes(4);
//向器件發編程命令,4個字節
Sleep(500);
//擦除器件要500ms
}
BOOL CAt89s51Isp::Write(BYTE Data,int nAddr)
//寫一個單元
{
int nTimeOut=0;
m_pParlPro->OutBuf[0]=0x40;
//根據器件手冊上規定的命令協議
m_pParlPro->OutBuf[1]=((BYTE*)&nAddr)[1];
//高地址
m_pParlPro->OutBuf[2]=((BYTE*)&nAddr)[0];
//低地址
m_pParlPro->OutBuf[3]=Data;
m_pParlPro->SckBytes(4);
//向器件發編程命令
while(Read(nAddr)!=Data)
//效驗:循環讀,直到讀出與寫入的數相同
{
nTimeOut++;
if(nTimeOut>=1000)
//如果超時了,寫入失敗
return FALSE;
}
return TRUE;
}
BYTE CAt89s51Isp::Read(int nAddr)
//讀一個單元
{
m_pParlPro->OutBuf[0]=0x20;
//根據器件手冊上規定的命令協議
m_pParlPro->OutBuf[1]=((BYTE*)&nAddr)[1];
//高地址
m_pParlPro->OutBuf[2]=((BYTE*)&nAddr)[0];
//低地址
m_pParlPro->SckBytes(4);
//向器件發編程命令
return m_pParlPro->InBuf[3];
//該單元的數據
}
void CAt89s51Isp::PreparePro()
//編程前的準備工作
{
m_pParlPro->SetRst(0);
//RST置低電平
m_pParlPro->SetMosi(0);
//MOSI置低電平
m_pParlPro->SetSck(0);
//SCK置低電平
Sleep(10);
m_pParlPro->SetRst(1);
//編程前RST要置高點平
Sleep(10);
m_pParlPro->OutBuf[0]=0xac;
//注意這里,按照ATMEL DataSheet的規定,任何編程操作前
m_pParlPro->OutBuf[1]=0x53;
//必須先發送Programming Enable的命令,安排在這里最合適
m_pParlPro->SckBytes(4);
}
還是貼那個出表來看一下吧!
還有一個函數千萬別忘了:
CAt89s51Isp::CAt89s51Isp()
{
m_pParlPro=NULL;
FID=0x02;
//該類所支持的FID
}
最后再看看CParlPro是如何使用CIsPro的:
CParlPro有個這樣的東西:
CArray<CIsPro*,CIsPro*> m_arIsp;
//Isp編程方法隊列
在CParlPro的構造函數中:
CParallelPro::CParallelPro()
{
m_arIsp.Add(new CAt89s51Isp);
//把所有的Isp編程方法對象加入到隊列
}
當用戶對選擇的某器件編程時須要先得到該器件的編程方法
CIsPro* CParallelPro::GetIsPro(BYTE FID)
//查找支持該FID的"Isp編程方法對象"
{
for(int n=0;n<m_arIsp.GetSize();n++)
if(m_arIsp.GetAt(n)->FID==FID)
//從隊列中找出支持該器件FID的編程方法
return m_pIsPro=m_arIsp.GetAt(n);
//設置當前"Isp編程方法對象"指針
return NULL;
}
例如用戶發出擦除AT89S51的命令后:
void CParallelPro::Erase(BYTE FID)
{
if(m_bThread)
//如果上一次操作線程還沒結束
{
m_pPro->Notify(PRO_INVALID);
return;
}
if(GetIsPro(FID)==NULL)
//查詢是否支持該FID,并獲得編程方法
{
m_pPro->Notify(PRO_WORK_INVALID);
return;
}
m_nCurWork=2;
//當前操作標識
AfxBeginThread(ProWorkThread,this);
}
獲得編程方法后當然是要使用該編程方法了,使用編程方法是在ProWorkThread線程中進行的,創建另外一個線程就是為了避免在讀,寫這些編程過程中,窗口界面停止響應。ProWorkThread是如何使用這些編程方法的,你一看源代碼就知道了。
最后再總結一下擴充Easy ISP的步驟:
步驟1,2,3,和《Easy 51Pro的原理與擴充》中介紹的一樣。
4.從CIsPro中派生出一個類,實現這個類中的所有函數。最好以CAt89s51Isp為模板,修改一下就可以了。還有記得這里:
CParallelPro::CParallelPro()
{
m_arIsp.Add(new CAt89s51Isp);
//把所有的Isp編程方法對象加入到隊列
m_arIsp.Add(new 你的Isp方法類);
//<<<<<<<<<<<<<<<<<<<<<<<
}
5.測試你的程序,成功后把它貼出來與大家分享,可以先發個Email給我。
Easy 51Pro v2.0 制作及使用說明
Easy 51Pro的第一個版本由于制作簡單,操作方便一發布就受到了大家的熱烈歡迎。很多網友自制成功后已經感受到了ISP編程技術是如何的爽,看到他們這么爽我也感到無比的高興和興奮,這也成了我開發第2個版本的動力。
努力奮斗一個月終于設計出了第2版。這個版本的設計目標:更好用,容易自制,容易擴充,更穩定,更靈活。
V2.0的新特性:
支持hex文件了
用戶自己可以擴充器件
重載的文件對話框,讓你不必到處找文件
熱鍵支持,讓你調試程序時效率更高
靈活的程序設計,甚至可以讓整套軟件在其他編程器硬件上運行
可以支持任何下載線,讓你有更多選擇
設計了串行通訊超時程序,減少了掉線現象
下載線,編程器都有相關的調試程序,讓你制作時更輕松,提高了成功率
開放源代碼和詳細的原理說明,用戶可以根據自己的要求進行修改
別看界面和上一個版本差不多,里面的東西可全部換了,使用還是一樣。點擊“自動完成”后,就會一項一項的往下進行。最優的設置就像上面這個圖。緩沖1會自動刷新上一次你打開的文件,所以你不必每燒一次芯片就去打開一次文件。你也可以不點擊“自動完成”,在該界面下“回車”就是的。不在該界面下時可以用“熱鍵”,所以每當編譯完程序后,直接按熱鍵就可以了(默認熱鍵Ctrl+Shift+P)。在調試中頻繁燒片時這個功能顯得很重要。要把按鈕設置成“自動”很簡單,用“鼠標右鍵”點一下就可以了。操作成功或失敗會有不同的聲音提示。成功的聲音提示可能會讓你編程時更興奮,效率更高。如果你覺得聲音聽起來不爽,就在設置里“False”它吧。
這個下面有提示,一看就知道怎么做了吧。有4個編程器選擇。Easy 51Pro串行編程器也是新設計的,原來的那個
電路中12v/5v切換電路改成了12v/5v/0v切換電路,這樣就可以燒AT89C2051了。不過還要使用一對跳線或開關切換(詳細內容在《自制Easy 51Pro串行編程器》)。
Easy ISP下載線可以是任何一種并口下載線,因為我有個這樣的設計:
打開程序目錄下的EasyIsp.ini文件可以編輯控制ISP時所用到的并口引腳。文件下面有詳細的說明。編輯這個文件就可以支持你手中現有的下載線了,同時也解決了軟件向上兼容的問題,如果你是老版本的用戶請把這個文件刪除。但我還是推薦一款我新設計的下載線,就是用的上面這個配置(其實每根線接個電阻比接根導線更容易焊,那就和Atmel的圖一樣了):
其實這個電路就是從Altera
下載線和Atmel
下載線中抄來了一點。我覺得使用74373的OE很有必要,編程完畢后可以設置為高阻,這樣就不會影響單片機的那幾個引腳。使用LE可以保持當前的信號狀態,增加了抗干擾。R1,R2是為以后擴充其他器件而保留的。這個電路在我的電腦上運行得很穩定了,如果你對電路的穩定性還存在懷疑,那么你可以去抄一份適合你的電路,不過要記得特別關照一下SCK這個引腳,不然下載線就會不穩定了。
Altera ByteBlaster下載線用來下載AT89S51的原理圖:
下載線輸出插頭恰好與Atmel規定的一致。
注意:本軟件設置中新增了一個“下載線性能”,里面有3個選擇“一般”,“較快”,“最快”。選擇“一般”改變一次信號就會有一次控制LE的操作(一個脈沖,開啟,關閉);“較快”則每改變一次信號就開啟一次LE,但不會關閉,這是因為對并口訪問一次可以延時,即使器件沒有LE或LE接了高電平;“最快”則不使用LE。請根據你自制下載線的穩定性設置。
下載線做完后,還要對其進行調試。我為大家開發了一個線路調試軟件“IspTest”,功能比上一個版本更強,使用更方便。
同樣它也共享了EasyIsp.ini中的配置。點擊按鈕后用萬用表量那個引腳的電平是否可以控制到位。
雖讓這個東西整個是免費的,但我的服務算做到無微不至了吧。做Easy 51Pro串行編程器也有個調試程序,那是我以前寫的,主要是方便當時學CPLD,測試邏輯是否可以實現。不過后來又添加了調試單片機子程序的功能,做編程器時可以用它來測試線路是否都接好,12v/5v/0v是否可以控制。
這次軟件設計的非常Flexible,從上面對下載線的支持就可以看得出,但最主要的還是對器件的支持。一個人做這個東西不可能做到支持很多器件,沒時間,也沒錢搞。所以我就設計了這樣一個東西:
這上面顯示的器件和Easy 51Pro中下拉列表中的一樣。Easy 51Pro每次啟動都會從一個“ChipList.chip”中載入器件信息,用這個軟件打開“ChipList.chip”就會像上圖這樣。如果列表中沒有你期望的器件也不必著急,自己DIY一個就是。這個DIY的過程已經被我簡化的不能再容易了。
你可以直接向這個列表添加新器件,填入一些器件的信息就可以了,也可以“從文件導入”,就是把另外一個“*.chip”文件中的列表合并到一起。器件列表是給Easy 51Pro軟件識別器件的,光有這個還不行,還必須讓它知道該器件編程的方法。
這個就要你編程序了。Easy 51Pro串行編程器的控制器單片機程序是用Keil C寫的,詳細的注釋,可讀性很高,而且我建立了一種框架讓程序可以分層設計,模塊化設計。要支持其他器件可以以我寫好的AT89C51,AT89C0251,AT89S51編程器程序為模板修改即可。如果要擴充Easy Isp下載線的功能,也不難,只要你懂得一點C++就可以了。擴充器件的具體細節請看《Easy 51Pro的原理與擴充》。
最后當然是祝你成功了。沒成功也不要著急,可以在我的留言板提出問題,還有你的好建議。特別歡迎那些幫忙擴充器件的同行網友,還要特別感謝幫忙測試和提供建議的網友們。
可以發郵件給我:nie_zq@163.net
或者用QQ:3813420
|手機版|MCU資訊論壇
( 京ICP備18035221號-2 )|網站地圖
GMT+8, 2025-5-1 06:58 , Processed in 0.045098 second(s), 10 queries , Redis On.
Powered by Discuz! X3.5
© 2001-2025 Discuz! Team.