部分代码如下:
type
TRS485 = class(Tcomponent)
// 通讯串口
Timer1: TTimer; //引用Timer控件
constructor create(AWoner:Tcomponent);override;
destructor destroy; override;
//初始化串口通讯
procedure comminitialize;
procedure Timer1Timer(Sender: TObject);//定时器
implementation
constructor TRS485.create;
begin
Timer1 := TTimer.Create(nil);
Timer1.Interval := 200; //每200秒就触发事件
Timer1.OnTimer := Timer1Timer;
end;
procedure TRS485.comminitialize; // 串 行 口 初 始 化
Begin
//Timer1.interval := 200; //每200秒就触发事件
Timer1.Enabled := false;
end;
procedure TRS485.Timer1Timer(Sender: TObject);//定时器 每200MS触发一次事件
begin
CurCommandState := stOverTime;
end;
Procedure TRS485.FSM;
begin
CurCommandState := stSndCmd;
while true do
begin
case CurCommandState of
stSndCmd:
begin
SndTimes := SndTimes + 1;
//OverTimeFlag := 0 ;
SndCommand;
CurCommandState := stWaitAck ;
Timer1.Enabled := true;//启动定时器
end;
.........
end;
end;
现在问题是我在TRS485.FSM;这个过程中 Timer1.Enabled := true就已经设为启动了,但是现在问题是每隔200MS这个事件不能启动啊(也就是不能触发Timer1Timer(Sender: TObject)这个过程啊,帮我解决,谢谢!。很急,在线等,谢谢
type
TRS485 = class(Tcomponent)
// 通讯串口
Timer1: TTimer; //引用Timer控件
constructor create(AWoner:Tcomponent);override;
destructor destroy; override;
//初始化串口通讯
procedure comminitialize;
procedure Timer1Timer(Sender: TObject);//定时器
implementation
constructor TRS485.create;
begin
Timer1 := TTimer.Create(nil);
Timer1.Interval := 200; //每200秒就触发事件
Timer1.OnTimer := Timer1Timer;
end;
procedure TRS485.comminitialize; // 串 行 口 初 始 化
Begin
//Timer1.interval := 200; //每200秒就触发事件
Timer1.Enabled := false;
end;
procedure TRS485.Timer1Timer(Sender: TObject);//定时器 每200MS触发一次事件
begin
CurCommandState := stOverTime;
end;
Procedure TRS485.FSM;
begin
CurCommandState := stSndCmd;
while true do
begin
case CurCommandState of
stSndCmd:
begin
SndTimes := SndTimes + 1;
//OverTimeFlag := 0 ;
SndCommand;
CurCommandState := stWaitAck ;
Timer1.Enabled := true;//启动定时器
end;
.........
end;
end;
现在问题是我在TRS485.FSM;这个过程中 Timer1.Enabled := true就已经设为启动了,但是现在问题是每隔200MS这个事件不能启动啊(也就是不能触发Timer1Timer(Sender: TObject)这个过程啊,帮我解决,谢谢!。很急,在线等,谢谢
我喜欢用时钟控件去触发一个命令按钮的事件,而在界面上我会将那个命令按钮delete.
你的程序运行完了就将Timer1.Enabled := false就好了
begin
CurCommandState := stSndCmd;
while true do
begin
case CurCommandState of
stSndCmd:
begin
SndTimes := SndTimes + 1;
//OverTimeFlag := 0 ;
SndCommand;
CurCommandState := stWaitAck ;
Timer1.Enabled := true;//启动定时器
end;
这段代码有问题
你不能把读串口的过程也放到OnTimer里面做吗?
如放在ontimer里做的话,一样也要一开始进入死循环啊,你说呢?
unit uRS485;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls,QExtCtrls, CPort, CPortCtl;
type
TCommand = class
// 命令状态
State: integer;
// 命令类型
Kind: integer;
CommandStr: String;
private
{private declaration}
public
{public declaration}
end; TRS485 = class(Tcomponent)
// 通讯串口
ComPort: TComPort; //
constructor create(AWoner:Tcomponent);override;
destructor destroy; override;
//初始化串口通讯
procedure comminitialize;
procedure commclose;
procedure Timer1Timer(Sender: TObject);//定时器
procedure SendData;//发送数据
procedure FSM;//有限状态机
// 发送命令种类
procedure SndCommandCategory(kind:Integer);
// 发送命令
procedure SndCommand;
// 接受回答
procedure ComPortRxChar(Sender: TObject; Count: Integer);//接受命令
private
{private declaration}
Timer1: TTimer;
CurCommand: TCommand;
// 当前命令状态
CurCommandState: integer;
RepeatTimes: integer;
SndTimes: integer;
SndShakeHandstring : string;//存发送握手命令的字符
RcvShakeHandstring : String;//存接受握手命令的字符
SndStr : String;//存发送命令的字符
RcvStr : String;//存接受命令的字符
i : Integer;
rbuf : array [1..6] of byte;
sbuf : array [1..6] of byte;
hcom,Post_Event:Thandle;//设置串行口变量
public
{public declaration}
//Constructor create(AWoner:Tcomponent);override;
end;
const
{ Command Kind 命令类型 }
stSndCmd = 1; // 发送状态
stWaitAck = 2; // 等待状态
stRcvAck = 3; //接受到数据状态
stOverTime = 4; // 超时状态
stEnd = 5; //结束状态
{ 485状态 }
implementation
constructor TRS485.create;
begin
ComPort := TComPort.Create(Self);
Timer1 := TTimer.Create(nil);
Timer1.Enabled := false;
Timer1.Interval := 200;//每200秒就触发事件
Timer1.OnTimer := Timer1Timer;
ComPort.OnRxChar := ComPortRxChar;
end;destructor TRS485.destroy ;
begin
inherited destroy;
end;procedure TRS485.comminitialize; // 串 行 口 初 始 化
Begin
if ComPort.Connected then
ComPort.Close
else
ComPort.Open;
ComPort.Port := 'com1';
ComPort.BaudRate := br9600;
ComPort.DataBits := dbEight;
ComPort.StopBits := sbOneStopBit;
ComPort.Parity.Bits := prEven;
//Timer1.interval := 200; //每200秒就触发事件
//Timer1.Enabled := false;
end;procedure TRS485.Timer1Timer(Sender: TObject);//定时器 每200MS触发一次事件
begin
CurCommandState := stOverTime;
end;procedure TRS485.SendData;
var
i : integer;
begin
SndStr := '' ;
for i:= 1 to 5 do
begin
SndStr := SndStr + inttohex(sbuf[i],2) + '' ;
end;
ComPort.WriteStr(SndStr);
end;procedure TRS485.SndCommand;
var
Kind:Integer;
begin
//SndShakeHandCommand; //在发送每条命令前都要建立一次握手
SndCommandCategory(0);
end;Procedure TRS485.FSM;
begin
CurCommandState := stSndCmd;
while true do
begin
case CurCommandState of
stSndCmd:
begin
SndTimes := SndTimes + 1;
SndCommand;
CurCommandState := stWaitAck ;
Timer1.Enabled := true;//启动定时器
end;
stWaitAck:
begin
ComPortRxChar(self,20);//读端口方法
if RcvStr = '' then
begin
end
else
begin
CurCommandState := stEnd;
end;
//CurCommandState := stRcvAck;
end;
stOverTime:
begin
if SndTimes > 3 then
begin
CurCommandState := stEnd;
end
else
begin
SndTimes := SndTimes + 1; //继续发送
CurCommandState := stSndCmd;
end
end;
stEnd:
begin
//break;
Timer1.Enabled := False;
exit;
end;
else
begin
end;
end;
end;
end;procedure TRS485.SndCommandCategory(Kind:Integer);//发送命令的类别
begin
case Kind of
0: //结束命令
begin
sbuf[1] := byte($A5);
sbuf[2] := byte($FF);
sbuf[3] := byte($FF);
sbuf[4] := byte($FF);
sbuf[5] := byte($01);
SendData;
end;
end;
end;procedure TRS485.ComPortRxChar(Sender: TObject; Count: Integer); //读端口
Var
Temp_receive : array of byte;
I,rec_len : byte;
Calculate_crc,rec_crc,reg,reg_value : word;
Begin
RcvStr := '';
ComPort.ReadStr(RcvStr, Count);
end;procedure TRS485.commclose;
begin
ComPort.Close;
end;
end.