请教:如何用API异步操作串口?谢谢! ( 积分: 200 )

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

chenshu_sc

Unregistered / Unconfirmed
GUEST, unregistred user!
如题。

 主要是操作多模块收发短信,因为要支持2、30个模块,即COM口有2、30个,所以不能用MSCOMM,SPCOMM这些控件。

另外,我的程序:
hHandle := CreateFile(
PChar('COM15'),
GENERIC_READ or GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0
);
//
if ( hHandle = Invalid_Handle_Value )then
begin
bIfOk := False;
exit;
end
else
begin
bIfOk := True;
end;
其中 bIfOk 总是等于 False 呢?而一改成COM1-COM9就是True....真正的郁闷
 
如题。

 主要是操作多模块收发短信,因为要支持2、30个模块,即COM口有2、30个,所以不能用MSCOMM,SPCOMM这些控件。

另外,我的程序:
hHandle := CreateFile(
PChar('COM15'),
GENERIC_READ or GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0
);
//
if ( hHandle = Invalid_Handle_Value )then
begin
bIfOk := False;
exit;
end
else
begin
bIfOk := True;
end;
其中 bIfOk 总是等于 False 呢?而一改成COM1-COM9就是True....真正的郁闷
 
异步操作串口其实就是readfile,writefile时使用overlapped参数,你看看SPCOMM的辕马就知道了。
第二个问题是不是因为没有这些设备,你用getlasterror看看出错代码再作判断
 
TO:迷糊

  SPCOMM的源码太多了,看起来有些吃力,能给个例程吗?

  第二个问题,没有设备是不可能的,因为我用超级终端可以正常连接,且可以用AT指令

  谢谢你的帮助!
 
试试 hHandle := CreateFile(PChar('//./COM15'),...)
另外
if ( hHandle = Invalid_Handle_Value )then
begin
showmessage(inttostr(getlasterror));// 看看出错代码
bIfOk := False;
exit;
end
SPCOMM的源码并不复杂,给你例程估计和SPCOMM的也差不多少
 
以前写过,代码没带出来,给你一个变通的方法

还是用SPCOMM,spcomm的完整代码在
http://www.delphibbs.com/delphibbs/dispq.asp?lid=171926

使用的时候,你建立一个TList的列表,把SPComm的实例都放进去,到时候一并销毁,
但是修改一下构造和析构代码代码,
constructor TComm.Create( AOwner: TComponent );
begin
inherited Create( AOwner );

ReadThread := nil;
WriteThread := nil;
hCommFile := 0;
hCloseEvent := 0;
FSendDataEmpty := True;

FCommName := 'COM2';
FBaudRate := 9600;
FParityCheck := False;
FOutx_CtsFlow := False;
FOutx_DsrFlow := False;
FDtrControl := DtrEnable;
FDsrSensitivity := False;
FTxContinueOnXoff := True;
FOutx_XonXoffFlow := True;
FInx_XonXoffFlow := True;
FReplaceWhenParityError := False;
FIgnoreNullChar := False;
FRtsControl := RtsEnable;
FXonLimit := 500;
FXoffLimit := 500;
FByteSize := _8;
FParity := None;
FStopBits := _1;
FXonChar := chr($11); // Ctrl-Q
FXoffChar := chr($13); // Ctrl-S
FReplacedChar := chr(0);
FReadIntervalTimeout := 100;
FReadTotalTimeoutMultiplier := 0;
FReadTotalTimeoutConstant := 0;
FWriteTotalTimeoutMultiplier := 0;
FWriteTotalTimeoutConstant := 0;

[blue] FHWnd := AllocateHWnd(CommWndProc)[/blue]
end;

destructor TComm.Destroy;
begin
[blue]DeallocateHWnd(FHwnd);[/blue]

inherited Destroy;
end;

然后修改下读取数据的代码
procedure TComm.ReceiveData(Buffer: PChar; BufferLength: Word);
begin
// if Assigned(FOnReceiveData) then
// FOnReceiveData( self, Buffer, BufferLength )
// 处理数据,根
end;
 
呵,第二个问题已经解决,迷糊 同志是对的,但是是什么原因呢?

现在主攻异步了:)请 迷糊 同志继续帮助啊!谢谢!

同时也要谢谢楼上的各位:)
 
串口多没有问题的,用我的方法可以存在多个SPCOMM实例,所有问题都帮你处理掉了,自己写未必比它写得好,但是却花了很多时间,CreateFile以后用GetLastError看看是什么错误,再出问题可能是串口占用和设置方面的问题了,一点看法
 
TO:chenybin
  打开的时候要加'//./'这个 迷糊 已经解决了

  你说的方法我不太明白,能否给个例程?(chenshu_sc@163.com或QQ:19420047)

