Lazarus开发串口通信
文章出处:sujic2006 发布时间: 2011/08/26 | 1206 次阅读 | 1次推荐 | 0条留言
每天新产品 时刻新体验 相信品牌的力量 专业PCB打样工厂,24小时加急出货     Lazarus的设计目标是应用Free Pascal,所以所有凡是Free Pascal能运行的平台,Lazarus都可以运行。最新版本能运行于Linux,Win32和FreeBSD。整个界面的外观和操作和Delphi IDE一样,因此,如果你会使用Delphi的话,用起Lazarus IDE来就一定能得心应手了。
    引集成开发环境
    Lazarus是一个用于FreePascal的快速应用开发(RAD)的面向对象的Pascal集成开发环境(IDE)。Lazarus 对于窗口管理来说是中性的。可以工作在KDE(1.13版本)下,也可以工作在GNOME(1.23版本)或其他窗口管理器(MVM、WindowMaker)。Lazarus的设计目标是应用Free Pascal,所以所有凡是Free Pascal能运行的平台,Lazarus也可以运行。最新版本能运行于Linux,Win9x/2000/xp/win7和FreeBSD。目前,已提供32位和64位版本支持。Lazarus的工作界面、外观和操作和Borland 的Delphi IDE非常相似,所不同的是Lazarus 是完全的自由软件。Lazarus 可以直接移植Delphi的代码。Lazarus的编程语言是以Pascal为基础的。Pascal语言具有可读性好、编写容易的特点,这使得它很适合作为基础的开发语言。同时,使用编译器创建的应用程序只生成单个可执行文件(。EXE,但生成的可执行文件体积相对Delphi的来说有点大,只包含一个空窗体的工程生成的可执行文件就达到了10多M。这里,可以通过编译选项来减小可执行文件的大小,可以减为1M多点,然后通过UPX压缩,可以减为600多K。)。正是这种结合,使得Pascal成为Lazarus这种先进开发环境的编程语言。
    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:
    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)
    // 实现功能:打开串口
    // 参数:port,串口号;例如wince下为从COM1:,COM2:……。win32下为COM1,COM2.…… ;其他略,顾名思义哈
    // 返回值:错误信息
    //===============================================================================================
    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 的状态
    cc.dcb.ByteSize:=ByteSize; // 字节为 ByteSize(8 bit)
    cc.dcb.Parity:=Parity; // Parity 为 None
    cc.dcb.StopBits:=StopBits; // 1 个Stop bit
    if not SetCommState(hComm, cc.dcb) then begin// 设置COM 的状态
    result:=‘SetCommState Error!’;
    CloseHandle(hComm);
    exit;
    end;
    end;


    //===============================================================================================
    // 语法格式:Send(str:String)
    // 实现功能:发送数据
    // 参数:str,数据
    // 返回值:无
    //===============================================================================================


    procedure TCE_Series.Send(str:String);
    var
    lrc:LongWord;
    begin
    if (hComm=0) then exit; //检查Handle值
    WriteFile(hComm,str,Length(str), lrc, nil); // 送出数据
    end;
    //=====================================================================
    //语法格式: Receive()
    //实现功能: 接收串口数据
    //参数: 无
    //返回值: 收到的字符串
    //=====================================================================
    Function TCE_Series.Receive():String;
    var
    inbuff: array[02047] of Char;
    nBytesRead, dwError:LongWORD ;
    cs:TCOMSTAT;
    begin
    ClearCommError(hComm,dwError,@CS); //取得状态
    // 数据是否大于我们所准备的Buffer
    if cs.cbInQue 》 sizeof(inbuff) then begin
    PurgeComm(hComm, PURGE_RXCLEAR); // 清除COM 数据
    exit;
    end;
    ReadFile(hComm, inbuff,cs.cbInQue,nBytesRead,nil); // 接收COM 的数据
    //转移数据到变量中
    result:=Copy(inbuff,1,cs.cbInQue);//返回数据
    end;
    //=====================================================================
    //语法格式: ClosePort()
    //实现功能:关闭串口
    //参数: 无
    //返回值: 无
    //=====================================================================
    procedure TCE_Series.ClosePort();
    begin
    SetCommMask(hcomm,$0);
    CloseHandle(hComm);
    end;
    end.
    二、写调用程序演示如何使用这个类,请自行加入控件,所用的控件不多:
    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定时接收数据
    var
    receive:string;
    begin
    receive:=myseries.Receive();
    if receive《》‘’ then
    begin
    edt_Receive.Lines.Add(receive); // 将数据显示于edt_Receive 上
    end;
    end;
    procedure TForm1.btn_ClosePortClick(Sender: TObject);
    begin
    Timer1.Enabled:=false;
    myseries.ClosePort();
    close;
    end;
    initialization
    {$I unit1.lrs}
    end.
Logo

更多推荐