wing 发表于 2013-4-6 17:16:34

自己写PC机上的串口组件(附源码)

微软停止了对mscomm组件的维护,在64位的windows下使用该组件可能会遇到问题。所以以后的串口程序都是建议直接使用API
方式。当然这是很久之前就发生的事情,而今天做的事情就是把API封装成组件使用。
程序用 DELPHI XE2 开发 环境是 64位 win8 pro。
在我印象中本版块比较少发自行开发的软件的帖子,不知道我是不是第一个呢...{:soso_e112:}

有两点要特别指出的
1 本程序是作为“堕落城市”项目开发的其中一部分(不要以为那个项目已经搁浅了,其实我重来没放弃过,只是稍稍慢了点)
2 代码是在以前的开发项目中整理出来的,其实很少写DELPHI的component,另外还没通过真实串口设备测试。

除了欢迎跟贴之外还特别欢迎有条件的朋友进行测试,如果您能完整描述真实且合理测试过程和测试结果,我会送您一些有用但不太贵重的礼物(放心不会让您付运费的,但数量有限)。

以下是uspi_serial_port_interface.pas文件的全部内容unit uspi_serial_port_interface;
//只要有了这个单元就足够了,秒掉mscomm
interface
uses
Windows,System,SysUtils;

type
TBytes=array of Byte;    //数据类型
Tspi_kc = class(TObject)
private
    FOpen_flg:Boolean;    //端口开启标记

    FPort,                //端口号
    FByteSize,            //字节长度 典型值8
    FParity,            //NOPARITY=0
    FStopBits:Byte;       //ONESTOPBIT=0
    FBaudRate:Cardinal;   //波特率典型值 CBR_9600

    FComm_handle: THandle;//COM句柄

public

       function open_comm(APort:Byte;ABaudRate:Cardinal;AByteSize,AParity,AStopBits:Byte):boolean;//打开通信端口
    procedure close_comm;       //关闭通信端口
    function send_comm(Adata:TBytes):Boolean;    //发送
    function receive_comm(var Adata:TBytes):boolean; //接收
end;

implementation


function Tspi_kc.open_comm(APort:Byte;ABaudRate:Cardinal;AByteSize,AParity,AStopBits:Byte):boolean;//打开通信端口
var
v_cc:TCOMMCONFIG;
v_temp:string;
begin
Result:=False;
v_temp:='COM'+inttostr(Aport);                        // 选择所要打开的COM
FComm_handle:=CreateFile(PChar(v_temp), GENERIC_READ or GENERIC_WRITE,0, nil, OPEN_EXISTING, 0, 0); // 打开COM
if (FComm_handle = INVALID_HANDLE_VALUE) then Exit;// 如果COM 未打开退出函数 结果是 false

if GetCommState(FComm_handle,v_cc.dcb) then // 获取目前COM 的状态
begin
    with v_cc.dcb do
    begin
      //设置状态参数
      BaudRate:=ABaudRate;    //波特率典型值 CBR_9600
      ByteSize:=AByteSize;    //字节长度 典型值8
      Parity:=AParity;      //NOPARITY=0
      StopBits:=AStopBits;    //ONESTOPBIT=0
    end;
    if SetCommState(FComm_handle,v_cc.dcb) then // 设置COM 的状态
      Result:=true         //正确设置 返回 true
    else
      CloseHandle(FComm_handle);    //否则 关闭comm口
end;

end;

procedure Tspi_kc.close_comm;       //关闭通信端口
begin
SetCommMask(FComm_handle,$$0);
CloseHandle(FComm_handle);
end;

function Tspi_kc.send_comm(Adata:TBytes):Boolean;    //发送
var
lrc:LongWord;
begin
Result:=False;
if FComm_handle<=0 then Exit;
if WriteFile(FComm_handle,Adata,Length(Adata), lrc, nil) then // 送出数据对于动态数组这里一定要这样写 Adata即数组的第一个元素 不能写动态数组名 ;但是对于下标固定的静态数组可以直接写数组名
    Result:=True;
end;

function Tspi_kc.receive_comm(var Adata:TBytes):boolean; //接收
var
nBytesRead, dwError:LongWORD ;
v_cs:TCOMSTAT;
begin
Result:=False;
if FComm_handle<=0 then Exit;

if ClearCommError(FComm_handle,dwError,@v_cs) then//取得状态
begin
    if v_cs.cbInQue<=0 then Exit;//没有数据 退出
    SetLength(Adata,v_cs.cbInQue);
    if ReadFile(FComm_handle,Adata,v_cs.cbInQue,nBytesRead,nil) then // 接收COM 的数据对于动态数组这里一定要这样写 Adata即数组的第一个元素 不能写动态数组名 ;但是对于下标固定的静态数组可以直接写数组名
    begin
      //PurgeComm(hComm, PURGE_RXCLEAR);// 清除COM 数据
      Result:=True;
    end;
end;
end;



end.

逃不掉的于飞 发表于 2013-5-8 15:42:52

这是用VB 写的?

逃不掉的于飞 发表于 2013-5-8 15:43:22

好吧 我知道了   DELPHI

wing 发表于 2013-5-8 18:38:02

终于有人关注一下了,真心感动...
没错就是DELPHI

Freezing 发表于 2013-5-11 17:06:41

wing 发表于 2013-5-8 18:38 static/image/common/back.gif
终于有人关注一下了,真心感动...
没错就是DELPHI

这种方式只限在Windows下用吧

阳光雨 发表于 2013-12-3 21:47:06

我用delphi写了个TCP/IP的上位机器程序,发现下位机发数据到上位机时上位机软件会假死一会。
页: [1]
查看完整版本: 自己写PC机上的串口组件(附源码)