Lazarus最吸引人的地方就是她的開發方式類似Delphi,支持超好用的RAD開發方式,並且最厲害的地方是她還支持多個平台,多個CPU,例如ARM9的WINCE。
本文要講述的就是“如何使用LAZARUS開發Wince上的串口程序”,並且,本文的串口程序同時支持WINCE和WINXP系統,當然編譯時要選擇平台啦。WINCE與WINXP在本文中的代碼區別只是OpenPort('COM1:',CBR_9600,8,NOPARITY,ONESTOPBIT);//wince用COM1:表示串口1;WINXP用COM1表示串口1.
一、建立一個可重用的類,文件名為CE_SerIEs.pas:
1. unit CE_SerIEs;
2. interface
3. uses
4. Windows,Classes, SysUtils, LResources, StdCtrls,ExtCtrls;
5.
6.
7. type
8. TCE_SerIEs = class(TObject)
9.
10. private
11. hComm: THandle;
12. public
13. Function OpenPort(Port:LPCWSTR;BaudRate,ByteSize,Parity,StopBits:integer):String;
14. procedure Send(str:String);
15. Function Receive():String;
16. procedure ClosePort();
17. end;
18.
19.
20. implementation
21.
22.
23. //===============================================================================================
24. // 語法格式:OpenPort(Port:LPCWSTR;BaudRate,ByteSize,Parity,StopBits:integer)
25. // 實現功能:打開串口
26. // 參數:port,串口號;例如wince下為從COM1:,COM2:.....win32下為COM1,COM2....... ;其他略,顧名思義哈
27. // 返回值:錯誤信息
28. //===============================================================================================
29. function TCE_SerIEs.OpenPort(Port:LPCWSTR;BaudRate,ByteSize,Parity,StopBits:integer):String;
30. var
31. cc:TCOMMCONFIG;
32. begin
33. result:='';
34. hComm:=CreateFile(port, GENERIC_READ or GENERIC_WRITE,
35. 0, nil, OPEN_EXISTING, 0, 0); // 打開COM
36. if (hComm = INVALID_HANDLE_VALUE) then begin // 如果COM 未打開
37. result:='CreateFile Error!';
38. exit;
39. end;
40.
41. GetCommState(hComm,cc.dcb); // 得知目前COM 的狀態
42. cc.dcb.BaudRate:=BaudRate; // 設置波特率為BaudRate
43. cc.dcb.ByteSize:=ByteSize; // 字節為 ByteSize(8 bit)
44. cc.dcb.Parity:=Parity; // Parity 為 None
45. cc.dcb.StopBits:=StopBits; // 1 個Stop bit
46.
47. if not SetCommState(hComm, cc.dcb) then begin// 設置COM 的狀態
48. result:='SetCommState Error!';
49. CloseHandle(hComm);
50. exit;
51. end;
52. end;
53.
54. //===============================================================================================
55. // 語法格式:Send(str:String)
56. // 實現功能:發送數據
57. // 參數:str,數據
58. // 返回值:無
59. //===============================================================================================
60. procedure TCE_SerIEs.Send(str:String);
61. var
62. lrc:LongWord;
63. begin
64. if (hComm=0) then exit; //檢查Handle值
65. WriteFile(hComm,str,Length(str), lrc, nil); // 送出數據
66. end;
67.
68.
69. //=====================================================================
70. //語法格式: Receive()
71. //實現功能: 接收串口數據
72. //參數: 無
73. //返回值: 收到的字符串
74. //=====================================================================
75. Function TCE_SerIEs.Receive():String;
76. var
77. inbuff: array[0..2047] of Char;
78. nBytesRead, dwError:LongWord ;
79. cs:TCOMSTAT;
80. begin
81. ClearCommError(hComm,dwError,@CS); //取得狀態
82. // 數據是否大於我們所准備的Buffer
83. if cs.cbInQue > sizeof(inbuff) then begin
84. PurgeComm(hComm, PURGE_RXCLEAR); // 清除COM 數據
85. exit;
86. end;
87. ReadFile(hComm, inbuff,cs.cbInQue,nBytesRead,nil); // 接收COM 的數據
88. //轉移數據到變量中
89. result:=Copy(inbuff,1,cs.cbInQue);//返回數據
90. end;
91.
92.
93. //=====================================================================
94. //語法格式: ClosePort()
95. //實現功能:關閉串口
96. //參數: 無
97. //返回值: 無
98. //=====================================================================
99. procedure TCE_SerIEs.ClosePort();
100. begin
101. SetCommMask(hcomm,$0);
102. CloseHandle(hComm);
103. end;
104.
105.
106. end.
二、寫調用程序演示如何使用這個類,請自行加入控件,所用的控件不多:
1. unit Unit1;
2.
3. {$mode objfpc}{$H+}
4.
5. interface
6.
7. uses
8. Windows,Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,ExtCtrls
9. ,CE_SerIEs;
10.
11. type
12.
13. { TForm1 }
14.
15. TForm1 = class(TForm)
16. btn_OpenPort: TButton;
17. btn_ClosePort: TButton;
18. btn_Send: TButton;
19. edt_Receive: TMemo;
20. GroupBox1: TGroupBox;
21. edt_Send: TMemo;
22. GroupBox2: TGroupBox;
23. Timer1: TTimer;
24. procedure btn_ClosePortClick(Sender: TObject);
25. procedure btn_OpenPortClick(Sender: TObject);
26. procedure btn_SendClick(Sender: TObject);
27. procedure Timer1Timer(Sender: TObject);
28. private
29. { private declarations }
30. public
31. { public declarations }
32. end;
33.
34. var
35. Form1: TForm1;
36. myseries:TCE_SerIEs;
37.
38. implementation
39.
40. { TForm1 }
41.
42. procedure TForm1.btn_OpenPortClick(Sender: TObject);
43. begin
44. myseries:=TCE_SerIEs.Create;
45. myserIEs.OpenPort('COM1:',CBR_9600,8,NOPARITY,ONESTOPBIT);
46. Timer1.Enabled:=true;
47. end;
48.
49. procedure TForm1.btn_SendClick(Sender: TObject);
50. begin
51. myserIEs.Send(edt_Send.Text);
52. end;
53.
54. procedure TForm1.Timer1Timer(Sender: TObject); //用Timer定時接收數據
55. var
56. receive:string;
57. begin
58. receive:=myserIEs.Receive();
59. if receive<>'' then
60. begin
61. edt_Receive.Lines.Add(receive); // 將數據顯示於edt_Receive 上
62. end;
63. end;
64.
65. procedure TForm1.btn_ClosePortClick(Sender: TObject);
66. begin
67. Timer1.Enabled:=false;
68. myserIEs.ClosePort();
69. close;
70. end;
71.
72. initialization
73. {$I unit1.lrs}
74.
75. end.
76.