MSCOMM串口通讯问题(300分奉送)(300分)

  • 主题发起人 主题发起人 junye--li
  • 开始时间 开始时间
J

junye--li

Unregistered / Unconfirmed
GUEST, unregistred user!
以下是我的程序:(变频器通讯控制问题)
出现的问题是:每发送信号,速率可以设定,正转一下,马上停止,报警,也未出现反馈信息.我现在找不出是那设置出错了,请大家帮忙找找原因,谢谢!

双击MSCOMM控件图标,其属性设置为(程序中也有设定,不知和这些属性有关没?):
general项中handshaking设置为0-comNone
Buffers项中InbufferSize设置为1024 ,OutBuffersize设置为 512
RThreshold设置为0,SThreshold设置为0, InputLen设置为0, EOFEnable复选框未选择
Hardware项中 PairityReplace设置?(系统设置)
NullDiscard未选 RTSEable选 DTREable选

unit Unit1;

interface

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

type
TForm1 = class(TForm)
MSCommain: TMSComm;
SpeedButton1: TSpeedButton;
Edit1: TEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Memo2: TMemo;
Edit2: TEdit;
SpeedButton2: TSpeedButton;
SpeedButton3: TSpeedButton;
procedure FormCreate(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
procedure MSCommainComm(Sender: TObject);
procedure SpeedButton3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation


{$R *.dfm}


procedure TForm1.FormCreate(Sender: TObject);
begin
mscommain.CommPort:=1;
mscommain.InBufferSize:=1024;
mscommain.OutBufferSize:=512;
mscommain.Settings:='19200,n,8,1';
mscommain.InBufferCount:=0;
mscommain.RThreshold:=1;
mscommain.InputLen:=0;
mscommain.DTREnable:=false;
mscommain.RTSEnable:=false;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
writestr,s,t,a1,a2:string;
temp1:integer;
begin
if not mscommain.PortOpen then
mscommain.PortOpen:=true;
mscommain.InBufferCount:=0;
mscommain.InputLen:=0;
mscommain.RThreshold:=1;
mscommain.DTREnable:=true;
mscommain.RTSEnable:=true;
mscommain.Output:=chr(5)+'00FB10002DB';//(设定通讯操作)
sleep(300);
mscommain.Output:=chr(5)+'00EE103E8FB';//设定速率
sleep(300);
mscommain.Output:=chr(5)+'00FA1027A';//设定正转
sleep(500);
end;


procedure TForm1.MSCommainComm(Sender: TObject);
var
recstr,I : Variant;
cc,pd : string ;
begin

if Mscommain.CommEvent = 2 then
begin
I:=MSCommain.InBufferCount;
MSCommain.InputLen:=I;

recstr := Mscommain.Input ;
Memo2.text := Memo2.Text+recstr;
cc := string(recstr);

Memo2.Lines.Add('MSCOMM is ok');
Memo2.Lines.Add(recstr);
pd:=copy(recstr,1,3);
sleep(100);
end;
if pd=chr(6)+'00' then
showmessage('写入数据正确!')
else
begin
if pd=chr(15)+'00'+'0' then
showmessage('计算机NAK错误:从计算机发送的通讯请求数据被检测到的连续错误次数超过规定的允许再试次数!');
if pd=chr(15)+'00'+'1' then
showmessage('奇偶校验错误:奇偶校验结果与规定的奇偶校验不相符!');
if pd=chr(15)+'00'+'2' then
showmessage('总和校验错误:计算机中的总和校验代码与变频器接收的数据不相符!');
if pd=chr(15)+'00'+'3' then
showmessage('协议错误:变频器接收的数据有文法错误,或在规定的时间内未完成数据通信,CR、LF没有按照参数的设定!');
if pd=chr(15)+'00'+'4' then
showmessage('格式错误:停止位长不符和规定!');
if pd=chr(15)+'00'+'5' then
showmessage('溢出错误:变频器完成前面的数据接收之前,从计算机又发送了新的数据!');
if pd=chr(15)+'00'+'7' then
showmessage('字符错误:接收的字符无效(在0~9、A~F的控制代码以外)!');
if pd=chr(15)+'00'+'A' then
showmessage('模式错误;试图写入的参数在计算机通讯操作模式以外或变频器在运行中!');
if pd=chr(15)+'00'+'B' then
showmessage('指令代码错误:规定的指令不存在!');
if pd=chr(15)+'00'+'C' then
showmessage('数据范围错误;规定了无效的数据用于参数写入、频率设定等!');
end;

end;

procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
memo1.Lines.Clear;
memo2.Lines.Clear;
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
close;
end;

end.
 
看看是不是硬件通讯问题。代码好象没大问题
 
出现的问题是:每发送信号,速率可以设定,正转一下,马上停止,报警,也未出现反馈信
从你写的,通讯应该正常。你设置命令已经发送到设置,而且设备已经正确执行,正转一下后就停止,然后报警。
我们可以做这样的假设,是否可能是设备本身的问题,接收命令执行的时候出现问题,然后设备就报警了,这个时候也就没有反馈信息回来。
给你另外一个想法供参考:
1、你手上是否有手段可以测试设备的状态,在怀疑你软件存在问题的时候,必须首先确信设备没有问题。
2、如果设备真的已经测试属于好的状态,你可以使用串口调试工具输出命令,看设备是否正确执行。
3、以上两条完成测试以后,再后过头来检查分析你的程序。或者更换一种通讯控件。我曾经遇到过一个设备,当时只能使用spcomm和mscomm中的一个,我忘记是哪一个才可以了。反正另外一个怎么都不可以。

题外话,纯粹个人观点。不一定有效。
 
通信速率设置对吗?
硬件有问题的话也应该能很快查出。
 
我也是这样认为.因为你的通信字节不多.所以我也建议先用串口调试工具,将数据发往设备,看能否正常运行.如果能,那问题在你程序.再说也可以从串口调试工具看到从设备返回的信息.然后再运行你的程序,在
procedure TForm1.MSCommainComm(Sender: TObject);
处设置断点,看接收到 的数据是什么?
这样一步一步分折,问题应该可以解决的.
 
mscom本身没问题,应该是你对变频器的协议没有理解透侧,要是该变频器是刚刚开发出来的新品,还没测试过,那设备的问题比较大,你可以拿它的测试程序调测以下。
 
我找到两个串口调试工具,程序发复位信号chr(5)+'00FD19696F9'变频器可以复位,但用串口调试工具如何发,是chr(5)+00FD19696F9,还是chr(5)00FD19696F9或者其他的,我试了几次没成功!现没有测试硬件的好方法,但其手动操作正常,有可能线缆有点问题,但也不太像!要求是5芯电缆,但买到的是8芯的!一头是9孔,一头是RJ45的!
协议书写正确,速率设置正确!变频器没有自带软件!如果谁能用spcomm帮我写个程序我再测试一下就更好了!
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3461218
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3461194
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3368615
以上3个网址还有160分一起奉上!那几个问题有一个是关于接线问题,其余都已解决!
 
我还没有找到原因.如果只发速率信号,手动查看已经设置上,但马上报警,复位后手动按正转键会以设定的速率转;如果继续发正转信号会转一下,马上停报警,复位后手动按正转键仍会以设定的速率转动;如果一起发,也是转一下就停报警.是软件还是硬件原因?
RThreshold设置为1,没发一个字节就产生ONCOMM事件,没弄懂!我发应该有几十个字节!
还有其他属性不知还有没有应该仔细设定而忽略的?mscommain.Settings:='19200,n,8,1';
中无较验,8数据位,1停止位有特殊规定吗?是根据什麽设定调试的?
 
已经正常接收速率信号,我觉得通讯已经通讯协议都应该已经正常了。试试这样的测试,你可以计算机的另外一个串口,把你发送到设备的信息读回来。看看出去的是不是有协议之外的其他内容,我觉得不排除这样的可能。
我们可以这样理解,你首先发送速度,如果接下来还有其他的内容,但是对于设备是不可识别的,此时设备报警属于正常的反应。但是速率参数已经正确接收,也就是复位以后可以手工操作。
另外,你可以删除mscomm ,重新建立一个,除去通讯参数,其他的全部使用默认值。可以测试看看。和设备打交道顺利的时候很简单,有问题的时候累死人。
 
现在的问题是,我实验室电脑只有一个串口!返回值用 Memo.Lines.Add()写吗?mscommain.Output或MSCommain.InputLen给予付值吗?
其实我先发的是 mscommain.Output:=chr(5)+'00FB10002DB';//(设定通讯操作)
再发速率或其他控制命令的!串口调试软件也没成功,就是没反应!继续测试!
 
使用另外一台计算机啊。
 
那位哥们能否提供些SPCOMM的源代码或更有价值的建议,真的希望一周内可以解决问题!
 
使用控件有时候很麻烦,你能否用API+线程呢?以下代码希望能够对你有帮助:
主程序声明:ComThread:TCommThread;
主程序调用:
ComThread := TCommThread.create(True);
ComThread.Com := ComPort;
//ComThread.Memo:=Memo1;
ComThread.BortRate:=strtoint(BortRate);
if ComThread.CommInitialize then begin
ComThread.Resume;
CommError:=True;
end else CommError:=False;
if CommError=False then
showmessage('Comm Port Error!');
主程序关闭:ComThread.ExistExecute:=False;
线程基本代码(某些语句你不需要,未删除):
unit CommManager;
//(4,53)按"."直接退出:目的地不会单一,至少有两种可能
//采集的项目列表可能也需要模仿选择工序的显示方法,不过如果少则不需要
interface

uses
Windows, Classes,SysUtils,ComCtrls,
StrUtils,ScktComp,StdCtrls,PublishDM,DateUtils,PublicFiles;

type
TCommThread = class(TThread)
private
{ Private declarations }
fCom: Integer;
fBortRate: Integer;
fLoopTime: Integer;//系统轮循等待时间
fComState: Integer;//端口状态变量 0初始状态;1正常;2失败
fThreadExit : Boolean;//线程退出标识
fMemo:TMemo;
fRevString : string;
sleeptime: integer;

fHcom,fPost_Event:Thandle; //Comm接收参数
fLpolW,fLpolR:Poverlapped; //Comm接收参数
protected
Public
ExistExecute : Boolean;
fTermIndex : Integer; //当前终端索引号
fCurTerm : PTermInfo;

procedure Over;
procedure Execute; overRIDE;
constructor Create(CreateSuspended: Boolean=FALSE);
destructor Destroy; override;

Function SetNextTerm():pTermInfo;
procedure SendData();
//发送数据到终端
function CommInitialize():Boolean;
Procedure CommDestroy;
Procedure ReadStr();
Function WriteStr(Com:integer;const Str:String):Boolean;
Published
property Com :integer read fCom write fCom default 1;
property BortRate :integer read fBortRate write fBortRate default 9600;
property LoopTime:Integer read fLoopTime write fLoopTime default 10;//系统轮循等待时间
property ComState:Integer read fComState write fComState default 0;//端口状态变量
property ExitThread: Boolean read fThreadExit write fThreadExit;
property Hcom:Thandle read fHcom write fHcom ;
property Post_Event:Thandle read fPost_Event write fPost_Event ;
property Memo:TMemo read fMemo write fMemo;
end;

implementation

procedure TCommThread.Over;
begin
ExitThread := True;
ExistExecute := False;
end;

function TCommThread.CommInitialize():Boolean;
Var Lpdcb:TDCB;
begin
Result := True;
hcom:=createFile(pChar('com'+inttostr(fCom)), //串口名,可为com1-com4
generic_read or Generic_write,//访问模式
0, //共享模式,必须为0
nil, //安全属性指针
open_existing, ///找开方式必须为open_existing
File_Flag_Overlapped,//文件属性,本文设为交迭标志
0); //临时文件句柄,必须为0
if hcom<>invalid_Handle_Value then
begin
//BaudRate:波特率,可直接设为110、300、600、1200、2400、4800、9600、19200等值。
//ByteBits:数据位长度,可高为4-8。
//Parity:奇偶校验方式,0-4分别为无、偶、奇、空
//StopBits:停止位长度,0,1,2分别为1、1.5、2位
SetupComm(hcom,4096,4096); //设置缓冲区长度
getCommState(hcom,lpdcb); //设置串口
lpdcb.baudrate:=fBortRate;
lpdcb.stopbits:=0;
lpdcb.bytesize:=8;
lpdcb.parity:=0;
setCommState(hcom,lpdcb);
SetCommMask(Hcom,ev_Rxchar); //设置串口事件屏蔽
end else begin
//无法打开串口
Result := False;
exit;
end;
SendData;
New(flpolW);
New(flpolR);
fLpolW^.Internal:=0;
fLpolW^.InternalHigh:=0;
fLpolW^.Offset:=0;
fLpolW^.OffsetHigh:=0;
fLpolW^.hEvent:=Createevent(nil,true,False,nil);
fLpolr^.Internal:=0;
fLpolr^.InternalHigh:=0;
fLpolr^.Offset:=0;
fLpolr^.OffsetHigh:=0;
fLpolr^.hEvent:=Createevent(nil,true,False,nil);
PurgeComm(Hcom,Purge_TxAbort or Purge_RxAbort or Purge_Txclear or Purge_Rxclear);
fPost_Event:=Createevent(nil,true,true,nil);
end;
Procedure TCommThread.CommDestroy; //释放内存
begin
if (fLpolW<>nil) then begin
CloseHandle(fLpolW^.hEvent);
dispose(flpolW);
fLpolW:=Nil;
end;
if (fLpolR<>nil) then begin
CloseHandle(fLpolR^.hEvent);
dispose(flpolR);
fLpolR:=Nil;
end;
SetEvent(fPost_Event);
CloseHandle(fPost_Event);
CloseHandle(fHcom);
end;
Procedure TCommThread.ReadStr(); //接收数据
var
clear:boolean;
coms:TComStat;
cbNum,Cbread,lpErrors:Dword;
S,S1,S2,S3,S_Temp:String;
i,iPos:integer;
P:PProcBarCodeInfo;
pTmp:PTermInfo;
begin
clear:=clearCommerror(hcom,lperrors,@Coms);
if clear then
begin
cbnum:=Coms.cbInQue; //获取接收缓冲区待接收字节数
setlength(S_Temp,cbnum+1); //分配内存
ReadFile(hcom,PChar(S_Temp)^,cbnum,Cbread,fLpolR);//读串口
setlength(S_Temp,cbread); //分配
//读取数据
fRevString:=fRevString+S_Temp;
S:=TransferHexToString(fRevString);
if S<>'' then begin
fRevString:='';
iPos:=-1;
//获得地址、条码、标志
S1:=Copy(S,2,1);
if Copy(S,Length(S),1)='1' then S3:='OK'
else S3:='NG';
if MonitorType=3 then begin
//获得条码和OK/NG标志
S2:=Copy(S,3,Length(S)-3);
if S2<>'' then begin
for i:=0 to fTermList.Count-1 do begin
pTmp:=PTermInfo(fTermList);
if pTmp.TermiAddr=S1 then begin
iPos:=i;
Break;
end;
//if pTmp.TermiAddr=S1 then begin
// if pTmp.StateValue<>'OK' then iPos:=i;
// Break;
//end;
end;
if iPos<>-1 then begin
if (pTmp.BarCode<>S2) or (pTmp.StateValue<>S3) then begin
pTmp.BarCode:=S2;
pTmp.StateValue:=S3;
new(P);
P.TermiAddr:=S1; //十六进制表示
P.BarCode:=S2;
P.StateValue:=S3;
SaveInfoList.Add(P);
end;
end;
end;
end else begin
//仅获得OK/NG标志
if SaveInfoList<>nil then begin
if (SaveInfoList.Count>0) and (S3<>'') then begin
P:=PProcBarCodeInfo(SaveInfoList[0]);
if UpperCase(Trim(P.StateValue))<>S3 then begin
P.StateValue:=S3;
P.SaveState:=True;
end;
end;
end;
end;
end;
SetEvent(fPost_Event); //同步事件置位
end else begin
CommError:=False;
end;
end;

Function TCommThread.WriteStr(Com:integer;const Str:String):Boolean;
var
DwCharsWritten,DwRes:Dword;
S_DATA:String;
BRes:boolean;
Begin
BRes:=False;
S_Data:=Str;
if fHcom<>INVALID_HANDLE_VALUE then
begin
DwCharsWritten:=0;
BRes:=WriteFile(fHcom,PChar(S_Data)^,Length(S_Data),
DwCharsWritten,fLpolW); //返回True,数据立即发送完成
if not BRes then
begin
if GetLastError()=Error_IO_Pending then
begin //正在发送数据
DwRes:=WaitForSingleObject(fLpolW^.hEvent,Infinite);
if DwRes=Wait_Object_0 then // 如果不相等,出错
BRes:=GetOverLappedResult(fhcom,fLpolW^,DwCharsWritten,False) //返回False,出错
else BRes:=true; //数据发送完成
end;
end;
end;
Result:=Bres;
end;

procedure TCommThread.Execute;
var
//Comm接收参数
dwEvtmask,dwOvres,bb:Dword;
RXFinish:Bool;
begin
fRevString:='';
SleepTime := 0;
ExistExecute := true;
if fTermList.Count<=0 then exit;
fCurTerm := fTermList[0];
fTermIndex := 0;
While ExistExecute do begin
try
DwEvtMask:=0;
RXFinish:=WaitCommEvent(fHcom,dwevtmask,fLpolR); //等待串口事件EV_RXCHAR
if not RXFinish then //如果返回True,已立即完成,否则继续判断
if GetLastError()=ERROR_IO_PENDING then //正在接收数据
begin
bb:=WaitForSingleObject(fLpolR^.hEvent,5);//等待5ms
Case bb of
Wait_Object_0: RXFinish:=GetOverLappedResult(fHcom,fLpolR^,dwOvRes,False);
//返回False,出错
Wait_TimeOut: RXFinish:=False;//定时溢出
else RXFinish:=False; //出错
end;
end else begin
RXFinish:=False;
CommError:=False;
end;
if RXFinish then
begin
if WaitForsingleobject(fPost_Event,infinite)=Wait_Object_0 then //等待同步事件置位
begin
resetEvent(fPost_Event); //同步事件复位
//在这里可以触发串口接收事件
ReadStr;
//Synchronize(ReadStr);
end;
end;
//Sleep(LateTime);
Synchronize(SendData);
Sleep(LateTime);
except
end;
END;
// WriteLog(TermLog,'T');
end;

constructor TCommThread.Create(CreateSuspended: Boolean);
begin
fThreadExit := false;
inherited Create(CreateSuspended);
end;

destructor TCommThread.Destroy;
begin
inherited Destroy;
CommDestroy;
end;


//获取下一可用终端
Function TCommThread.SetNextTerm():pTermInfo;
VAR I: INTEGER;
Tmp: pTermInfo;
Str1: String;
begin
result := nil;

FOR I :=0 TO fTermList.Count -1 do begin
Inc(fTermIndex);
IF fTermIndex >= ftermlist.Count THEN BEGIN
fTermIndex := 0;
END;
Tmp := ftermlist[fTermIndex];
if Tmp.bStop THEN begin //终端不使用
continue;
end else begin ////终端在使用
result := Tmp;
break;
end;
end;
end;

//发送数据到终端
procedure TCommThread.SendData();
var pt:pTermInfo;
S:String;
begin
if MonitorType=2 then begin
if fFileList.Count>0 then
ShellChangeNotifierChangeMonitor(ProcDirect,ProcDirectValue,PO,PPP,fMemo);
end;
fCurTerm:=SetNextTerm;
PT := fCurTerm;
If PT= nil then exit;
//因为线程是不停的发,第一次错,第二次可能就对了,所以校验码其实作用不大
if MonitorType=2 then begin
S:=Chr(HexMod256ToAsc('A'+TermiAddr));
S:=CharToHex(TermiAddr)+CharToHex(S);
WriteStr(fCom,Chr($48)+Chr($34)+Chr($31)+S+Chr($47));
end else begin
S:=Chr(HexMod256ToAsc('B'+pt.TermiAddr));
S:=CharToHex(pt.TermiAddr)+CharToHex(S);
WriteStr(fCom,Chr($48)+Chr($34)+Chr($32)+S+Chr($47));

///x48 /x34 /x32 /x33 /x31 /x33 /x32 /x47
{if PT.TermiAddr='1' then
WriteStr(fCom,Chr($48)+Chr($34)+Chr($32)+Chr($33)+Chr($31)+Chr($33)+Chr($32)+Chr($47))
else if PT.TermiAddr='2' then
WriteStr(fCom,Chr($48)+Chr($34)+Chr($32)+Chr($33)+Chr($32)+Chr($33)+Chr($33)+Chr($47))
else if PT.TermiAddr='3' then
WriteStr(fCom,Chr($48)+Chr($34)+Chr($32)+Chr($33)+Chr($33)+Chr($33)+Chr($34)+Chr($47))
else if PT.TermiAddr='4' then
WriteStr(fCom,Chr($48)+Chr($34)+Chr($32)+Chr($33)+Chr($34)+Chr($33)+Chr($35)+Chr($47))
else if PT.TermiAddr='5' then
WriteStr(fCom,Chr($48)+Chr($34)+Chr($32)+Chr($33)+Chr($35)+Chr($33)+Chr($36)+Chr($47))
else if PT.TermiAddr='6' then
WriteStr(fCom,Chr($48)+Chr($34)+Chr($32)+Chr($33)+Chr($36)+Chr($33)+Chr($37)+Chr($47));
}
end;
end;

end.
 
TO ldey-999:说实话,你的程序很好,只是我没看懂你这段用API加线程写的程序!线程我没做过,很多语句我不知干啥的,有用没!程序的主程序说明及主程序调用一般写在那里?我只是想发几个十六进制字符串。如:chr(5)+'00FB10002DB'(设定通讯操作);chr(5)+'00EE103E8FB'(设定速率);chr(5)+'00FA1027A'(设定正转)。应该把这几句话具体加在那里?
我的程序设置为:使用COM1口,通讯速率19200,无校验,8位数据位,1位停止位(mscommain.Settings:='19200,n,8,1')。请你再帮下忙,帮我把这个程序完善一下,校验那部分不用你帮忙加,谢谢!

TO zywcd:你提供的建议也不错,只是我按你的建议没有解决问题,现在还不知用串口调试程序应该到底发那个字符串CHR(5)怎麽写!用SPCOMM自己写估计得几天,现在主要还有别的事,有些乱,写不下去!现在我这里都是只有一个串口的机器,很遗憾!下面的语句其实也已经写返回语句了,可惜没有返回!
I:=MSCommain.InBufferCount;
MSCommain.InputLen:=I;
recstr := Mscommain.Input ;
Memo2.text := Memo2.Text+recstr;
是在procedure TForm1.MSCommainComm(Sender: TObject)中定义的!不知这样写有问题没?

TO sxwy:在procedure TForm1.MSCommainComm(Sender: TObject);处设置断点,看接收到 的数据是什么? 请问断点如何设置呀?谢谢!

我最近几天休假回老家,大家还有什麽好主意,多给些建议呀!现在的结果还和上两天的一样,没有进展!
 
其实:你要做的是三个操作,
一个是设定操作,一个是设定速率,一个是要变频器正转.
那么我想,既然出错了,为什么不考虑一个一个过程完成呢.
过程一:
mscommain.Output:=chr(5)+'00FB10002DB';//(设定通讯操作)
sleep(300);
过程二:
mscommain.Output:=chr(5)+'00EE103E8FB';//设定速率
sleep(300);
过程三:
mscommain.Output:=chr(5)+'00FA1027A';//设定正转
sleep(500);
然后在MSCOMMON事件里用鼠标双击进行断点设定.每一个过程调试一遍,看变频器返回是否正确,如果是最后的设定正转过程出错,那么你在断点里看有有没有返回信息,返回信息是什么?
分折:
如果在设定速率和通信操作都有返回,而设定正转没有返回的话,那肯定是变频器在接收设定正转指令的时候出错(因为你如果操作通信和设定速率都成功的话,那肯定你的数据能发到变频器,至少证明线路是好的,指令是正确的).

这个时候你就要考虑硬件的问题(要排除设定正转指令错误的可能性),不要老是想你自已.这本来就上上层软件和下层软件配合的问题.不是你一个人的事.
有时间发协议来看一下.
 
不好意思,让你晕了!不过我喜欢API加线程,一切尽在掌握之中!
1、CommInitialize:初始化端口变量
2、你应该建立一个发送命令的队列,全局变量,这样你就可以在主程序中控制了
3、在ReadStr中得到你的接收信息,一旦获得需要报警的信息,你就可以将该信息加入到接收队列中,有待处理,参见代码:
if clear then
begin
...
//读取数据
fRevString:=fRevString+S_Temp;
S:=接收处理函数;
if S<>'' then begin
end else begin
end;
SetEvent(fPost_Event); //同步事件置位
end else begin
CommError:=False;
end;
4、在主程序中处理接收队列信息,将需要的处理结果加入到发送队列信息
5、根据发送队列的信息,在函数SendData中书写处理代码:
if 发送队列.Count>0 then begin
AAA:=发送队列[0];
发送队列.Delete(0);
WriteStr(fCom,AAA);
end;
6、退出主程序时销毁线程,见以上说明
7、其他函数说明:
Create、Destroy:线程创建必须的函数;Execute:线程创建后会立即执行;Over:可以保留先;WriteStr:向串口发送数据函数,你不能改了;SetNextTerm:如果你有不同的终端需要轮巡,可以考虑使用这个函数,在SendData中也有相关的代码,一次轮巡一个终端就可以了
 
InputLen:= 1; // 这才是关键!
 
其实用MSCOMM也未必不可以,可以说更稳定.跟据每个人的爱好吧.
用API及线程是更透明一点.
同意SUPERMANTM的观点.InputLen:= 1
但是由于楼主说可以设定通信操作及设定速率,所以我怀疑在通信方面是没有问题的.而有可能错就错在设定正转的这一步上.
 
标记,有空来学习!!
大家继续。。。。
 
谢谢大家的参与,我休假结束!调试成功,原因是变频器的一个参数设置的值太小!多谢!
再过几天结帐!与InputLen:= 1无关!现在的问题是为啥没有反馈呀??
procedure TForm1.MSCommainComm(Sender: TObject);
var
recstr,I : Variant;
cc,pd : string ;
begin
if Mscommain.CommEvent = 2 then
begin
I:=MSCommain.InBufferCount;
MSCommain.InputLen:=I;
recstr := Mscommain.Input ;
Memo2.text := Memo2.Text+recstr;
Memo2.Lines.Add('MSCOMM is ok');
Memo2.Lines.Add(recstr);
pd:=copy(recstr,1,3);
sleep(100);
end;
if pd=chr(6)+'00' then
showmessage('写入数据正确!').....

TO DEY-999 : 真想把API弄通,还是不行呀!用API还是没成功!RDA,RDB<=>M+,M-
SDA,SDB<=>T-/A,T+/A 是对应关系还是应该那样接?我的转换器是R+,R-.

最后的问题还有就是写加速延迟时间没成以及没有反馈!可能是语法或协议那的问题!大家帮忙出出主意呀!
 

Similar threads

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