spcom串口收数据的简单问题!(100分)

  • 主题发起人 主题发起人 happytimes_dsq
  • 开始时间 开始时间
H

happytimes_dsq

Unregistered / Unconfirmed
GUEST, unregistred user!
通过spcom串口收数据!
1.假设对方无限发送数据.
2.我想通过edit的输入来动态的接受它传过来的字节!当我收完设置的数值后,对对方继续发送的字节不与理会.
3.将收到的数据放入数组作成.bin文件.
我的问题是:
怎么样当我收完我需要的字节后,不理会它继续传的呢?我尝试 关闭串口和设置标志位.但是不行.对方一直发的话,程序就出乱子,连savedialog的对话框都不弹了.如果对方发的字节少的话还好点,要是对方发送多于1K就出乱子!
或者是我程序本身的接收数据就不对呢???请有经验的大哥帮帮忙!~
错误的代码如下!

procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
i,k:integer;
viewstring,filename:string;
begin
//if dsq=1 then//我尝试做的标志位,在初始化的时候置1了
// begin
viewstring:='';k:=strtoint(edit1.Text);
setlength(adata,k);
move(buffer^,pchar(@data)^,k);

for i:=0 to k-1 do
begin
viewstring:=viewstring+inttohex(data,2)+' ';
adata:=data;
end;
memo1.lines.add(viewstring);
memo1.lines.add('');
dsq:=0;
//Comm1.StopComm;
// bitbtn1.Caption:='CommStop';
if savedialog1.Execute then
begin
filename:=savedialog1.FileName;
array_to_bin(filename,adata,k);
end;
//end;
end;
 
控件读取串口信息的方式是在线程里实现的,在你不需要接受数据的地方,把comm1的线程挂起([red]Suspend[/red]),再需要的的时候再激活([green]Resume[/green])就可以了.
切记:不能用Stopcomm.
 
谢谢楼上大哥指教,具体应该怎么实现呢?可是现在我的主要问题是,当我设置接收2000字节时,没有问题.但是我要是想接收更多(比如3000或者更大的数据量).就出乱.数据内容和个数都发生了改变.但是我觉得从程序控制来说是一样的呀?为什么有这样的现象呢?
 
你用的是spcomm控件
线程已经封装
你只是数据缓冲处理不好
设个数据缓冲就ok
 
设置缓冲就能解决问题吗?应该怎么做呢?楼上的大哥,能帮忙改改吗??谢谢了.小弟愚钝
 
串口通信网上一大堆(源码都有)
var
arrRec: array[1..1024] of byte;
begin
move(buffer^, arrRec, BufferLength); 
doyoursth                // 处理你的事情
end;
 
我也准备作。收藏
 
to uuit大哥!
你 move(buffer^, arrRec, BufferLength); //这样是把收到所有的字节往arrRec里存呢?那如果对方发送字节是超过1024不定的话,应该用动态数组的吧!你的意思是先把它传的所有的存下,然后我在进行取舍啊?
 
不需要!
你只要判断是否你需要的就行了
建议:1、找本串口通信的书 2、了解一下缓冲机制
先了解基本概念
 
大哥,能帮小弟写写吗?小弟第一次用spcom,手头没有相关资料!事情比较急.大哥帮帮忙.分可以多给你.谢谢了!
 
http://www.delphibox.com
http://www.tomore.com
到处都是源码,你自己弄吧
 
大哥!小弟还是搞不定啊,拜托能帮帮忙吗?
 
大哥,我发现spcom控件的intputbuffersize=2048,所以当我收超过2000的时候就出错,而在2000以内的就是正确的.是这样吗?
 
你可以缩短接受数据等待间隔来避免缓冲溢出,当你收到你所需的数据后,你就可以不用管串口了,当你想再次接受数据的时候,你先清空缓冲即可。
 
"你可以缩短接受数据等待间隔来避免缓冲溢出"--小弟不是很懂!应该怎么避免呢..
可是要是我要收的一次大于2048,我还没收完还没有关闭.那就溢出了啊..
 
ReadIntervalTimeout 值可以调小,需要根据你的波特率大概算一下,要是还不行,那你只能通过“流控”来实现了。
 
ReadIntervalTimeout 值是什么啊?是读入字节间的间隔吗?它单位是ms吧!你是说缩短读入字节传入之间的时间吧??
 
我也正准备做..期待你的解决!~收藏!!帮你顶~
 
可以在For循环中,Application.ProcessMessages;增加这一句话试一试,还有保存对话框最好不要放在这里,而是最好直接写文件,文件名称就事先定义:
接收完成后,立即更改你的标志位:dsq=0
你一定使用的是SPCOMM控件,他本身已经内置了多线程功能,所以接收数据时,你的程序不会没有相应,程序没有相应是因为你的For循环造成的。

还有想不通你所要实现的功能,串口发送过来的数据,你截获了一段,但是这一段到底是什么内容你也没有分辨,只是取了长度,而且每次你的程序开启的时间不同,就可能造成你收到的数据完全不同,这样的数据保存了有什么用呀???难道他给你发送的就是单一字符,比如无穷个"X",如果真的是这样,我看也不要串口接收了,你就自己写一个文件,都是X好了,更快一点也更加简单。
 
多人接受答案了。
 
后退
顶部