(串口编程)为何命令发不出去,接收数据无响应(spcomm控件)!!! ( 积分: 0 )

J

jin005

Unregistered / Unconfirmed
GUEST, unregistred user!
请问,为什么我的程序(计算机与测速雷达的接口程序)在实际的测试中,好象测速指令(FE,3F)根本没有发送出去,因为我在CommReceiveData()中加showmessage()根本不弹出,好象根本没有接收到任何消息。而我用串口精灵发送FE,3F就有返回值。
我写的代码如下:(是不是我发送的不是十六进制造成的结果)
procedure TfrmData.Button1Click(Sender: TObject);
var
s:string;
Count:Integer;
p:pchar;
begin
//设置串口参数 ,并打开串口
comm.CommName:=Cmb_com.text;
comm.BaudRate:=9600;
comm.ByteSize:=_8;
comm.StopBits:=_1;
comm.Parity:=none;
//打开串口
try
Comm.StartComm;
except
raise Exception.Create('打开串口错误');
end;
//准备接收火花开机识别码,并发送测速命令,和接收火花传回速度值
sleep(1000);

s := Char($FE) + Char($3F);//发送测速指令
Count:=Length(s);
p:=pchar(s);
comm.WriteCommData(p,Count);//这步好象没有发送成功,要不然应该有返回值,可是下面CommReceiveData()没有任何响应
Button1.Enabled:=false;
end;
//从端口接收数据
procedure TfrmData.CommReceiveData(Sender:Tobject;Buffer:pointer;
BufferLength:Word);
var
strRecv,tmpstr:string;
//b:array [1..4096] of byte;
b:array [0..50000] of char;
flag1,flag2,flag3,flag4:Boolean;
strlen,i,pos,speed1,speed2,speed3,speed4:Integer;
// 超速目标/最大目标/相对方向最大/自身速度
begin
showmessage('如果接受到数据,这里应该弹出');//后加的,为了测试是否缓存接收到数据,而实际测试中没有弹出
strRecv:='';
speed1:=0;
speed2:=0;
speed3:=0;
speed4:=0;
flag1:=false;
flag2:=false;
flag3:=false;
flag4:=false;
Move(Buffer^,b,BufferLength);
for i:=0 to bufferlength do
strRecv:=strRecv+b;
strlen:=Length(strRecv);
for i := 1 to strlen do
begin
if Byte(strRecv)=$F1 then //$F1后面为超速目标的速度
begin
flag1:=true;
pos := i;
tmpstr := Copy(strRecv, pos+1, 1);
speed1:=strtoint(tmpstr);//取出速度
if speed1>240 then //判断是否超出00-F0范围
speed1:=0;
break;
Delete(strRecv, pos, 2);//从缓存中删除该数据
break;
end;
if Byte(strRecv)=$F2 then //$F2后面为最大速度目标速度
begin
flag2:=true;
pos := i;
tmpstr := Copy(strRecv, pos+1, 1);
speed2:=strtoint(tmpstr);//取出速度
if speed2>240 then //判断是否超出00-F0范围
speed2:=0;
break;
Delete(strRecv, pos, 2);//从缓存中删除该数据
break;
end;
if Byte(strRecv)=$F4 then //$F4后面为相对方向最大速度
begin
flag3:=true;
pos := i;
tmpstr := Copy(strRecv, pos+1, 1);
speed3:=strtoint(tmpstr);//取出速度
if speed3>240 then //判断是否超出00-F0范围
speed3:=0;
break;
Delete(strRecv, pos, 2);//从缓存中删除该数据
break;
end;
if Byte(strRecv)=$F8 then //$F8后面为自身速度
begin
flag4:=true;
pos := i;
tmpstr := Copy(strRecv, pos+1, 1);
speed4:=strtoint(tmpstr);//取出速度
if speed4>240 then //判断是否超出00-F0范围
speed4:=0;
break;
Delete(strRecv, pos, 2);//从缓存中删除该数据
break;
end;
//添加到数据库对应的字段里
if flag1 and flag2 and flag3 and flag4 then
begin
ADOTable1.Append; //增加一条新记录
ADOTable1.FieldValues['Patrol speed'] :=speed4;
ADOTable1.FieldValues['Fastest goal'] :=speed2;
ADOTable1.FieldValues['Strongest echo'] :=speed3;
ADOTable1.FieldValues['Exceeding'] :=speed1;
ADOTable1.Post;
flag1:=false;
flag2:=false;
flag3:=false;
flag4:=false;
end;
sleep(100);

