搜索
bottom↓
回复: 9

delphi用spcomm控件做串口通讯,为什么接收数据的的准确率只有50%

[复制链接]

出0入0汤圆

发表于 2011-12-8 16:22:50 | 显示全部楼层 |阅读模式
我先是上位机发送一个6位数组,然后接收单片机返回一个数据。但上位机接收到的数据只有50%是正确的,就是说要发几次才能正确收到单片机发送的数据。我用Terminal测试通讯 是没有问题的,都收到正确的。不知道是不是SPCOMM控件要设置什么,我总觉得这控件的启动通信时间要比较长会不会这个的影响呢

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2011-12-8 16:37:37 | 显示全部楼层
spcomm 是接收超时中断的,所以 一包很长的数据 很有可能会发生两次接收中断(分别接收前后两部分的数据)而不是像MSCOMM那样一个字节一个字节接收,需要你自己做好数据帧格式,以及接收的缓冲处理,不是SPCOMM的错,SPCOMM是一个很优秀的控件,好好使用

出0入0汤圆

 楼主| 发表于 2011-12-8 17:05:07 | 显示全部楼层
回复【1楼】ele_eye
-----------------------------------------------------------------------

接收到的数据位数没有少,比如我单片机发送  0xF0 0x44 0x57 0x02 0x01 0x43 0xE1 0x0F
              但是上位机接收到的可能会是  0xF0 0x44 0xFD 0x02 0x01 0x43 0xE1 0x0F
总是会有几个位不正确,可能连_发三次才能收到一个是完成正确的数据。请问这样是什么原因

出0入0汤圆

发表于 2011-12-8 17:10:27 | 显示全部楼层
用SPCOMM尽量不要将下位机做成收到上位机的数据请求命令才向上位机发数据,而且一次发送的数据量也不要过大,还有,把SPCOMM里的缓冲区开小点,最好跟向上位机发的一个数据包一样的大小,这样不用等超时就有接收数据中断。

出0入0汤圆

发表于 2011-12-8 20:38:22 | 显示全部楼层
LS在误认子弟

SPCOMM有这么RZ么?

出0入0汤圆

发表于 2011-12-9 08:25:29 | 显示全部楼层
我用SPCOMM做过没有出现这个问题呀,楼主有代码可帮分析一下原因

出0入0汤圆

发表于 2011-12-9 08:42:01 | 显示全部楼层
是不是设置了XON,,,属性里面。

出0入0汤圆

 楼主| 发表于 2011-12-9 09:06:42 | 显示全部楼层
回复【5楼】xjjiang
-----------------------------------------------------------------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, SPComm, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Comm1: TComm;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
      BufferLength: Word);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation
var
  rbuf,sbuf:array[0..16] of byte;
  viewstring:string;
{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  comm1.commname:='COM3';
  Comm1.StartComm
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Comm1.StopComm;
end;

procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
  BufferLength: Word);
var
  i:integer;
begin
  move(buffer^,pchar(@rbuf)^,bufferlength);
  viewstring:='';
for i:=0 to bufferlength-1 do
viewstring:=viewstring+inttohex(rbuf,2)+' ';
viewstring:='接收'+viewstring;
memo1.lines.add(viewstring);
end;

procedure SendData;            //发送数据
var
i:integer;
commflg:boolean;
begin
viewstring:='' ;
commflg:=true;
for i:=0 to 16 do
begin
if not form1.comm1.writecommdata(@sbuf,1) then
begin
commflg:=false;
break;
end;
//发送时字节间的延时
sleep(2);
viewstring:=viewstring+inttohex(sbuf,2)+' ';
end;
viewstring:='发送'+viewstring+' ';
form1.memo1.lines.add(viewstring);
if not commflg then
messagedlg('发送失败',mterror,[mbyes],0)
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  i:integer;
  sum:byte;
begin
sum:= 0;
  sbuf[0] := byte($F0);
  sbuf[1] := byte($52);
  sbuf[2] := byte($51);
  sbuf[3] := byte($01);
  sbuf[4] := byte($00);
  for i:=1 to 4 do
    sum:=sum+sbuf;
  inttohex(sum,2);
  sbuf[5] := sum;
  sbuf[6] := byte($0F);
  SendData;
end;

end.

出0入0汤圆

 楼主| 发表于 2011-12-9 09:42:51 | 显示全部楼层
我可能找到原因了,因为我单片机是接收到了就立刻返回数据,我现在加多个延时200MS接收之后延时再发送,目前是一切正常。先谢谢各位的指导

出0入0汤圆

发表于 2014-4-28 15:35:13 | 显示全部楼层
jiongeyes 发表于 2011-12-9 09:06
回复【5楼】xjjiang
-----------------------------------------------------------------------

终于找到一个对的接收程序
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 16:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表