Lazarus最吸引人的地方就是她的開發(fā)方式類似Delphi,支持超好用的RAD開發(fā)方式,并且最厲害的地方是她還支持多個(gè)平臺(tái),多個(gè)CPU,例如ARM9的WINCE。
本文要講述的就是“如何使用LAZARUS開發(fā)Wince上的串口程序”,并且,本文的串口程序同時(shí)支持WINCE和WINXP系統(tǒng),當(dāng)然編譯時(shí)要選擇平臺(tái)啦。WINCE與WINXP在本文中的代碼區(qū)別只是OpenPort(‘COM1:’,CBR_9600,8,NOPARITY,ONESTOPBIT);//wince用COM1:表示串口1;WINXP用COM1表示串口1.
一、建立一個(gè)可重用的類,文件名為CE_Series.pas:
unit CE_Series;
interface
uses
Windows,Classes, SysUtils, LResources, StdCtrls,ExtCtrls;
type
TCE_Series = class(TObject)
private
hComm: THandle;
public
Function OpenPort(Port:LPCWSTR;BaudRate,ByteSize,Parity,StopBits:integer):String;
procedure Send(str:String);
Function Receive():String;
procedure ClosePort();
end;
implementation
//===============================================================================================
// 語法格式:OpenPort(Port:LPCWSTR;BaudRate,ByteSize,Parity,StopBits:integer)
// 實(shí)現(xiàn)功能:打開串口
// 參數(shù):port,串口號;例如wince下為從COM1:,COM2:。..。.win32下為COM1,COM2.。..。.. ;其他略,顧名思義哈
// 返回值:錯(cuò)誤信息
//===============================================================================================
function TCE_Series.OpenPort(Port:LPCWSTR;BaudRate,ByteSize,Parity,StopBits:integer):String;
var
cc:TCOMMCONFIG;
begin
result:=‘’;
hComm:=CreateFile(port, GENERIC_READ or GENERIC_WRITE,
0, nil, OPEN_EXISTING, 0, 0); // 打開COM
if (hComm = INVALID_HANDLE_VALUE) then begin // 如果COM 未打開
result:=‘CreateFile Error!’;
exit;
end;
GetCommState(hComm,cc.dcb); // 得知目前COM 的狀態(tài)
cc.dcb.BaudRate:=BaudRate; // 設(shè)置波特率為BaudRate
cc.dcb.ByteSize:=ByteSize; // 字節(jié)為 ByteSize(8 bit)
cc.dcb.Parity:=Parity; // Parity 為 None
cc.dcb.StopBits:=StopBits; // 1 個(gè)Stop bit
if not SetCommState(hComm, cc.dcb) then begin// 設(shè)置COM 的狀態(tài)
result:=‘SetCommState Error!’;
CloseHandle(hComm);
exit;
end;
end;
//===============================================================================================
// 語法格式:Send(str:String)
// 實(shí)現(xiàn)功能:發(fā)送數(shù)據(jù)
// 參數(shù):str,數(shù)據(jù)
// 返回值:無
//===============================================================================================
procedure TCE_Series.Send(str:String);
var
lrc:LongWord;
begin
if (hComm=0) then exit; //檢查Handle值
WriteFile(hComm,str,Length(str), lrc, nil); // 送出數(shù)據(jù)
end;
//=====================================================================
//語法格式: Receive()
//實(shí)現(xiàn)功能: 接收串口數(shù)據(jù)
//參數(shù): 無
//返回值: 收到的字符串
//=====================================================================
Function TCE_Series.Receive():String;
var
inbuff: array[0..2047] of Char;
nBytesRead, dwError:LongWORD ;
cs:TCOMSTAT;
begin
ClearCommError(hComm,dwError,@CS); //取得狀態(tài)
// 數(shù)據(jù)是否大于我們所準(zhǔn)備的Buffer
if cs.cbInQue 》 sizeof(inbuff) then begin
PurgeComm(hComm, PURGE_RXCLEAR); // 清除COM 數(shù)據(jù)
exit;
end;
ReadFile(hComm, inbuff,cs.cbInQue,nBytesRead,nil); // 接收COM 的數(shù)據(jù)
//轉(zhuǎn)移數(shù)據(jù)到變量中
result:=Copy(inbuff,1,cs.cbInQue);//返回?cái)?shù)據(jù)
end;
//=====================================================================
//語法格式: ClosePort()
//實(shí)現(xiàn)功能:關(guān)閉串口
//參數(shù): 無
//返回值: 無
//=====================================================================
procedure TCE_Series.ClosePort();
begin
SetCommMask(hcomm,$0);
CloseHandle(hComm);
end;
end.
二、寫調(diào)用程序演示如何使用這個(gè)類,請自行加入控件,所用的控件不多:
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Windows,Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,ExtCtrls
,CE_Series;
type
{ TForm1 }
TForm1 = class(TForm)
btn_OpenPort: TButton;
btn_ClosePort: TButton;
btn_Send: TButton;
edt_Receive: TMemo;
GroupBox1: TGroupBox;
edt_Send: TMemo;
GroupBox2: TGroupBox;
Timer1: TTimer;
procedure btn_ClosePortClick(Sender: TObject);
procedure btn_OpenPortClick(Sender: TObject);
procedure btn_SendClick(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
myseries:TCE_Series;
implementation
{ TForm1 }
procedure TForm1.btn_OpenPortClick(Sender: TObject);
begin
myseries:=TCE_Series.Create;
myseries.OpenPort(‘COM1:’,CBR_9600,8,NOPARITY,ONESTOPBIT);
Timer1.Enabled:=true;
end;
procedure TForm1.btn_SendClick(Sender: TObject);
begin
myseries.Send(edt_Send.Text);
end;
procedure TForm1.Timer1Timer(Sender: TObject); //用Timer定時(shí)接收數(shù)據(jù)
var
receive:string;
begin
receive:=myseries.Receive();
if receive《》‘’ then
begin
edt_Receive.Lines.Add(receive); // 將數(shù)據(jù)顯示于edt_Receive 上
end;
end;
procedure TForm1.btn_ClosePortClick(Sender: TObject);
begin
Timer1.Enabled:=false;
myseries.ClosePort();
close;
end;
initialization
{$I unit1.lrs}
end.