关于RS-232串行通信的开发,大家给出出主意 ( 积分: 200 )

  • 主题发起人 主题发起人 Crazyz
  • 开始时间 开始时间
C

Crazyz

Unregistered / Unconfirmed
GUEST, unregistred user!
具体情况:此软件为万用表pc端软件,以前是用VB编的通过RS-232C接口标准来访问Com口,万用表也是联在Com上,现我要改为用delphi的并且同时支持com口和USB口,现在手头上拿到的资料有VB的可执行文件,万用表USB的驱动程序,万用表我的问题:

1.要完成此软件还需要哪些资料?
2.用delphi做基于RS-232的开发,可用到的控件有哪些?如果直接调用操作系统的函数,和RS-232相关有哪些函数?
3.关于USB接口的开发,我在USB驱动程序中发现有一个CCPORT.SYS这样的文件,在这个文件中有一些函数,好像是对接口操作,不知,这种函数能不能像Dll一样调用!

请不啬赐教,多谢了!
 
具体情况:此软件为万用表pc端软件,以前是用VB编的通过RS-232C接口标准来访问Com口,万用表也是联在Com上,现我要改为用delphi的并且同时支持com口和USB口,现在手头上拿到的资料有VB的可执行文件,万用表USB的驱动程序,万用表我的问题:

1.要完成此软件还需要哪些资料?
2.用delphi做基于RS-232的开发,可用到的控件有哪些?如果直接调用操作系统的函数,和RS-232相关有哪些函数?
3.关于USB接口的开发,我在USB驱动程序中发现有一个CCPORT.SYS这样的文件,在这个文件中有一些函数,好像是对接口操作,不知,这种函数能不能像Dll一样调用!

请不啬赐教,多谢了!
 
TSPCOMM,TComPort
 
走过,路过,帮帮忙,多谢各位了
 
DELPHI在底层接口方面没有官方的控件,建议用VB的 MSCOMM32.OCX 控件
 
将VB代码转换成DELPHI代码应该是最好的办法
 
对于串口的操作可以直接使用API
我这里有一个自己近期使用的单元可以参考一下
我的中文注释出来居然是乱码,我懒得改了,讲究看吧

{ System Resource }

{ Copyright (c) 2005, CHR Corporation }
{ Date: 2005-10-01 }
{ Build: 2005-10-04 }
{ Author: muhx }

unit UntCommDefine;

interface

uses
Windows, Classes, SyncObjs, SysUtils, UntTypeDefine;

type
{ ´®¿ÚͨѶÀà }
TCom = class
private
FCriticalSection: TCriticalSection;
FHandle: THandle;

FComName: string;
FBaud: TBaudRate;
FParity: TParity;
FStopBit: TStopBit;
FDataBit: TDataBit;
FInQueue: Integer;
FOutQueue: Integer;
FReadTimeOut: Integer;
FWriteTimeOut: Integer;
FTimeOut: COMMTIMEOUTS;
FEventMask: Integer;
private
procedure Lock;
procedure Unlock;
public
constructor ComCreate(AComSet: TComSet);
destructor Destroy; override;
public
procedure ChangeComSet(const AComSet: TComSet);
procedure ChangeParity(AParity: TParity);
procedure CloseCom;
procedure OpenCom;
procedure PurgeCom;
function Enabled: Boolean;
function Read(var APData; ADataLen: Integer): Boolean;
function Write(var APData; ADataLen: Integer): Boolean;
public
function SendCommand(APCommand: PCmdParam): Boolean;
function HandtoClip(AAddress: Byte): Boolean;
function ReceiveData(APReceive: PByte; AReceiveLen: Integer): Boolean;
public
property gHandle: THandle read FHandle;
property gBaud: TBaudRate read FBaud default br57600;
property gDataBit: TDataBit read FDataBit default da8;
property gInQueue: Integer read FInQueue default 4096;
property gOutQueue: Integer read FOutQueue default 2048;
property gParity: TParity read FParity default paSpace;
property gStopBits: TStopBit read FStopBit default sb10;
property gReadTimeOut: Integer read FReadTimeOut default 2000;
property gComName: string read FComName;
property gWriteTimeOut: Integer read FWriteTimeout default 2000;
end;

implementation

