串口通迅,运行一段时间出现Stack Overflow错误,为何?

xiangdie 2003-10-09 02:47:35

循环对串口进行读写,次数不限,我用的是spcomm控件,用消息机制通知是否抄到数据,软件运行大约半个小时后出现stack overflow错误,有时点击确定可以继续抄,有时却接着出现非法操作警告,程序退出,重新运行又可,不过一段时间后还是同样错误
不知为何,请大家帮帮忙!
...全文
167 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiangdie 2003-10-13
  • 打赏
  • 举报
回复
up
aiunong 2003-10-10
  • 打赏
  • 举报
回复
study
xiangdie 2003-10-10
  • 打赏
  • 举报
回复
消息定义如下
const WM_STARTREAD=WM_USER+100;
const WM_STOPREAD=WM_USER+101;

procedure WMStartReadProc(var Mas:TMessage);Message WM_STARTREAD;
procedure WMStopReadProc(var Mas:TMessage);Message WM_STOPREAD;

下面是几个重要的过程

procedure TMeterForm.TBReadDataClick(Sender: TObject);
begin //点击读取按钮
MeterIndex:=0;
Cycle1Index:=1;
Cycle2Index :=1;
ProIndex :=0;
shqDl645.IsCallChar := FSendFE;
shqDl645.IsWaitChar := FWait00;
TBStop.Enabled := true;
TBReadData.Enabled := false;
Comm.StopComm;
Comm.StartComm;
PostMessage(Handle,WM_STARTREAD,0,0);
end;


procedure TMeterForm.WMStartReadProc(var Mas:TMessage);
var
SendStr : string;
begin
Screen.Cursor := crHourGlass;
if(ProIndex>=ProtocolNum) then
begin
Cycle1Index := Cycle1Index +1;
ProIndex :=0;
if(Cycle1Index>Cycle1) then
begin
Cycle1Index :=1;
MeterIndex := MeterIndex+1;
if(MeterIndex>=MeterCount) then
begin
MeterIndex :=0;
Cycle2Index := Cycle2Index+1;
if(Cycle2Index>Cycle2) then
begin
PostMessage(Handle,WM_STOPREAD,0,0);
exit;
end;
end;
end;
end;
shqDl645.ComAddr := IntToStr(MeterAddr+MeterIndex);
if(protocols[ProIndex].checked='t') then
begin
shqDl645.MarkCode := protocols[ProIndex].IDCode;
shqDl645.DataLen := protocols[ProIndex].DataLength;
shqDl645.DecimalDigit := protocols[ProIndex].Demical;
SendStr := shqDl645.OutPutStr;
SendFrame(SendStr);
end
else begin
ProIndex := ProIndex+1;
PostMessage(Handle,WM_STARTREAD,0,0);
end;
end;

procedure TMeterForm.SendFrame(SendStr :string);
var //发送帧
i,DataLen:integer;
commflg:boolean;
sbuf:array[1..50] of byte;
str:string;
begin
Memo_Info.Lines.Add('发:'+shqDl645.StrToHex2(SendStr));
DataLen:=Length(SendStr);
for i:=1 to DataLen do
sbuf[i]:=byte(SendStr[i]);

commflg:=true;
RecieveStr:='';
str:='';
for i:=1 to DataLen do
begin
//commflg:=true;
commflg:= Comm.writecommdata(@sbuf[i],1);
if not commflg then
begin
str := shqDl645.ComAddr+ ' 发送失败----------'+DateTimeToStr(Now()) ;
Memo_Info.Lines.add(str);
ProIndex := ProIndex+1;
PostMessage(Handle,WM_STARTREAD,0,0);
exit;
end;
sleep(FWordDelay);
end;
delay(FWaitTime);
if(RecieveStr='') then
begin
str := shqDl645.ComAddr+ ' 无应答-----------'+DateTimeToStr(Now()) ;
Memo_Info.Lines.add(str);
ProIndex := ProIndex+1;
PostMessage(Handle,WM_STARTREAD,0,0);
end;
end;

procedure TMeterForm.CommReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
i:integer;
rbuf:array[1..255] of byte;
RecStr,TmpStr : string;
MessStr : string;
begin
move(buffer^,rbuf,bufferlength);
RecieveStr:='';
for i:=1 to bufferlength do
begin
TmpStr := inttohex(rbuf[i],2);
RecieveStr:=RecieveStr+ TmpStr;
RecStr := RecStr + TmpStr+ ' ';
end;
Memo_Info.Lines.Add('收:'+RecStr+'-------'+DateTimeToStr(Now()));
MessStr := shqdl645.AnalyseData(RecieveStr);
if((MessStr='操作成功' ) and (Cycle2Index=1) and (Cycle1Index=1)) then
begin
with dxTL_Data.Add do
begin
Strings[0] := shqdl645.ComAddr;
Strings[1] := protocols[ProIndex].Name ;
Strings[2] := shqdl645.Data;
Strings[3] := protocols[ProIndex].DataUnit;
Strings[4] := DateTimeToStr(Now());
end;
dxTL_Data.Refresh;
end
else
Memo_Info.Lines.Add(MessStr);
delay(FOrderDelay);
ProIndex := ProIndex+1;
PostMessage(Handle,WM_STARTREAD,0,0);

end;

procedure TMeterForm.WMStopReadProc(var Mas:TMessage);
begin
TBStop.Enabled := false;
TBReadData.Enabled := true;
Screen.Cursor := crDefault;
MeterIndex:=MeterCount-1;
Cycle1Index:=Cycle1;
Cycle2Index :=Cycle2;
ProIndex :=ProtocolNum;
Comm.StopComm;
end;
haoguozhong 2003-10-10
  • 打赏
  • 举报
