奇怪问题,请高手回答关于MSCOMM问题。(200分)

  • 主题发起人 主题发起人 runnerwise
  • 开始时间 开始时间
R

runnerwise

Unregistered / Unconfirmed
GUEST, unregistred user!
本人在开发一个485的门禁通讯程序,单片机通讯时候出了莫名其妙的问题,问题如下:
通讯的指令在“串口调试助手”程序中全部通过,通讯都正常,发送、接收一切OK。在DELPHI中采用MSCOMM控件调试中发现以下情况:
首先要说明一下:PC与读卡器的通讯为主从方式,PC机为主方式,读卡器为从方式;
PC机向读卡器发送的数据格式为:
起始字节+读卡器地址+功能码+数据字节数+数据(没有数据时,此项为空)+校验码+结
33 03 06 02 AA F3 BB
束字节
EE 
调试的时候发现奇怪的事情,当调试功能码中有(A~F)的指令,下位机没有响应,然后执行功能码中没有(A~F)的指令,会受到影响,现象为:必需在发送指令2~3次后,通讯才正常,前2~3次下位机的反映为收到了乱码。我程序通讯的代码如下:
procedure TForm1.Button9Click(Sender: TObject);
var
sendstr,str,strCmd :string;
i,j,Len:integer;
senddata:array[1..10] of char;

begin
senddata[1]:=chr($55)
//要发送的数据
senddata[2]:=chr($03);
senddata[3]:=chr($F1);
senddata[4]:=chr($00);
senddata[5]:=chr($F4);
senddata[6]:=chr($AA);
sendstr:='';
for i:=1 to 6 do
sendstr:=sendstr + senddata;
if mscomm1.PortOpen then
mscomm1.PortOpen:=false;
mscomm1.CommPort := 1
//指定端口
mscomm1.Settings := '9600,N,8,2'
//其它参数
mscomm1.InBufferSize := 1024
//接收缓冲区
mscomm1.OutBufferSize := 1024
//发送缓冲区
mscomm1.InputMode := comInputModeBinary
//接收模式
mscomm1.InputLen := 0
//一次读取所有数据
mscomm1.SThreshold := 0
//一次发送所有数据
mscomm1.InBufferCount := 0
//清空读取缓冲区
mscomm1.OutBufferCount := 0
//清空发送缓冲区
mscomm1.PortOpen:=true
//打开端口
MSComm1.RThreshold :=50
//设置接收多少字节开产生oncomm事件
mscomm1.Output:=sendstr
//发送数据
sleep(50);
i:=0;
sleep(50);
Application.ProcessMessages;
if (mscomm1.InBufferCount)=0 then //检测是否有反馈
begin
showmessage('设备未联机!');
exit;
end else
begin // 接收数据
redata:=mscomm1.Input;
restr:='';
for i:=0 to vararrayhighbound(redata,1) do
restr:=restr + inttohex(redata,2);
mscomm1.PortOpen:=false;
str:='55'+AddNo+'2B'+'00'+'00AA'
//校验码
if strtomystr(restr)=strtoCmdstr(str) then
edit2.Text:='延时修改成功' else
edit2.Text:='延时修改失败';
end;


end; 
请高人指点
 
你的问题在于
MSComm1.RThreshold :=50
//设置接收多少字节开产生oncomm事件
但你并没用oncomm 来处理数据, 所以应设 MSComm1.RThreshold :=0

你试一下准行。
 
不对,我设置过,不是MSComm1.RThreshold的设置问题。
 
问题原因查出来了,但是无法解释,原因是:我采用串口2,3短接,这样发送什么数据,
就应该接收什么数据,结果大吃一惊,当我按以下内容发送时:
mscomm1.Output:=Chr($55)+Chr($03)+chr($F1)+chr($00)+chr($f4)+Chr($AA)

串口应该反馈的内容是:55 03 f1 00 F4 AA,没有想到竟然是:55 03 00 00 00 00。后来又做了一些试验,总结出来问题是:当功能码中有A~F数据的,一律没有正常发送,难道16进制的发送数据,采用“chr($F1)+chr($f4)+Chr($AA);”这种表达方式是错误的???请高人解答!!!
 
问题已经检查出并且解决,MSCOMM控件有错误,当数字>80的16进制,即A以上的,必须采用字节方式发送,表示方式如下:
   var senddate:array of byte;
sendstr:string;
i,j,len:integer;
begin
sendstr:='AABBCC112233';
Len := Length(sendstr);
Len := Len div 2;
SetLength(senddate,len);
for i:=0 to len-1 do
begin
j:=2*i+1;
senddate := strtoint('$'+copy(sendstr,j,2));
end;
mscomm1.output:=senddate;
end;
 
后退
顶部