{ ´´½¨´®¿ÚÀà }
constructor TCom.ComCreate(AComSet: TComSet);
begin
inherited Create;
{ ÁÙ½çÇø }
FCriticalSection := TCriticalSection.Create;
{ ´®¿Ú¿ØÖƾä±ú }
FHandle := INVALID_HANDLE_VALUE;
{ ´®¿Ú²ÎÊý }
FComName := COMComID[AComSet.csComID];
FParity := AComSet.csParity;
FBaud := AComSet.csBaud;
FDataBit := AComSet.csDataBit;
FStopBit := AComSet.csStopBit;
FInQueue := AComSet.csInQueue;
FOutQueue := AComSet.csOutQueue;
FReadTimeOut := AComSet.csReadTimeOut;
FWriteTimeOut := AComSet.csWriteTimeOut;
FEventMask := EV_RXCHAR;
{ Á½¸ö×Ö½Ú´«Êä¼ä¸ô }
FTimeOut.ReadIntervalTimeout := 30;
{ ÿ×Ö½Ú´«Êäʱ¼ä }
FTimeOut.ReadTotalTimeoutMultiplier := 5;
{ ûÓÐ×Ö½Úʱ·µ»Øʱ¼ä }
FTimeOut.ReadTotalTimeoutConstant := 80;
{ ÿ×Ö½Ú´«Êäʱ¼ä }
FTimeOut.WriteTotalTimeoutMultiplier := 5;
{ ´«Êäʱ¼ä³£Á¿ }
FTimeOut.WriteTotalTimeoutConstant := 50;
{ ´ò¿ª´®¿Ú }
OpenCom;
end;

{ ÊÍ·Å´®¿ÚÀà }
destructor TCom.Destroy;
begin
CloseCom;
if FCriticalSection <> nil then
begin
FCriticalSection.Free;
FCriticalSection := nil;
end;
inherited Destroy;
end;

{ &amp;Aring;&amp;ETH;&amp;para;&amp;Iuml;&amp;acute;&amp;reg;&amp;iquest;&amp;Uacute;&amp;Ecirc;&amp;Ccedil;·&amp;ntilde;&amp;acute;&amp;acute;&amp;frac12;¨ }
function TCom.Enabled: Boolean;
begin
Result := FHandle <> INVALID_HANDLE_VALUE;
end;

{ &amp;sup1;&amp;Oslash;±&amp;Otilde;&amp;acute;&amp;reg;&amp;iquest;&amp;Uacute; }
procedure TCom.CloseCom;
begin
if Enabled then
begin
Sleep(100);
CloseHandle(FHandle);
FHandle := INVALID_HANDLE_VALUE;
end;
end;

{ &amp;cedil;ü&amp;cedil;&amp;Auml;&amp;acute;&amp;reg;&amp;iquest;&amp;Uacute;&amp;sup2;&amp;Icirc;&amp;Ecirc;&amp;yacute; }
procedure TCom.ChangeComSet(const AComSet: TComSet);
var
tmpDCB: DCB;
begin
try
with AComSet do
begin
FParity := csParity;
FBaud := csBaud;
FDataBit := csDataBit;
FStopBit := csStopBit;
FInQueue := csInQueue;
FOutQueue := csOutQueue;
FReadTimeOut := csReadTimeOut;
FWriteTimeOut := csWriteTimeOut;
end;

if Enabled then
begin
tmpDCB.DCBlength := SizeOf(DCB);
GetCommState(FHandle, tmpDCB);
tmpDCB.BaudRate := COMBaudRate[FBaud];
tmpDCB.Parity := COMParity[FParity];
tmpDCB.ByteSize := COMDataBit[FDataBit];
tmpDCB.StopBits := COMStopBit[FStopBit];

if not (SetupComm(FHandle, FInQueue, FOutQueue) and SetCommState(FHandle, tmpDCB))
then Abort;
PurgeCom;
end;
except
on E: Exception do
begin
CloseCom;
end;
end;
end;

{ &amp;cedil;ü&amp;cedil;&amp;Auml;&amp;acute;&amp;reg;&amp;iquest;&amp;Uacute;&amp;AElig;&amp;aelig;&amp;Aring;&amp;frac14;&amp;ETH;&amp;pound;&amp;Ntilde;é&amp;Eacute;è&amp;Ouml;&amp;Atilde; }
procedure TCom.ChangeParity(AParity: TParity);
var
tmpDCB: DCB;
begin
try
FParity := AParity;
if Enabled then
begin
tmpDCB.DCBlength := SizeOf(DCB);
GetCommState(FHandle, tmpDCB);
tmpDCB.Parity := COMParity[FParity];