回复
贴出代码来看看
liangzisiyun 2003-10-09
  • 打赏
  • 举报
回复
反正是堆栈溢出了。看看是不是没有定期清除内存或者什么的。最好贴出代码来看看。
delphizd 2003-10-09
  • 打赏
  • 举报
回复
用排除法试试
xiangdie 2003-10-09
  • 打赏
  • 举报
回复
up
xiangdie 2003-10-09
  • 打赏
  • 举报
回复

代码太多了,想想会是在哪部分可能出现这个问题?接收数据后不用手动清串口数据吧
传递消息是用的postmessage,还用了一个memo显示通信命令帧,但每隔一段时间就清了memo中的数据,实在想不出来哪出问题了
stack overflow是堆栈溢出吧。
jpyc 2003-10-09
  • 打赏
  • 举报
回复
参考:

delphi中常用串口控件简介:
mscomm:微软的东西,是VB中带的一个ActiveX控件,使用简单,性能一般,由于是ActivX控件,打包时需要注册好多信息,在Delphi中使用,建议使用VCL控件,编译程序时直接编入程序中,再不需任何其它处理。
spcomm:比较好的vcl控件,算是比较专业的,解剖了一下,功能比较完善。
TurboPower:公认的专业通讯vcl控件。可以到其站点下载,开放源码了。
我在制作串口通讯软件时三种都用过,最终全部使用TurboPower!所以也推荐大家使用它。
写了个例子,基本的串口通讯都可以实现,可提供参考:
下载基地-》文件名称:串口通讯控制器


版权声明:以下本文只允许在本站观看,不得以任何媒体方式进行传播。
发表意见请到留言版。

TurboPower串口通讯实际应用:
在串口通讯时有字符和十六进制两种数据传输方式,不论使用哪种方式,只要能正确收到数据就是目的,至于收到数据后如何处理,就要根据具体的情况来定了。

1.接收数据的方法:
轮询和中断(利用windows消息激发事件)。
1)轮询:每间隔一定的时间查询一下串口接收缓存中有无数据,有就读出来。这种方法是很毫资源的,即没事找事。
2)中断:在控件中有OnTrigger事件,当串口收到数据后,即触发此事件,无数据时什么都不做,在这个事件中接收数据就比较科学了。
所以,提倡使用控件中的OnTrigger事件接收数据。

2.通讯协议的制定:
接收数据的一般处理方法,最基本的思路就是通过协议进行分析,所以协议的制定是至关重要的:
1)首先要确定指令的起始点,从大量的数据流中将指令分离出来,没有起始标志的话,结果就可想而知了,一串无效的费数据!
2)然后就是指令结束识别点,可以利用指令的长度(如果长度一定或有表示长度的数据)或结束标志来确定,当然还可以利用下一条指令的指令头。
3)既然头尾都明确了,指令的截取想来不是什么问题了吧!但还有一种情况就是数据错误是的容错,如何容错呢,最简单的办法:发现不符合格式的指令,就将其抛掉或特殊处理(如要求重发)一下!
4)有效数据中如果增加一些校验,通讯将会更加可靠!
例:#(指令头)**(指令功能)0123456789(有效数据)**(有效数据校验和)%(指令尾)
注:**代表变动值。

3.接收数据的分析技巧:
通讯协议制定好后,一切将以通讯协议为中心。一套协议中的所有指令可能长度都是统一的,也有可能是长短不同的,并且在OnTrigger事件中实际反应速度及快,可能一条指令数据还没有完全收齐就已经触发了此事件,即收到了半截指令,并且有可能继续收取的数据中除了下半截指令外,还有下一条指令的前半截,如何处理?
我在做这种处理时是利用全局变量,将串口收到的所有数据都收到该串中,然后按指令格式进行截取,发现不合法指令做一下特殊处理(如要求重发)或抛弃。
如收到的数据串为:
#**0000012000**%#**0000000343#**000000540560**%#**0002200000**%
分段截为:
#**0000012000**%
#**0000000343
#**000000540560**%
#**0002200000**%
四条指令,其中:#**0000000343不完整,检测到后进行抛弃处理。

调试技巧篇:
对于已了解协议的支持串口产品,要想进行编程控制,可以使用“串口通讯控制器”进行调试,以摸清具体实现数据,可按如下步骤进行:
1.确定硬件连接无误,这是首要条件,如果错误将没有成功的可能;
连线必须正确,必要时可以使用计算机自带的多个端口相互进行测试,已保证硬件的连接无误。串口通讯线有9针和25针,多用9针,其中最重要的是2(RXD)、3(TXD)、5(GND)线,对应关系如下:
9针 25针
2 -- 3
3 -- 2
5 -- 7

2.确定通讯参数正确,如:波特率、奇偶校验位、数据位、停止位等,以及收发的是十六进制还是字符串:

3.以上确保正确,则使用“串口通讯控制器”,按协议输入数据进行收发控制了。
注意:有的仪器需要进行初始化,即先发一段激活指令,然后才能进入工作状态,这种设置主要是为了实现利用硬件为软件加密,即类似加密狗,需要有激活方法才行,不过该类方法使用较少。

原创作者:JPYC,望业界专家多多指正!控件及例程源码请到:http://218。56。11。178/default.aspx->下载基地
dickeybird888 2003-10-09
  • 打赏
  • 举报
回复
贴出代码看看!

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