串口通信高手请进!(200分)

  • 主题发起人 主题发起人 avant
  • 开始时间 开始时间
A

avant

Unregistered / Unconfirmed
GUEST, unregistred user!
测试程序如下:
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
Label1: TLabel;
Button1: TButton;
procedure Memo1KeyPress(Sender: TObject; var Key: Char);
procedure FormDestroy(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
hCom:Thandle;
Connected:boolean;
NotifyWnd : HWND; // This is used for the timer
procedure TimerWndProc( var msg: TMessage );
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

{******************打开、初始化串口*************************}
procedure TForm3.Button1Click(Sender: TObject);
var
dcb:TDCB;
tms: TCOMMTIMEOUTS;
strOut:string;
WriteNum:Cardinal;
begin
hCom := CreateFile(
'com1',
GENERIC_READ or GENERIC_WRITE,
0, // Not shared
nil, // No security attributes
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0 // No template
) ;
if HCom > 0 then
begin
BuildCommDCB('Com1:9600,n,8,1',dcb);
SetCommState(hcom,dcb);
tms.ReadIntervalTimeout := MAXDWORD;
tms.ReadTotalTimeoutMultiplier := 0;
tms.ReadTotalTimeoutConstant := 0;
tms.WriteTotalTimeoutMultiplier := 0;
tms.WriteTotalTimeoutConstant := 1000;
SetCommTimeOuts( hcom, tms );
PurgeComm( hcom, PURGE_TXCLEAR );
PurgeComm( hcom, PURGE_RXCLEAR );
{初始化}
strOut:='ATZ'+#13#10;
WriteFile(hcom,strOut,Length(strOut),WriteNum,nil);
{接收定时器}
NotifyWnd := AllocateHWnd( TimerWndProc );
SetTimer( NotifyWnd, 1, 50, nil );
Connected:=true;
Label1.Caption:='Connect Ok';
end;
end;

{****************************发数据**************************}
procedure TForm3.Memo1KeyPress(Sender: TObject; var Key: Char);
var
nsent: DWord;
begin
if Connected then
WriteFile(hcom,Key,1,nsent,nil);
end;

{****************************读数据**************************}
procedure TForm3.TimerWndProc(var msg: TMessage);
var
nRead: dword;
ReadBuffer : array[0..100] of char;
begin
if (msg.Msg = WM_TIMER) and Connected then
begin
nRead := 0;
if ReadFile( hCom, ReadBuffer, Length(ReadBuffer), nRead, nil ) then
if (nRead <> 0) then
Memo2.Lines.Add(ReadBuffer);
end;
end;

procedure TForm3.FormDestroy(Sender: TObject);
begin
KillTimer(NotifyWnd,1);
CloseHandle(Hcom);
end;

end.

问题:
1)以上程序在Delphi的IDE环境运行一切正常,每在Memo1中写一字母,就在Memo2
中收到,并能正确响应.如:Memo1中输入ATL0,Memo2中立即显示ATL0,Ok.但是一脱离IDE
环境就出异常(access violation...in module 'DERNEL32.DLL')!!! Why???
2)我对Memo1KeyPress改进了一下,当收到回车时才发送,代码如下:
procedure TForm3.Memo1KeyPress(Sender: TObject; var Key: Char);
var
nsent: DWord;
DataSent:Pchar; //用String也不行!!!
SizeSent:integer;
begin
if (Key=#13)and(Connected) then
begin
DataSent:=PChar(Memo1.Lines[Memo1.Lines.Count-1]);
SizeSent:=Length(DataSent);
WriteFile(hcom,DataSent,SizeSent,nsent,nil);
WriteFile(hcom,Key,1,nsent,nil);
end;
end;
Memo2显示的全是乱码!

已做如下测试(对DataSent):
用PChar,用String,用String+#13#10,用String+#0(该法在直接发时有效:'atdt163');
请高手指教!谢谢!
 
1)是不是编译没加包呵
2)DataSend: array [0..80] of char;
 
iie:
1)加了,只有点了按钮打开串口时才发生异常,有什么特殊的包要加吗?
2)忘了说了,这种方式我也已经试过,也不行的.
Thanks.Please go on!
 
Memo2.Lines.Add(ReadBuffer);
这句有问题
 
1) BuildCommDCB('Com1:9600,n,8,1',dcb);这句改为GetCommDCB
然后在后面修改DCB就可以
2) ReadBuffer要先变为string形式再lines.add

*) 这样的程序只是实验而已,没有实用价值
 
1.事实上,我先用的GetCommDCB,然后在后面修改DCB,什么也收不到,改BuildCommDCB('Com1:9600,n,8,1',dcb)
一个一个发能收,多了收到乱码, :(
2.Memo2.Lines.Add(String(ReadBuffer));也无效,:(
*.确是实验而已,实用价值?习习,谁把卖钱的东希望这儿贴呀!
还望各位大虾相助喽!
 
可能性:
1。没有使用流控制。即CTR,DTR。
2。没有使用事件。当发送端还没发时,你就开始读了。当然是乱码。
应:
1。使用流控制。
2。使用已有的控件。如MSCOMM。
 
这两个问题我都做通了,没有问题呵,
1)你先去掉修改DCB的代码,直接GetCommDCB跟SetCommDCB试试(默认值)
2)string(ReadBuffer)是不行的
怎么也得for i := 0 to nread - 1 do s := s + ReadBuffer;
add(s);

 
你怎么不用Spcom,我常用,爽得很,不妨试试,有问题找我
 
可以帮我看一看这个问题吗?借用宝地了:)
http://www.gislab.ecnu.edu.cn/delphibbs/DispQ.asp?LID=354525
 
还不行噢!请继续!
 
真见鬼了,我把你的程序都贴过来,改了两行,编译,运行,肯定好用呵。

PS:我用的是D3,除了上面的两条改动外,更新Memo2后我刷新了form,否则虽然add了,
但显示并没有出来。
 

DATASENT :STRIGNG[N],
WriteFile(hcom,DataSent[1],SizeSent,nsent,nil);
只有这样行,为什么不知道
 
wuling:那当然了,字符串存储的[0]是长度呵
 
我投降!还是用MSComm吧!
 
多人接受答案了。
 
Spcom在哪里能够找到?
 

Similar threads

I
回复
0
查看
647
import
I
I
回复
0
查看
785
import
I
I
回复
0
查看
547
import
I
I
回复
0
查看
470
import
I
后退
顶部