Lazarus实战开发之串口通信(WINCE/WIN32)

时间:2023-02-13 18:05:41
本文来自 http://blog.csdn.net/hellogv/ ,转载必须注明出处!
以下代码可到: http://download.csdn.net/source/611385 下载
    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. type
  7.   TCE_Series = class(TObject)
  8.   
  9.   private
  10.     hComm: THandle;
  11.   public
  12.     Function OpenPort(Port:LPCWSTR;BaudRate,ByteSize,Parity,StopBits:integer):String;
  13.     procedure Send(str:String);
  14.     Function Receive():String;
  15.     procedure ClosePort();
  16.   end;
  17. implementation
  18. //===============================================================================================
  19. // 语法格式:OpenPort(Port:LPCWSTR;BaudRate,ByteSize,Parity,StopBits:integer)
  20. // 实现功能:打开串口
  21. // 参数:port,串口号;例如wince下为从COM1:,COM2:.....win32下为COM1,COM2....... ;其他略,顾名思义哈
  22. // 返回值:错误信息
  23. //===============================================================================================
  24. function TCE_Series.OpenPort(Port:LPCWSTR;BaudRate,ByteSize,Parity,StopBits:integer):String;
  25. var
  26.   cc:TCOMMCONFIG;
  27. begin
  28.   result:='';
  29.   hComm:=CreateFile(port, GENERIC_READ or GENERIC_WRITE,
  30.        0nil, OPEN_EXISTING, 00); // 打开COM
  31.   if (hComm = INVALID_HANDLE_VALUE) then begin  // 如果COM 未打开
  32.     result:='CreateFile Error!';
  33.     exit;
  34.   end;
  35.   GetCommState(hComm,cc.dcb); // 得知目前COM 的状态
  36.   cc.dcb.BaudRate:=BaudRate; // 设置波特率为BaudRate
  37.   cc.dcb.ByteSize:=ByteSize;  // 字节为 ByteSize(8 bit)
  38.   cc.dcb.Parity:=Parity; // Parity 为 None
  39.   cc.dcb.StopBits:=StopBits; // 1 个Stop bit
  40.   
  41.   if not SetCommState(hComm, cc.dcb) then begin// 设置COM 的状态
  42.     result:='SetCommState Error!';
  43.     CloseHandle(hComm);
  44.     exit;
  45.   end;
  46. end;
  47. //===============================================================================================
  48. // 语法格式:Send(str:String)
  49. // 实现功能:发送数据
  50. // 参数:str,数据
  51. // 返回值:无
  52. //===============================================================================================
  53. procedure TCE_Series.Send(str:String);
  54. var
  55.   lrc:LongWord;
  56. begin
  57.   if (hComm=0then exit; //检查Handle值
  58.   WriteFile(hComm,str,Length(str), lrc, nil); // 送出数据
  59. end;
  60. //=====================================================================
  61. //语法格式: Receive()
  62. //实现功能: 接收串口数据
  63. //参数:     无
  64. //返回值:   收到的字符串
  65. //=====================================================================
  66. Function TCE_Series.Receive():String;
  67. var
  68.   inbuff: array[0..2047of Char;
  69.   nBytesRead, dwError:LongWORD ;
  70.   cs:TCOMSTAT;
  71. begin
  72.    ClearCommError(hComm,dwError,@CS);  //取得状态
  73.        // 数据是否大于我们所准备的Buffer
  74.    if cs.cbInQue > sizeof(inbuff) then begin
  75.      PurgeComm(hComm, PURGE_RXCLEAR);  // 清除COM 数据
  76.      exit;
  77.    end;
  78.    ReadFile(hComm, inbuff,cs.cbInQue,nBytesRead,nil); // 接收COM 的数据
  79.    //转移数据到变量中
  80.    result:=Copy(inbuff,1,cs.cbInQue);//返回数据
  81. end;                             
  82. //=====================================================================
  83. //语法格式: ClosePort()
  84. //实现功能:关闭串口
  85. //参数:  无
  86. //返回值:  无
  87. //=====================================================================
  88. procedure TCE_Series.ClosePort();
  89. begin
  90.    SetCommMask(hcomm,$0);
  91.    CloseHandle(hComm);
  92. end;
  93. end.
二、写调用程序演示如何使用这个类,请自行加入控件,所用的控件不多:
  1. unit Unit1; 
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5.   Windows,Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,ExtCtrls
  6.   ,CE_Series;
  7. type
  8.   { TForm1 }
  9.   TForm1 = class(TForm)
  10.     btn_OpenPort: TButton;
  11.     btn_ClosePort: TButton;
  12.     btn_Send: TButton;
  13.     edt_Receive: TMemo;
  14.     GroupBox1: TGroupBox;
  15.     edt_Send: TMemo;
  16.     GroupBox2: TGroupBox;
  17.     Timer1: TTimer;
  18.     procedure btn_ClosePortClick(Sender: TObject);
  19.     procedure btn_OpenPortClick(Sender: TObject);
  20.     procedure btn_SendClick(Sender: TObject);
  21.     procedure Timer1Timer(Sender: TObject);
  22.   private
  23.     { private declarations }
  24.   public
  25.     { public declarations }
  26.   end
  27. var
  28.   Form1: TForm1; 
  29.   myseries:TCE_Series;
  30.   
  31. implementation
  32. { TForm1 }
  33. procedure TForm1.btn_OpenPortClick(Sender: TObject);
  34. begin
  35.   myseries:=TCE_Series.Create;
  36.   myseries.OpenPort('COM1:',CBR_9600,8,NOPARITY,ONESTOPBIT);
  37.   Timer1.Enabled:=true;
  38. end;
  39. procedure TForm1.btn_SendClick(Sender: TObject);
  40. begin
  41.   myseries.Send(edt_Send.Text);
  42. end;
  43. procedure TForm1.Timer1Timer(Sender: TObject); //用Timer定时接收数据
  44. var
  45.   receive:string;
  46. begin
  47.    receive:=myseries.Receive();
  48.    if receive<>'' then
  49.    begin
  50.       edt_Receive.Lines.Add(receive);   // 将数据显示于edt_Receive 上
  51.    end;
  52. end;
  53. procedure TForm1.btn_ClosePortClick(Sender: TObject);
  54. begin
  55.    Timer1.Enabled:=false;
  56.    myseries.ClosePort();
  57.    close;
  58. end;
  59. initialization
  60.   {$I unit1.lrs}
  61. end.