用Delphi 實現串口通訊,常用的幾種方法為:使用控件如MSCOMM和SPCOMM,使用API函數或者在Delphi 中調用其它串口通訊程序。利用API編寫串口通信程序較為復雜,需要掌握大量通信知識,其優點是可實現的功能更強大,應用面更廣泛,更適合於編寫較為復雜的低層次通信程序。相比較而言,利用SPComm控件則相對較簡單,該控件具有豐富的與串口通信密切相關的屬性及事件,提供了對串口的各種操作。
使用控件這一方法容易掌握,而SPCOMM支持多線程,所以SPCOMM控件的應用更加廣泛。結合實例詳細介紹SPCOMM的使用。
一.SPCOMM控件的安裝
1.選擇下拉菜單Component的第二項Install Component 。
圖1
彈出圖1所示的窗口,在Unit file name 處填寫控件SPCOMM控件所在路徑,其它可用默認值,點擊OK按紐。
2.安裝成功後,system控件面板中將出現一個紅色控件COMM。現在使用COMM控件可以象Delphi自帶控件一樣使用.。
二.SPCOMM的主要屬性,方法和事件
1.屬性
CommName:填寫COM1,COM2…等串口的名字,在打開串口前,必須填寫好此值。
BaudRate:設定波特率9600,4800等,根據實際需要來定,在串口打開後也可更改波特率,實際波特率隨之更改。
ParityCheck:奇偶校驗。
ByteSize:字節長度_5,_6,_7,_8等,根據實際情況設定。
Parity:奇偶校驗位
pBits:停止位
SendDataEmpty:這是一個布爾屬性,為true時表示發送緩存為空,或者發送隊列裡沒有信息;為False時表示表示發送緩存不為空,或者發送隊列裡有信息。
2.方法
Startcomm過程用於打開串口,當打開失敗時通常會報錯,錯誤主要有7種:
⑴串口已經打開 ;
⑵打開串口錯誤 ;
⑶文件句柄不是通訊句柄;
⑷不能夠安裝通訊緩存;
⑸不能產生事件 ;
⑹不能產生讀進程;
⑺不能產生寫進程;
StopComm過程用於關閉串口,沒有返回值。
函數WriteCommData(pDataToWrite: PChar;dwSizeofDataToWrite:Word ): boolean 用於發送一個字符串到寫線程,發送成功返回true,發送失敗返回false, 執行此函數將立即得到返回值,發送操作隨後執行。函數有兩個參數,其中 pdatatowrite是要發送的字符串,dwsizeofdatatowrite 是發送的長度。
3.事件
OnReceiveData : procedure (Sender: TObject;Buffer: Pointer;BufferLength: Word) of object
當輸入緩存有數據時將觸發該事件,在這裡可以對從串口收到的數據進行處理。Buffer中是收到的數據,bufferlength是收到的數據長度。
OnReceiveError : procedure(Sender: TObject; EventMask : DWord)
當接受數據時出現錯誤將觸發該事件。
三.SPCOMM的使用
下面,我們結合一個串口通訊的例子來說明SPCOMM的使用。
為了實現PC與單片機8051之間的通訊,首先要調通它們之間的握手信號,假定它們之間的通訊協議是,PC到8051一幀數據6個字節,8051到PC一幀數據也為6個字節,當PC發出(F0,01,FF,FF,01,F0)後能收到這樣一幀(F0,01,FF,FF,01,F0),表示數據通信握手成功,兩者之間就可以按照協議相互傳輸數據。在PC方要發送及接受數據需要以下步驟:
1.創建一個新的工程COMM.DPR,把窗體的NAME屬性改為FCOMM,把窗體的標題改為測試通訊,添加控件。
對COMM1(黑色矩形圍住的控件)進行屬性設計,設波特率4800,校驗位無,字節長度_8,停止位_1,串口選擇COM1。Memo1中將顯示發送和接受的數據。選擇File/Save As將新的窗體存儲為Comm.pas。
2.編寫源代碼
變量說明
var
FCOMM: TFCOMM;
VIEwstring:string;
i:integer;
rbuf,sbuf:array[1..6] of byte;
打開串口
procedure TFCOMM.FormShow(Sender: TObject);
begin
comm1.StartComm;
end;
關閉串口
procedure TFCOMM.FormClose(Sender: TObject; var Action: TCloseAction);
begin
comm1.StopComm;
end;
發送數據
自定義的發送過程
procedure senddata;
var
i:integer;
commflg:boolean;
begin
vIEwstring:="";
commflg:=true;
for i:=1 to 6 do
begin
if not fcomm.comm1.writecommdata(@sbuf[i],1) then
begin
commflg:=false;
break;
end;
sleep(2); {發送時字節間的延時}
viewstring:=vIEwstring+inttohex(sbuf[i],2)+" ";
end;
viewstring:="發送"+vIEwstring;
fcomm.memo1.lines.add(vIEwstring);
fcomm.memo1.lines.add("");
if not commflg then messagedlg("發送失敗!",mterror,[mbyes],0);
end;
procedure TFCOMM.Btn_sendClick(Sender: TObject);{發送按鈕的點擊事件}
begin
sbuf[1]:=byte($f0); {幀頭}
sbuf[2]:=byte($01); {命令號}
sbuf[3]:=byte($ff);
sbuf[4]:=byte($ff);
sbuf[5]:=byte($01);
sbuf[6]:=byte($0f); {幀尾}
senddata;{調用發送函數}
end;
接收過程
procedure TFCOMM.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
i:integer;
begin
vIEwstring:="";
move(buffer^,pchar(@rbuf^),bufferlength);
for i:=1 to bufferlength do
viewstring:=vIEwstring+inttohex(rbuf[i],2)+" ";
viewstring:="接受"+vIEwstring;
memo1.lines.add(vIEwstring);
memo1.lines.add("");
end;
如果memo1上顯示發送F0 01 FF FF 0F 和 接受F0 01 FF FF F0
這表示串口已正確的發送出數據並正確的接受到數據,串口通訊成功。