给你一个例程,不知对你有没有用: unit comdemou; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;const Wm_commNotify=Wm_User+12; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); private Procedure comminitialize; Procedure MsgcommProcess(Var Message:Tmessage); Message Wm_commnotify; { Private declarations } public { Public declarations } end; //线程声明 TComm=Class(TThread) protected procedure Execute;override; end;var Form1: TForm1; hcom,Post_Event:Thandle; lpol:Poverlapped; implementation{$R *.DFM}Procedure TComm.Execute; //线程执行过程 var dwEvtMask:Dword; Wait:Boolean; Begin fillchar(lpol,sizeof(toverlapped),0); While True do Begin dwEvtMask:=0; Wait:=WaitCommEvent(hcom,dwevtmask,lpol); //等待串行口事件; if Wait Then Begin waitforsingleobject(post_event,infinite); //等待同步事件置位; resetevent(post_event); //同步事件复位; PostMessage(Form1.Handle, WM_COMMNOTIFY,0,0);//发送消息; end; end; end;procedure Tform1.comminitialize; //串行口初始化 var lpdcb:Tdcb; Begin hcom:=createfile('com2',generic_read or generic_write,0,nil,open_existing, file_attribute_normal or file_flag_overlapped,0);//打开串行口 if hcom=invalid_handle_value then else setupcomm(hcom,4096,4096); //设置输入,输出缓冲区皆为4096字节 getcommstate(hcom,lpdcb); //获取串行口当前默认设置 lpdcb.baudrate:=2400; lpdcb.StopBits:=1; lpdcb.ByteSize:=8; lpdcb.Parity:=EvenParity; //偶校验 Setcommstate(hcom,lpdcb); setcommMask(hcom,ev_rxchar); //指定串行口事件为接收到字符; end;Procedure TForm1.Msgcomm Process(Var Message:Tmessage); var Clear:Boolean; Coms:Tcomstat; cbNum,ReadNumber,lpErrors:Integer; Read_Buffer:array[1..100]of char; Begin Clear:=Clearcommerror(hcom,lpErrors,@Coms); if Clear Then Begin cbNum:=Coms.cbInQue; ReadFile(hCom,Read_Buffer, cbNum,ReadNumber,lpol); //处理接收数据 SetEvent(Post_Event); //同步事件置位 end; end;procedure TForm1.FormCreate(Sender: TObject); begin comminitialize; post_event:=CreateEvent (nil,true,true,nil); //创建同步事件; Tcomm.Create(False); //创建串行口监视线程; end;end.
procedure TForm1.FormCreate(Sender: TObject); begin mscomm1.InBufferCount:=0; mscomm1.InputLen:=0; mscomm1.RThreshold:=1; mscomm1.PortOpen:=true; end;procedure TForm1.MSComm1Comm(Sender: TObject); var recstr:olevariant; ss:string; begin if mscomm1.commevent=2 then begin recstr:=Mscomm1.input; ss:=recstr; showmessage(ss); end;end;procedure TForm1.Button2Click(Sender: TObject); var str:string;begin str:='sendinfo'; Mscomm1.output:=str; end;你的例子改了一下,试试
别急!
和设备通讯用哪种格式其实应该看设备是什么样的协议和要求.
你具体做什么我不太清楚,不过可以摧荐一本书
<<Delphi串口通信编程>>人民邮电出版的.里面有Mscomm的详细说明,
还有例子.
相信会对你很有帮助
unit comdemou;
interface
uses
Windows, Messages, SysUtils, Classes,
Graphics, Controls, Forms, Dialogs;const
Wm_commNotify=Wm_User+12;
type
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
Procedure comminitialize;
Procedure MsgcommProcess(Var
Message:Tmessage); Message Wm_commnotify;
{ Private declarations }
public
{ Public declarations }
end; //线程声明
TComm=Class(TThread)
protected
procedure Execute;override;
end;var
Form1: TForm1;
hcom,Post_Event:Thandle;
lpol:Poverlapped;
implementation{$R *.DFM}Procedure TComm.Execute; //线程执行过程
var
dwEvtMask:Dword;
Wait:Boolean;
Begin
fillchar(lpol,sizeof(toverlapped),0);
While True do Begin
dwEvtMask:=0;
Wait:=WaitCommEvent(hcom,dwevtmask,lpol);
//等待串行口事件;
if Wait Then Begin
waitforsingleobject(post_event,infinite);
//等待同步事件置位;
resetevent(post_event); //同步事件复位;
PostMessage(Form1.Handle,
WM_COMMNOTIFY,0,0);//发送消息;
end;
end;
end;procedure Tform1.comminitialize;
//串行口初始化
var
lpdcb:Tdcb;
Begin
hcom:=createfile('com2',generic_read or
generic_write,0,nil,open_existing,
file_attribute_normal or
file_flag_overlapped,0);//打开串行口
if hcom=invalid_handle_value then
else
setupcomm(hcom,4096,4096);
//设置输入,输出缓冲区皆为4096字节
getcommstate(hcom,lpdcb);
//获取串行口当前默认设置
lpdcb.baudrate:=2400;
lpdcb.StopBits:=1;
lpdcb.ByteSize:=8;
lpdcb.Parity:=EvenParity; //偶校验
Setcommstate(hcom,lpdcb);
setcommMask(hcom,ev_rxchar);
//指定串行口事件为接收到字符;
end;Procedure TForm1.Msgcomm
Process(Var Message:Tmessage);
var
Clear:Boolean;
Coms:Tcomstat;
cbNum,ReadNumber,lpErrors:Integer;
Read_Buffer:array[1..100]of char;
Begin
Clear:=Clearcommerror(hcom,lpErrors,@Coms);
if Clear Then Begin
cbNum:=Coms.cbInQue;
ReadFile(hCom,Read_Buffer,
cbNum,ReadNumber,lpol);
//处理接收数据
SetEvent(Post_Event);
//同步事件置位
end;
end;procedure TForm1.FormCreate(Sender: TObject);
begin
comminitialize;
post_event:=CreateEvent
(nil,true,true,nil); //创建同步事件;
Tcomm.Create(False);
//创建串行口监视线程;
end;end.
begin
mscomm1.InBufferCount:=0;
mscomm1.InputLen:=0;
mscomm1.RThreshold:=1;
mscomm1.PortOpen:=true;
end;procedure TForm1.MSComm1Comm(Sender: TObject);
var
recstr:olevariant;
ss:string;
begin
if mscomm1.commevent=2 then
begin
recstr:=Mscomm1.input;
ss:=recstr;
showmessage(ss);
end;end;procedure TForm1.Button2Click(Sender: TObject);
var
str:string;begin
str:='sendinfo';
Mscomm1.output:=str;
end;你的例子改了一下,试试
有问题可以给我发消息,或者来信:[email protected]
我做的程序是将天平和计算机连接,采集数据。
比如我计算机发一个命令“Z”,是要将天平清空的。关键是我发出去的命令好象天平没接受,所以我想可能是我发命令时“Z”的格式没写对。
也就是Mscomm1.output:=str;-----此处的str为字符?ACSII?16?
各位有经验的认为我发这个“Z”的时候以什么形式发呢?
再说一点,本人的MSCOMM设置应该没问题。
str:variant;begin
str:='z';
Mscomm1.output:=str;
end;
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleCtrls, MSCommLib_TLB, ExtCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
MSComm1: TMSComm;
procedure FormCreate(Sender: TObject);
procedure MSComm1Comm(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
var mmstr:olevariant;
aa:array of variant;
i:integer;
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
MScomm1.RThreshold :=1;
Mscomm1.InputLen :=0;
mscomm1.Settings :='9600,n,8,1';
Mscomm1.CommPort :=1;
Mscomm1.PortOpen :=true;
mmstr:='';
setlength(aa,8);
i:=0;
end;
procedure TForm1.MSComm1Comm(Sender: TObject);
var
recstr:olevariant;
begin
if Mscomm1.CommEvent =2 then
begin
recstr:=Mscomm1.Input ;
mmstr:=mmstr+ recstr;
showmessage(mmstr);
if length(mmstr)=8 then
begin
aa[i]:=mmstr;
i:=i+1;
mmstr:='';
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var j:integer;
begin
mscomm1.DTREnable:=true; //数据终端准备好
mscomm1.RTSEnable:=true; //请求发送
for j:=0 to i-1 do
memo1.Text:=aa[j];
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Mscomm1.PortOpen :=false;
mscomm1.DTREnable:=false;
mscomm1.RTSEnable:=false;
end;
end.
TMon = class(TThread)
private
pt : integer;
ph: string;
LineOff : Boolean;
Lasttime : TDatetime;
lastmodemstatus : Dword;
CmdBuf : array [1..10] of _Cmd;
lCmd,rCmd : integer;
procedure WriteCmd; //写出命令并负责读回数据
procedure CheckLineStatus; //主循环调用,检测线路状态
procedure SendToMaster(msgstr:string); //发送消息到主应用程序
public
ready : Boolean;
constructor create(port:integer;phone:string);
procedure WriteToCache(Cmd:_CMD);
protected
procedure Execute; Override;
end;procedure TMon.CheckLineStatus ;
var
thistime : Tdatetime;
Cmd : _CMD;
thismodemstatus : Dword;
begin
thismodemstatus := sio_lstatus(Pt);
if (not((thismodemstatus and s_cd)=s_cd) and ((lastmodemstatus and s_cd)=s_cd)) then LineOff := true ;
lastmodemstatus := thismodemstatus;
thistime := now;
if (thistime - lasttime) > (15/(24*60*60)) then begin
Cmd := BuildCmd(KeepConnectCmd);
WriteToCache(CMD);
end;
WriteCmd;
LineOff := false;
end;
procedure TMon.Execute;
var
Cmd : _CMD;
begin
if DailAndWaitConnection(pt,ph) then
While (Not Terminated) and (not LineOff) do
begin
Synchronize(CheckLineStatus);
sleep(100);
ready := true;
end;
ready := false;
if LineOff then SendToMaster('断线了。')
else begin
Cmd := BuildCmd(HangePhone);
WriteToCache(Cmd);writecmd;sleep(300);
HangLine(pt);
SendToMaster('线程结束。');
end;
end;
constructor TMon.Create(port:integer;phone:string);
begin
pt := port;
ph := phone;
FreeOnTerminate := True;
LineOff := false;
lCmd := 1;
rcmd := 1;
inherited Create(False);
end;