关于mscomm,单步调试没有问题,可是运行就会出错,贴出代码,请高人帮忙(在线等) ( 积分: 100 )

  • 主题发起人 主题发起人 乖乖小妹
  • 开始时间 开始时间

乖乖小妹

Unregistered / Unconfirmed
GUEST, unregistred user!
procedure TForm1.MSComm1Comm(Sender: TObject)
//缓冲区里有4个字节触发comm事件
var
reData:array of Variant
//接收串口的变量
restr:array of string
//将接收到的串口变量变为string型
num,i,k:integer;
number:integer;
codesize:integer;
begin
codesize:=mscomm1.InBufferCount
//为了防止有variant or safe array index out
of bounds 的错误
if codesize=4 then
begin
redata:=mscomm1.Input;
mscomm1.RThreshold:=0
关掉comm事件
mscomm1.InBufferCount:=0
清空缓冲区的数据
number:=0

i:=0;
repeat
inboxstr[number]:=inttohex(redata,2);
number:=number+1;
i:=i+1;
until
number=4;
button6.Click;
end;
mscomm1.RThreshold:=4
设置comm事件
end
//八个字符
end;

[red]以下为button6的触发程序,是为了实现将com口接收到的数据进行处理,画出坐标图,在单步调试过程中也没有发生什么错误。(可以不用细看)[/red]
procedure TForm1.Button6Click(Sender: TObject);
var
a:integer
//旧
binwordstr:array of string
//将串口变量转为一个字的存储(二进制代码)
binstr:array of string
//补充二进制码的临时数组
needstr:array of real
//画图用到的数据数组
i,j,k,count:integer
//用到的计数变量
transstr:string
//临时的转换字符串
num2:integer
//字组的长度
datastr:string;
len:integer;
begin
datastr:='0';
for i:=0 to 3 do
begin
datastr:=datastr+inboxstr;
end;
if datastr[1]='1' then
begin
showmessage('数据传输错误,重新传输,请稍候');
button5.Click;
end
else
begin
len:=length(datastr)-1;
len:=len div 2;
setlength(binstr,len);
for i:=1 to len do
begin
transstr:= dectobin(strtoint('$'+copy(datastr,2*i,2)));//将十六进制的数转为二进制代码
if length(transstr)<>8 then
begin
for j:=1 to 8-length(transstr) do
begin
transstr:='0'+transstr;
end;
end;
binstr[i-1]:=transstr;
transstr:='';
end;
num2:=len;
num2:=num2 div 2;
setlength(binwordstr,num2)
//设定处理数组的长度
k:=0;
for j:=0 to num2-1 do //将两个字节合并为一个字(设为先传高八位后传
// 低八位)
begin
binwordstr[j]:=binstr[k]+binstr[k+1];
k:=k+2;
end;
setlength(needstr,num2)
//画图处理数组长度
for j:=0 to num2-1 do //将字转为十进制数
begin
needstr[j]:=bintodec(binwordstr[j]);
end;
edit4.Text:=floattostr(needstr[0]);
edit3.Text:=floattostr(needstr[1]);
count:=0
//设一个计数变量的初值
if num2>1 then //绘制U-I图(则点必须是成对的)
begin
if num2 mod 2 =0 then
begin
repeat
series1.AddXY(needstr[count+1],needstr[count],'',clblue);
memo1.Lines.Add(inttostr(s)+' '+floattostr(needstr[count])+
' '+floattostr(needstr[count+1]));
s:=s+1;
count:=count+2;
until
count=num2;
end
else
begin
repeat
series1.AddXY(needstr[count+1],needstr[count],'',clblue);
memo1.Lines.Add(inttostr(s)+' '+floattostr(needstr[count])
+' '+floattostr(needstr[count+1]));
s:=s+1;
count:=count+2;
until
count=num2-1;
end;
end;

showstr[step]:=needstr[0];
showstr[step+1]:=needstr[1];
step:=step+2;
progressbar1.StepIt;
if step=10 then
begin
series2.AddXY(strtoint(zhouqi),showstr[0],'',clblack);
a:=2;
for j:=1 to 9 do
begin
if j mod 2=0 then //判断j是否为偶数,奇数为电流,偶数为电压
begin
series2.AddXY(a*strtoint(zhouqi),showstr[j],'',clblack);
end
else
begin
series3.AddXY(a*strtoint(zhouqi),showstr[j],'',clblack)
//series3为电压
end;
a:=a+1;
end
//for 循环end;
step:=0;
end
//一屏数据end;
end;
end;

comm事件中的inbox是全局变量,在按钮程序里面step,showstr都是全局变量

series1在chart1里面,其他两个在chart2里面,chart1在tabsheet1,chart2在tabsheet2里面。

单步调试时,没有错误。
但是运行时,就会出现“Project Project 2.exe raised exception class EAccess Violation with message &quot;Access violation at address 0041ECA in module 'Project 2.exe' write of address 000020F&quot;的错误提示,
而且在单步调试时,如果只发送一次数据(即触发一次comm事件)切换页面(page control 的分页),即要查看不同的图时就会出这样的错误提示,是因为mscomm与page control控件的冲突,还是编程里面有错误。望高人指教

在线等候教诲
 
procedure TForm1.MSComm1Comm(Sender: TObject)
//缓冲区里有4个字节触发comm事件
var
reData:array of Variant
//接收串口的变量
restr:array of string
//将接收到的串口变量变为string型
num,i,k:integer;
number:integer;
codesize:integer;
begin
codesize:=mscomm1.InBufferCount
//为了防止有variant or safe array index out
of bounds 的错误
if codesize=4 then
begin
redata:=mscomm1.Input;
mscomm1.RThreshold:=0
关掉comm事件
mscomm1.InBufferCount:=0
清空缓冲区的数据
number:=0