谢谢!
 
spcomm的代码我已经把地址发送上去了,你自己去下载,按我说的方法修改

数据的获得用这样的方法
http://www.delphibbs.com/delphibbs/dispq.asp?lid=508492

今天太晚了,明天写个框架例子,因为无论如何你都需要维护多个串口类实例
 
TO:chenybin

  嗯,SPCOMM 的代码我正在看,你的框架例子今天能这写好吗?记得发一份给我哦:)

  
 
邮件已发
 
spcomm对一个com口会启两个线程,楼主要2、30个com口,所以用多个spcomm的方法不太合理
其实如果你弄弄明白异步io操作,完全可以一对读写线程管理若干个com口,这个不是很复杂
 
9494,同意迷糊,那么多个线程搞晕你,想要串口通信程序又不想弄线程啊可能性还真不大,而且串口通信的API真的很简单的,满打满算有六个核心API就够用了:
CreateFile, CloseHandle, ReadFile, WriteFile, WaitForSingleObject, GetOverlappedResult
到Spcomm里面找找这些函数怎么用的也就清楚了
 
下午chenybin给我发了个MSDN上关于串口通讯的文档,现在正在看,感觉有些乱,所以先看完再继续^_^
 
呵,全是英文的看着太晕了[:(]
  现在有些问题想请教一下,如果异步操作,那么操作结果如何得到?是存在OVERLAPPED结构里?用WaitforSingleObject得到?
  如果是存在OVERLAPPED结构里那么如果在得到上个操作的OVERLAPPED时又进行了操作该怎么办?
 
....是不是因为周末的原因,都没人搭理我的啊....
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Label1: TLabel;
Edit1: TEdit;
Button3: TButton;
Button4: TButton;
Label2: TLabel;
Memo1: TMemo;
ComboBox1: TComboBox;
Label3: TLabel;
Button5: TButton;
procedure Button2Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Edit1KeyPress(Sender: TObject; var Key: Char);
procedure Button5Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
hcom,Post_Event:Thandle;
lpol:_overlapped;
lpdcb:Tdcb;



implementation

{$R *.dfm}

procedure TForm1.Button2Click(Sender: TObject);
begin
closehandle(hcom);
close;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Closehandle(hcom);
hcom:=createfile(Pchar(combobox1.Text),generic_read or generic_write,0,nil,open_existing,file_attribute_normal,0);
getcommstate(hcom,lpdcb);
lpdcb.baudrate:=9600;
lpdcb.ByteSize:=8;
lpdcb.Parity:=MarkParity;
lpdcb.StopBits:=OneStopBit;
setcommstate(hcom,lpdcb);
showmessage('连接成功!');
button1.Enabled:=false;
end;

procedure TForm1.Button3Click(Sender: TObject);
var
dwErrorFlags: DWORD;
ComStat : TComStat;
num,i:integer;
rebuf:byte;
begin
PurgeComm(hcom,(PURGE_RXABORT and PURGE_RXCLEAR));
ClearCommError(hcom,dwErrorFlags,@ComStat);
if comstat.cbInQue>0 then
begin
for i:=0 to comstat.cbInQue-1 do
begin
ReadFile(hcom,reBuf,1,dwErrorFlags,@lpol);
num:=rebuf;
memo1.Text:=memo1.Text+inttostr(num)+' ';
end;
end
else
begin
showmessage('接收已经完成或者没有数据接收!');
end;
edit1.SetFocus;
end;

procedure TForm1.Button4Click(Sender: TObject);
var
lrc:DWORD;
ch:integer;
begin
ch:=strtoint(edit1.Text);
writefile(hcom,ch,1,lrc,nil);
edit1.SetFocus;
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
if key<>#13 then
begin
if (not (Key in ['0'..'9'])) then
begin
key:=#0;
end;
end;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
Closehandle(hcom);
hcom:=createfile(Pchar(combobox1.Text),generic_read or generic_write,0,nil,open_existing,file_attribute_normal,0);
getcommstate(hcom,lpdcb);
lpdcb.baudrate:=9600;
lpdcb.ByteSize:=8;
lpdcb.Parity:=SpaceParity;
lpdcb.StopBits:=OneStopBit;
setcommstate(hcom,lpdcb);
end;

end.

送你个简单的代码,看对你有没帮助,在delphi 7调试通过。
 
请问用这句:
 hcom:=createfile(Pchar(combobox1.Text),generic_read or generic_write,0,nil,open_existing,[red]file_attribute_normal[/red],0);
打开的串口是在异步方式下工作的吗?
 
另外:我决定对这个程序不用异步操作了,决定采用同步多线程的方式做。还请各位多多帮忙,谢谢!
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
774
import
I
I
回复
0
查看
632
import
I
后退
顶部