if not SetCommState(FHandle, tmpDCB) then
Abort;
PurgeCom;
end;
except
on E: Exception do
begin
CloseCom;
end;
end;
end;

{ &amp;frac12;&amp;oslash;&amp;Egrave;&amp;euml;&amp;Aacute;&amp;Ugrave;&amp;frac12;&amp;ccedil;&amp;Ccedil;&amp;oslash; }
{ &amp;Ocirc;&amp;Uacute;&amp;para;&amp;Ocirc;&amp;acute;&amp;reg;&amp;iquest;&amp;Uacute;&amp;frac12;&amp;oslash;&amp;ETH;&amp;ETH;&amp;sup2;&amp;Ugrave;×÷&amp;micro;&amp;Auml;&amp;Ecirc;±&amp;ordm;ò&amp;Egrave;·±&amp;pound;&amp;Atilde;&amp;raquo;&amp;Oacute;&amp;ETH;&amp;Iacute;&amp;not;&amp;Ecirc;±&amp;frac12;&amp;oslash;&amp;ETH;&amp;ETH;&amp;AElig;&amp;auml;&amp;Euml;&amp;ucirc;&amp;sup2;&amp;Ugrave;×÷ }
procedure TCom.Lock;
begin
FCriticalSection.Enter;
end;

{ &amp;Iacute;&amp;Euml;&amp;sup3;&amp;ouml;&amp;raquo;&amp;ordm;&amp;sup3;&amp;aring;&amp;Ccedil;&amp;oslash; }
procedure TCom.Unlock;
begin
FCriticalSection.Leave;
end;

{ &amp;acute;&amp;acute;&amp;frac12;¨&amp;acute;&amp;reg;&amp;iquest;&amp;Uacute; }
procedure TCom.OpenCom;
var
tmpDCB: DCB;
begin
if Enabled then
Exit;
try
FHandle := CreateFile(PChar(FComName), GENERIC_READ or GENERIC_WRITE,
0, nil,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);

if not Enabled then
Abort
else begin
{ &amp;Eacute;è&amp;Ouml;&amp;Atilde;&amp;acute;&amp;reg;&amp;iquest;&amp;Uacute;&amp;sup2;&amp;Icirc;&amp;Ecirc;&amp;yacute; }
tmpDCB.DCBlength := SizeOf(DCB);
GetCommState(FHandle, tmpDCB);
tmpDCB.BaudRate := COMBaudRate[FBaud];
tmpDCB.Parity := COMParity[FParity];
tmpDCB.ByteSize := COMDataBit[FDataBit];
tmpDCB.StopBits := COMStopBit[FStopBit];

if not (SetCommMask(FHandle, FEventMask) and
SetCommTimeouts(FHandle, FTimeOut) and
SetupComm(FHandle, FInQueue, FOutQueue) and
SetCommState(FHandle, tmpDCB) and
(FCriticalSection <> nil)) then
Abort;
end;
except
on E: Exception do
begin
CloseCom;
end;
end;
end;

{ &amp;Ccedil;&amp;aring;&amp;iquest;&amp;Otilde;&amp;raquo;&amp;ordm;&amp;sup3;&amp;aring;&amp;Ccedil;&amp;oslash; }
procedure TCom.PurgeCom;
begin
if Enabled then
begin
PurgeComm(FHandle, PURGE_RXCLEAR);
PurgeComm(FHandle, PURGE_TXCLEAR);
end;
end;

{ &amp;acute;&amp;Oacute;&amp;acute;&amp;reg;&amp;iquest;&amp;Uacute;&amp;para;&amp;Aacute;&amp;Egrave;&amp;iexcl;&amp;Ecirc;&amp;yacute;&amp;frac34;&amp;Yacute; }
function TCom.Read(var APData; ADataLen: Integer): Boolean;
var
tmpOverlapped: TOverlapped;
tmpEvent: TSimpleEvent;
tmpReceive: DWord;
begin
Result := True;
Lock;
tmpEvent := TSimpleEvent.Create;
try
tmpReceive := 0;
FillChar(tmpOverlapped, SizeOf(tmpOverlapped), 0);
tmpOverlapped.hEvent := tmpEvent.Handle;

