微软停止了对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[0],Length(Adata), lrc, nil) then // 送出数据 对于动态数组这里一定要这样写 Adata[0]即数组的第一个元素 不能写动态数组名 ;但是对于下标固定的静态数组可以直接写数组名
- 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[0],v_cs.cbInQue,nBytesRead,nil) then // 接收COM 的数据 对于动态数组这里一定要这样写 Adata[0]即数组的第一个元素 不能写动态数组名 ;但是对于下标固定的静态数组可以直接写数组名
- begin
- //PurgeComm(hComm, PURGE_RXCLEAR); // 清除COM 数据
- Result:=True;
- end;
- end;
- end;
- end.
复制代码 |