end;
end;
 
请问,为什么我的程序(计算机与测速雷达的接口程序)在实际的测试中,好象测速指令(FE,3F)根本没有发送出去,因为我在CommReceiveData()中加showmessage()根本不弹出,好象根本没有接收到任何消息。而我用串口精灵发送FE,3F就有返回值。
我写的代码如下:(是不是我发送的不是十六进制造成的结果)
procedure TfrmData.Button1Click(Sender: TObject);
var
s:string;
Count:Integer;
p:pchar;
begin
//设置串口参数 ,并打开串口
comm.CommName:=Cmb_com.text;
comm.BaudRate:=9600;
comm.ByteSize:=_8;
comm.StopBits:=_1;
comm.Parity:=none;
//打开串口
try
Comm.StartComm;
except
raise Exception.Create('打开串口错误');
end;
//准备接收火花开机识别码,并发送测速命令,和接收火花传回速度值
sleep(1000);

s := Char($FE) + Char($3F);//发送测速指令
Count:=Length(s);
p:=pchar(s);
comm.WriteCommData(p,Count);//这步好象没有发送成功,要不然应该有返回值,可是下面CommReceiveData()没有任何响应
Button1.Enabled:=false;
end;
//从端口接收数据
procedure TfrmData.CommReceiveData(Sender:Tobject;Buffer:pointer;
BufferLength:Word);
var
strRecv,tmpstr:string;
//b:array [1..4096] of byte;
b:array [0..50000] of char;
flag1,flag2,flag3,flag4:Boolean;
strlen,i,pos,speed1,speed2,speed3,speed4:Integer;
// 超速目标/最大目标/相对方向最大/自身速度
begin
showmessage('如果接受到数据,这里应该弹出');//后加的,为了测试是否缓存接收到数据,而实际测试中没有弹出
strRecv:='';
speed1:=0;
speed2:=0;
speed3:=0;
speed4:=0;
flag1:=false;
flag2:=false;
flag3:=false;
flag4:=false;
Move(Buffer^,b,BufferLength);
for i:=0 to bufferlength do
strRecv:=strRecv+b;
strlen:=Length(strRecv);
for i := 1 to strlen do
begin
if Byte(strRecv)=$F1 then //$F1后面为超速目标的速度
begin
flag1:=true;
pos := i;
tmpstr := Copy(strRecv, pos+1, 1);
speed1:=strtoint(tmpstr);//取出速度
if speed1>240 then //判断是否超出00-F0范围
speed1:=0;
break;
Delete(strRecv, pos, 2);//从缓存中删除该数据
break;
end;
if Byte(strRecv)=$F2 then //$F2后面为最大速度目标速度
begin
flag2:=true;
pos := i;
tmpstr := Copy(strRecv, pos+1, 1);
speed2:=strtoint(tmpstr);//取出速度
if speed2>240 then //判断是否超出00-F0范围
speed2:=0;
break;
Delete(strRecv, pos, 2);//从缓存中删除该数据
break;
end;
if Byte(strRecv)=$F4 then //$F4后面为相对方向最大速度
begin
flag3:=true;
pos := i;
tmpstr := Copy(strRecv, pos+1, 1);
speed3:=strtoint(tmpstr);//取出速度
if speed3>240 then //判断是否超出00-F0范围
speed3:=0;
break;
Delete(strRecv, pos, 2);//从缓存中删除该数据
break;
end;
if Byte(strRecv)=$F8 then //$F8后面为自身速度
begin
flag4:=true;
pos := i;
tmpstr := Copy(strRecv, pos+1, 1);
speed4:=strtoint(tmpstr);//取出速度
if speed4>240 then //判断是否超出00-F0范围
speed4:=0;
break;
Delete(strRecv, pos, 2);//从缓存中删除该数据
break;
end;
//添加到数据库对应的字段里
if flag1 and flag2 and flag3 and flag4 then
begin
ADOTable1.Append; //增加一条新记录
ADOTable1.FieldValues['Patrol speed'] :=speed4;
ADOTable1.FieldValues['Fastest goal'] :=speed2;
ADOTable1.FieldValues['Strongest echo'] :=speed3;
ADOTable1.FieldValues['Exceeding'] :=speed1;
ADOTable1.Post;
flag1:=false;
flag2:=false;
flag3:=false;
flag4:=false;
end;
sleep(100);