if not ReadFile(FHandle, APData, ADataLen, DWord(tmpReceive),
@tmpOverlapped) and (GetLastError <> ERROR_IO_PENDING) then
Result := False;

if tmpEvent.WaitFor(FReadTimeOut) <> wrSignaled then
Result := False
else begin
GetOverlappedResult(FHandle, tmpOverlapped, DWord(tmpReceive), False);
tmpEvent.ResetEvent;
end;
finally
Unlock;
tmpEvent.Free;
if tmpReceive <> DWord(ADataLen) then
Result := False;
end;
end;

{ &amp;Iuml;ò&amp;acute;&amp;reg;&amp;iquest;&amp;Uacute;&amp;ETH;&amp;acute;&amp;Egrave;&amp;euml;&amp;Ecirc;&amp;yacute;&amp;frac34;&amp;Yacute; }
function TCom.Write(var APData; ADataLen: Integer): Boolean;
var
tmpOverlapped: TOverlapped;
tmpEvent: TSimpleEvent;
tmpWrite: DWord;
begin
Lock;
Result := True;
tmpEvent := TSimpleEvent.Create;
try
tmpWrite := 0;
FillChar(tmpOverlapped, SizeOf(tmpOverlapped), 0);
tmpOverlapped.hEvent := tmpEvent.Handle;

if not WriteFile(FHandle, APData, ADataLen, DWord(tmpWrite),
@tmpOverlapped) and (GetLastError <> ERROR_IO_PENDING) then
Result := False;

if tmpEvent.WaitFor(FWriteTimeOut) <> wrSignaled then
Result := False
else begin
GetOverlappedResult(FHandle, tmpOverlapped, DWord(tmpWrite), False);
tmpEvent.ResetEvent;
end;
finally
Unlock;
tmpEvent.Free;
if tmpWrite <> DWord(ADataLen) then
Result := False;
end;
end;

{ ·&amp;cent;&amp;Euml;&amp;Iacute;&amp;Atilde;ü&amp;Aacute;&amp;icirc; }
function TCom.SendCommand(APCommand: PCmdParam): Boolean;
var
i: Integer;
begin
Result := False;
Lock;
try
i := 0;
while (i < 5) do
begin
{ &amp;micro;&amp;Oslash;&amp;Ouml;·&amp;Icirc;&amp;Otilde;&amp;Ecirc;&amp;Ouml; }
ChangeParity(paMark);
if not HandtoClip(APCommand^.cmdAddress) then
begin
Inc(i);
Continue;
end;
{ ·&amp;cent;&amp;Euml;&amp;Iacute;&amp;Atilde;ü&amp;Aacute;&amp;icirc; }
ChangeParity(paSpace);
if not Write(APCommand^.cmdCommand, SizeOf(APCommand^.cmdCommand)) then
begin
Inc(I);
Continue;
end;
{ ·&amp;cent;&amp;Euml;&amp;Iacute;&amp;Ecirc;&amp;yacute;&amp;frac34;&amp;Yacute; }
if APCommand^.cmdSendLen <> 0 then
begin
if not Write(APCommand^.cmdPSend^, APCommand^.cmdSendLen) then
begin
Inc(I);
Continue;
end;
end;
{ &amp;frac12;&amp;Oacute;&amp;Ecirc;&amp;Otilde;&amp;Ecirc;&amp;yacute;&amp;frac34;&amp;Yacute; }
if not ReceiveData(APCommand^.cmdPReceive, APCommand^.cmpReceiveLen) then
begin
Inc(I);
Continue;
end;
Result := True;
Break;
end;
finally
Sleep(100);
PurgeCom;
UnLock;
end;
end;