i:=0;
repeat
inboxstr[number]:=inttohex(redata,2);
number:=number+1;
i:=i+1;
until
number=4;
button6.Click;
end;
mscomm1.RThreshold:=4
设置comm事件
end
//八个字符
end;

[red]以下为button6的触发程序,是为了实现将com口接收到的数据进行处理,画出坐标图,在单步调试过程中也没有发生什么错误。(可以不用细看)[/red]
procedure TForm1.Button6Click(Sender: TObject);
var
a:integer
//旧
binwordstr:array of string
//将串口变量转为一个字的存储(二进制代码)
binstr:array of string
//补充二进制码的临时数组
needstr:array of real
//画图用到的数据数组
i,j,k,count:integer
//用到的计数变量
transstr:string
//临时的转换字符串
num2:integer
//字组的长度
datastr:string;
len:integer;
begin
datastr:='0';
for i:=0 to 3 do
begin
datastr:=datastr+inboxstr;
end;
if datastr[1]='1' then
begin
showmessage('数据传输错误,重新传输,请稍候');
button5.Click;
end
else
begin
len:=length(datastr)-1;
len:=len div 2;
setlength(binstr,len);
for i:=1 to len do
begin
transstr:= dectobin(strtoint('$'+copy(datastr,2*i,2)));//将十六进制的数转为二进制代码
if length(transstr)<>8 then
begin
for j:=1 to 8-length(transstr) do
begin
transstr:='0'+transstr;
end;
end;
binstr[i-1]:=transstr;
transstr:='';
end;
num2:=len;
num2:=num2 div 2;
setlength(binwordstr,num2)
//设定处理数组的长度
k:=0;
for j:=0 to num2-1 do //将两个字节合并为一个字(设为先传高八位后传
// 低八位)
begin
binwordstr[j]:=binstr[k]+binstr[k+1];
k:=k+2;
end;
setlength(needstr,num2)
//画图处理数组长度
for j:=0 to num2-1 do //将字转为十进制数
begin
needstr[j]:=bintodec(binwordstr[j]);
end;
edit4.Text:=floattostr(needstr[0]);
edit3.Text:=floattostr(needstr[1]);
count:=0
//设一个计数变量的初值
if num2>1 then //绘制U-I图(则点必须是成对的)
begin
if num2 mod 2 =0 then
begin
repeat
series1.AddXY(needstr[count+1],needstr[count],'',clblue);
memo1.Lines.Add(inttostr(s)+' '+floattostr(needstr[count])+
' '+floattostr(needstr[count+1]));
s:=s+1;
count:=count+2;
until
count=num2;
end
else
begin
repeat
series1.AddXY(needstr[count+1],needstr[count],'',clblue);
memo1.Lines.Add(inttostr(s)+' '+floattostr(needstr[count])
+' '+floattostr(needstr[count+1]));
s:=s+1;
count:=count+2;
until
count=num2-1;
end;
end;

showstr[step]:=needstr[0];
showstr[step+1]:=needstr[1];
step:=step+2;
progressbar1.StepIt;
if step=10 then
begin
series2.AddXY(strtoint(zhouqi),showstr[0],'',clblack);
a:=2;
for j:=1 to 9 do
begin
if j mod 2=0 then //判断j是否为偶数,奇数为电流,偶数为电压
begin
series2.AddXY(a*strtoint(zhouqi),showstr[j],'',clblack);
end
else
begin
series3.AddXY(a*strtoint(zhouqi),showstr[j],'',clblack)
//series3为电压
end;
a:=a+1;
end
//for 循环end;
step:=0;
end
//一屏数据end;
end;
end;

comm事件中的inbox是全局变量,在按钮程序里面step,showstr都是全局变量

series1在chart1里面,其他两个在chart2里面,chart1在tabsheet1,chart2在tabsheet2里面。

单步调试时,没有错误。
但是运行时,就会出现“Project Project 2.exe raised exception class EAccess Violation with message &quot;Access violation at address 0041ECA in module 'Project 2.exe' write of address 000020F&quot;的错误提示,
而且在单步调试时,如果只发送一次数据(即触发一次comm事件)切换页面(page control 的分页),即要查看不同的图时就会出这样的错误提示,是因为mscomm与page control控件的冲突,还是编程里面有错误。望高人指教

在线等候教诲
 
up
沉的也太快了吧!
急啊!
 
咋就没人回呢?是问题太弱智,还是别的阿
 
东西太多,看晕了
建议你先简化程序,把复杂的处理注释掉,从最基本的接收开始调试
 
我是从最基础的处理作过的,都没有问题,只有在画图之后就会出现那样的错误了,但是单做画图的界面就不会有错误,所以我想知道是不是pagecontrol与什么东西冲突,还是在我写画图程序的地方引用错误。

还有,我想知道,使用comm事件时,是不是触发事件之后一定要关闭触发条件,然后再进行完处理之后再打开触发条件
 
不用关,但这里要改一下
codesize:=mscomm1.InBufferCount
//为了防止有variant or safe array index out
of bounds 的错误
if codesize=4 then
改为
if (Mscomm1.CommEvent=2) then
while Mscomm1.inbuffercount>=4 do //否则当数据大于4个时会出问题

下面两行不要
mscomm1.RThreshold:=0
关掉comm事件
mscomm1.InBufferCount:=0
清空缓冲区的数据

画图的东西我不清楚,也许是画图引入数据时出的错误
 
画图的部分好像是出现了应用数据错误的问题,我实在是看不出来,请高人指教
 
reData:array of Variant
//接收串口的变量
声明也有问题吧,应该是reData:Variant
如果接收的是2进制数,直接使用就可以了
 
后退
顶部