end;
end;
 
你可以下载一个串口监视的工具来监视你发送和接收到的数据.
 
你的发送数据写错了,这样写不是发送了十六进制的FE 3F
s := Char($FE) + Char($3F);//发送测速指令(这里写错了应该写成:s := Chr($FE) + Chr($3F));
Count:=Length(s);
p:=pchar(s);
 
谢谢楼上的,这个我没注意,我再测测,可能是这个错误。再次感谢。
也谢谢fuxiaojie 我会下载这个试试的。
 
有个IgnoreNullChar的设置,具体记不得了,你看看SPCOMM的设置,看看设置了以后行不行
另外把超时时间设置长点
 
s := Char($FE) + Char($3F);
s := Chr($FE) + Chr($3F));

这两种写法其实没什么差别,都是一样的!
 
结果如何?
 
结果还是未接收到数据,不知道为何。两种写法好象没有什么差别。CommReceiveData()一直没有被触发,不知道什么原因,串口监视软件显示有接收数据,发送命令好象成功了,但CommReceiveData()里不管写什么代码好象都不运行。写showmessage()也不弹出,不知道为什么??急!
 
检查波特率是否一致
 
单步跟踪不到吗?
 
把FE和3F互换位置试试,连续发3遍试试
 
var
b:array[1..2] of byte;
begin
b[1]:=$FE;
b[2]:=$3F;//发送测速指令
comm.WriteCommData(@b,2);//
 
我也碰到过这个问题.
 
但是我的问题解决了.可以当为一个串口调试器用,可以接收字符串和二进制代码,你看一下下面的代码.应该可以的,如果可以就给点分,我没分了.
procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
tmpArray:array[0..4096] of Byte;
i: DWORD;
tmpStr:string;
pStr:pChar;
StrBuf:string;
begin
StrBuf:='';
tmpStr:='';
pStr:=Buffer; //转存接收到的所有数据
tmpStr:=string(pStr); //强制将数据全部转换成字符型
Dec(PStr); //指针后退一个字节 为了配合Inc()
for i:=0 to Length(tmpStr)-1 do
begin
inc(PStr); //自动+1

if RadioButton2.Checked then //以十六进制数值形式接收
begin
//所有数值存放在数组tmpArray中等待解析处理
tmpArray:=Byte(PSTR^);
//保存格式化的十六进制字符
StrBuf:=StrBuf+'0x'+IntToHEX(Ord(tmpArray),2)+' ';
end;
end;
if RadioButton2.Checked then //以十六进制数值形式接收
begin
memo2.Lines.Add(StrBuf);
ComboBox8.Text:=StrBuf; //显示到接收栏
end;
if RadioButton1.Checked then //以字符形式接收
begin
memo2.Lines.Add(tmpStr);
ComboBox8.Text:=tmpStr;
end;
end;
 
谢谢大家,问题已经解决了,是spcomm的事件没有选上,所以接收没有响应。
 
后退
顶部