1 引 言
在調(diào)試單片機(jī)應(yīng)用系統(tǒng)時(shí),需要反復(fù)地修改用戶程序,為了避免頻繁地使用編程器寫存儲芯片,可以編制單片機(jī)監(jiān)控程序,單片機(jī)的監(jiān)控程序接收來自PC機(jī)的用戶程序,PC機(jī)向單片機(jī)發(fā)送用戶程序。
2 用戶程序格式
用戶將單片機(jī)源程序(.a(chǎn)sm文件)匯編后形成.hex格式的文件,該文件即為發(fā)送至單片機(jī)的十六進(jìn)制可執(zhí)行文件。該文件的結(jié)構(gòu)是:由多行構(gòu)成,行頭為起始符(:),然后是該行有效數(shù)據(jù)字節(jié)數(shù)(滿行時(shí)該數(shù)為10,即十進(jìn)數(shù)16),接下來為兩字節(jié)地址及00,接著是有效數(shù)據(jù),行尾是校驗(yàn)碼及換行符。為了簡化單片機(jī)監(jiān)控程序,僅向單片機(jī)發(fā)送行字節(jié)數(shù)和有效數(shù)據(jù),可用下面的簡單C語句從.hex文件中提取字節(jié)數(shù)和有效數(shù)據(jù):
fscanf(fp,":%2x%4x00",&TranBytes,&Address);
fscanf(fp,"%2x",&TranChar);
3 單片機(jī)監(jiān)控程序的實(shí)現(xiàn)
單片機(jī)監(jiān)控程序?qū)崿F(xiàn)的功能為:接收來自PC機(jī)的用戶程序,將用戶程序放置在用戶程序段,當(dāng)用戶程序接收完畢后,跳轉(zhuǎn)至用戶程序段首地址以執(zhí)行用戶程序。接收采用單字節(jié)方式,即每次只接收一個(gè)字節(jié)。
為了保證單片機(jī)接收用戶程序的準(zhǔn)確性,在接收用戶程序之前需要進(jìn)行握手。筆者所用的握手協(xié)議為:PC機(jī)發(fā)0x55,單片機(jī)收0x55后發(fā)回0x55給PC機(jī),上位PC機(jī)收0x55后再發(fā)0xaa,單片機(jī)收0xaa后發(fā)回,PC機(jī)收0xaa后握手成功,轉(zhuǎn)為發(fā)用戶程序,單片機(jī)轉(zhuǎn)為接收用戶程序。
為了防止單片機(jī)監(jiān)控程序被破壞,需將其固化在EPROM里。筆者所用的80C196系統(tǒng),將地址2000H-7FFFFH固化,監(jiān)控程序從2080開始。這樣一來又涉及到如何使用中斷向量的問題?梢赃@樣解決:在中斷向量地址中放入8000之后的地址,舉例說明,在串行中斷向量地址放入8030H,當(dāng)要使用串行中斷時(shí),在8030中PUSHF和LJMP指令,在8032中放入跳轉(zhuǎn)字節(jié)數(shù)。
利用串行中斷,單片機(jī)接收用戶程序?yàn)橹鹦薪邮眨ㄒ娗皵ⅲ甴ex文件的結(jié)構(gòu))。先接收本行要接收的字節(jié)個(gè)數(shù),然后才將接受的有效數(shù)據(jù)寫入用戶程序段,當(dāng)接受的有效數(shù)據(jù)數(shù)等于該行要接收的字節(jié)個(gè)數(shù)時(shí),準(zhǔn)備接收下一行,如此反復(fù),如果某行要接收的字節(jié)數(shù)為0,則表明用戶程序已經(jīng)傳完,將用戶程序段首址壓入堆棧再彈出(改變中斷返回地址技術(shù)),以執(zhí)行用戶程序,如圖1所示。
4 Win98平臺串行通信的實(shí)現(xiàn)
現(xiàn)在PC機(jī)的應(yīng)用程序絕大多數(shù)都是基于Win98,在進(jìn)行串行通信時(shí)可以通過調(diào)用API函數(shù)來實(shí)現(xiàn)。API函數(shù)提供了對串口的各種操作。串口通信時(shí)通過CreateFile,GetCommState,SetCommState,WriteFile,ReadFile,CloseHandle以及超時(shí)函數(shù)GetCommTimeouts,SetCommTimeouts來實(shí)現(xiàn)。利用CreateFile函數(shù)打開串口,獲取串口句柄,CloseHandle關(guān)閉串口句柄,利用GetComm-State和SetCommState對通信參數(shù)進(jìn)行設(shè)置,WriteFile及ReadFile可對串口進(jìn)行讀寫。在TC環(huán)境下,對串口的操作方式有兩種:查詢方式和中斷方式。在VC環(huán)境下,對串口的操作方式可有多種:查詢方式,同步I/O方式,異步I/O方式,以及事件驅(qū)動(dòng)I/O方式。筆者采用的是異步I/O方式,它可以讓串口操作在后臺執(zhí)行。讓讀寫串口操作有足夠的時(shí)間在后臺執(zhí)行。使用異步I/O方式時(shí),采用如下方式打開串口:
HANDLE m_hCom=CreateFile("COM2",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
FILE_FLAG_OVERLAPPED指明串口為異步方式打開。此時(shí)可以分別在WriteFile和ReadFile