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;
请高人指点
通讯的指令在“串口调试助手”程序中全部通过,通讯都正常,发送、接收一切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;
请高人指点