{ &amp;Oacute;&amp;euml;MCU&amp;micro;&amp;Oslash;&amp;Ouml;·&amp;Icirc;&amp;Otilde;&amp;Ecirc;&amp;Ouml; }
function TCom.HandtoClip(AAddress: Byte): Boolean;
var
tmpRead: array[0..2] of Byte;
begin
{ ·&amp;cent;&amp;Euml;&amp;Iacute;&amp;micro;&amp;Oslash;&amp;Ouml;· }
if not Write(AAddress, SizeOf(AAddress)) then
begin
Result := False;
Exit;
end;
{ &amp;para;&amp;Aacute;&amp;Egrave;&amp;iexcl;&amp;Ecirc;&amp;yacute;&amp;frac34;&amp;Yacute; }
if not Read(tmpRead, SizeOf(tmpRead)) then
begin
Result := False;
Exit;
end;
{ ±&amp;Egrave;&amp;frac12;&amp;Iuml;&amp;Ecirc;&amp;yacute;&amp;frac34;&amp;Yacute; }
if (tmpRead[0] <> $AA) or (tmpRead[1] <> $55) or (tmpRead[2] <> AAddress) then
begin
Result := False;
Exit;
end;
{ &amp;Egrave;&amp;ocirc;&amp;frac12;&amp;Oacute;&amp;Ecirc;&amp;Otilde;&amp;sup3;&amp;Eacute;&amp;sup1;&amp;brvbar;&amp;Ccedil;&amp;Ograve;&amp;Ecirc;&amp;yacute;&amp;frac34;&amp;Yacute;&amp;Otilde;&amp;yacute;&amp;Egrave;··&amp;micro;&amp;raquo;&amp;Oslash;True }
Result := True;
end;

{ &amp;frac12;&amp;Oacute;&amp;Ecirc;&amp;Otilde;&amp;Ecirc;&amp;yacute;&amp;frac34;&amp;Yacute;&amp;pound;&amp;not;&amp;cedil;ù&amp;frac34;&amp;Yacute;&amp;Iacute;¨&amp;Ntilde;&amp;para;&amp;ETH;&amp;shy;&amp;Ograve;é&amp;pound;&amp;not;&amp;Ocirc;&amp;Uacute;&amp;frac12;&amp;Oacute;&amp;Ecirc;&amp;Otilde;&amp;Ecirc;&amp;yacute;&amp;frac34;&amp;Yacute;&amp;Ccedil;°&amp;Oacute;&amp;ETH;AA55&amp;Aacute;&amp;frac12;×&amp;Ouml;&amp;frac12;&amp;Uacute;&amp;ETH;&amp;pound;&amp;Ntilde;é&amp;Acirc;&amp;euml; }
function TCom.ReceiveData(APReceive: PByte; AReceiveLen: Integer): Boolean;
var
tmpRead: array[0..1023] of Byte;
tmpPByte: PByte;
i: Integer;
begin
if AReceiveLen <> 0 then
begin
if Read(tmpRead, AReceiveLen + 2) then
begin
if (tmpRead[0] = $AA) and (tmpRead[1] = $55) then
begin
tmpPByte := APReceive;
for i := 0 to AReceiveLen - 1 do
begin
tmpPByte^ := tmpRead[i + 2];
Inc(tmpPByte);
end;
end
else
begin
Result := False;
Exit;
end;
end
else
begin
Result := False;
Exit;
end;
end
else
begin
if (not Read(tmpRead, 3)) or (tmpRead[0] <> $AA) or (tmpRead[1] <> $55) then
begin
Result := False;
Exit;
end;
if tmpRead[2] = $88 then
begin
Result := False;
Exit;
end
end;
Result := True;
end;

end.
 
串口通信我一直用的都是PCOMM,一个动态连接库,不过我发现好象大家用这个的不多啊,多数都是MSCOM
 
关键看任务具体情况,用API,或现成的控件也好,动态库也好或者MSCOMM都可以的.
我自己什么方法都用过,但也从没固定一种,都是看开发时候随便自己选的.
 
串口通信我用的是moxa的PCOMM,很不错的。usb没弄过,学习
 
Spcomm不错,我的主页有Spcomm3.0下载:www.zptang.ys168.com
 
串口用MSCOMM,DELPHI开发USB我也很关注!!!!
 
spcomm就够用了
 
串口通信我用了PCOMM就不用别的了
 
推荐用SPCOMM
 
最关键的是你要有此万用表的通讯协议。
 

Similar threads

D
回复
0
查看
911
DelphiTeacher的专栏
D
D
回复
0
查看
868
DelphiTeacher的专栏
D
D
回复
0
查看
840
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部