Delphi 中串口通信的實現
Delphi 是一種具有功能強大、簡便易用和代碼執行速度快等優點的視覺化快速應用
開發工具,它在構架企業資訊系統方面發揮著越來越重要的作用,許多程式師願意選擇
Delphi 作為開發工具編制各種應用程式。但是,美中不足之處是 Delphi 沒有自帶的串
口通信控制項,在它的幫助文檔裏也沒有提及串口通信,這就給編制通信程式的開發人員
帶來許多不便。
目前,利用 Delphi 實現串口通信的常用的方法有 3 種:一是利用控制項,如
MSCOMM 控制項和 SPCOMM 控制項;二是使用 API 函數;三是調用其他串口通信程式。
其中利用 API 編寫串口通信程式較為複雜,需要掌握大量的通信知識。相比較而言,
利用 SPCOMM 控制項則相對較簡單,並且該控制項具有豐富的與串口通信密切相關的屬性
及事件,提供了對串口的各種操作,而且還支持多線程。下面本文結合實例詳細介紹
SPCOMM 控制項的使用。
SPCOMM 的安裝
1.選擇下拉功能表 Component 中的 Install Component 選項,在 Unit file name 處填寫
SPCOMM 控制項所在的路徑,其他各項可用預設值,點擊 OK 按鈕。
2.安裝後,在 System 控制項面板中將出現一個紅色控制項 COM。現在就可以像 Delphi
自帶控制項一樣使用 COM 控制項了。
SPCOMM 的屬性、方法和事件
1.屬性
●CommName:表示 COM1、 COM2 等串口的名字;
●BaudRate:根據實際需要設定的串列傳輸速率,在串口打開後也可更改此值,實際串列傳輸速率隨之
更改;
●ParityCheck:表示是否需要奇偶校驗;
●ByteSize:根據實際情況設定的位元組長度;
●Parity:奇偶校驗位;
●StopBits:停止位;
●SendDataEmpty:這是一個布林型屬性,為 true 時表示發送緩存為空,或者發送佇列
裏沒有資訊;為 false 時表示發送緩存不為空,或者發送佇列裏有資訊。
2.方法
●Startcomm 方法用於打開串口,當打開失敗時通常會報錯。錯誤主要有 7 種:
⑴串口已經打開;
⑵打開串口錯誤;
⑶檔控制碼不是通信控制碼;
⑷不能夠安裝通信緩存;
⑸不能產生事件;
⑹不能產生讀進程;
⑺不能產生寫進程;
●StopComm 方法用於關閉串口,沒有返回值;
●WriteCommData(pDataToWrite: PChar;dwSizeofDataToWrite:Word )方法是個帶有布林
型返回值的函數,用於將一個字串發送到寫進程,發送成功返回 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)後 8051 能收到一幀( F0,01,FF,FF,01,F0),
表示資料通信握手成功,兩者之間就可以按照協定相互傳輸資料。
創建一個新的工程 COMM.DPR,把表單的 NAME 屬性定為 FCOMM,把表單的標題
定義為測試通信,添加相應的控制項。
1.設定 COMM1 屬性:
●串列傳輸速率: 4800;
●奇偶校驗位:無;
●位元組長度: 8;
●停止位: 1;
●串口: COM1。
Memo1 中將顯示發送和接收的資料。將新的表單存儲為 Comm.pas。
2.編寫源代碼
//變數說明
var
fcomm: TFCOMM;
viewstring:string;
i:integer;
rbuf,sbuf:array[16] 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($ f0); //幀尾
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 01 F0 和接收到 F0 01 FF FF 01 F0,這表示串口已
正確地發送出資料並正確地接收到資料,則串口通信成功。