请教串口高速传输数据问题(使用spcomm控件)(100分)

  • 主题发起人 主题发起人 Reecking
  • 开始时间 开始时间
R

Reecking

Unregistered / Unconfirmed
GUEST, unregistred user!
偶用spcomm控件编写一个数据接收监控程序。
DSP每次发送35个数据,
波特率是38400,ReadIntervalTimeOut:5,其他默认。

由于接收端无法每次恰好收到35个数据(有多有少,高速情况下一般接收长度大于35),
因此用一个字符串保存总的接收字符,在处理线程内进行分割。

处理方法是,在OnReceiveData事件中将接收到的数据传出来,新建一个线程进行处理
现在的问题是,当数据传过来时,速度太快,串口能收到消息但是程序无法处理。
(需要将数据转换后用Tchart画出动态曲线)

程序关键执行语句记录如下,在最后,串口能收到数据,但是处理线程起不来。

2006-10-23 12:44:27:日志开始记录
2006-10-23 12:44:27:接收到串口数据
2006-10-23 12:44:27:数据处理线程启动
2006-10-23 12:44:27:数据长度:64,第五位ASCII值:00
2006-10-23 12:44:27:CurPos=51 b c
2006-10-23 12:44:27:正常数据处理
2006-10-23 12:44:27:数据长度<35,长度17
2006-10-23 12:44:27:接收到串口数据
2006-10-23 12:44:27:数据处理线程启动
2006-10-23 12:44:27:数据长度:257,第五位ASCII值:54
2006-10-23 12:44:27:CurPos=4 b c
。。。。
2006-10-23 12:44:47:数据处理线程启动
2006-10-23 12:44:47:数据长度:112,第五位ASCII值:00
2006-10-23 12:44:47:CurPos=58 b c
2006-10-23 12:44:47:正常数据处理
2006-10-23 12:44:47:数据长度>35,长度58
2006-10-23 12:44:47:删除处理后数据,当前数据长度:23
2006-10-23 12:44:47:开始记录绘制曲线
2006-10-23 12:44:47:接收到串口数据
2006-10-23 12:44:48:接收到串口数据
2006-10-23 12:44:48:接收到串口数据
2006-10-23 12:44:48:接收到串口数据
2006-10-23 12:44:48:接收到串口数据

////OnReceiveData消息中处理方法
pStr := Buffer;
CurDataReceive := '';
SetLength(CurDataReceive, BufferLength);
for i := 1 to BufferLength do
CurDataReceive := (pStr + i - 1)^;
SetLength(AllDataReceive, Length(AllDataReceive) + BufferLength);
AllDataReceive := AllDataReceive + CurDataReceive;
if acDataProcessThread.Running then
acDataProcessThread.Terminate(True); //终止上一线程
acDataProcessThread.Execute; //开辟新线程
PurgeComm(myComm.Handle, PURGE_RXCLEAR); //清接收缓存

//线程中的处理过程如下

//每组完整数据格式为
// xx xx xx xx a xx xx xx xx b xx xx xx xx c
// xx xx xx xx d xx xx xx xx e xx xx xx xx f
// xx xx xx xx g

CurPos := Pos('a', AllDataReceive);
if ((ord(AllDataReceive[CurPos + 5]) = 98) and
(ord(AllDataReceive[CurPos + 10]) = 99)) then
begin
IsFirstData := False;
Delete(AllDataReceive, 1, CurPos - 4);
end
else
begin
AllDataReceive := '';
exit;
end;

if Length(AllDataReceive) < 35 then
exit;

for i := 1 to Length(AllDataReceive) div 35 do
begin
for j := 1 to 7 do
begin //数据转换过程
CurValue := Ord(AllDataReceive[j * 5 - 1]) * 256
+ Ord(AllDataReceive[i * 5 - 2])
+ Ord(AllDataReceive[j * 5 - 3]) / 256.0
+ Ord(AllDataReceive[j * 5 - 4]) / 65536.0;
ChannelFlag := AllDataReceive[j * 5];

case ChannelFlag of //每次7个通道数据,前6个为6通道采样电压,
//第七个采样电流
chr(97):
begin
Value_Channel1 := (CurValue * 3.0 / 4095);
LMDChannel1.Text := FloattoStr(Value_Channel1);
end;
chr(98):
begin
Value_Channel2 := (CurValue * 3.0 / 4095);
LMDChannel2.Text := FloattoStr(Value_Channel2);
// viewstring + '通道2:' + FloatToStr(Value_Channel2) + #13;
end;
chr(99):
begin
Value_Channel3 := (CurValue * 3.0 / 4095);
LMDChannel3.Text := FloattoStr(Value_Channel3);
// viewstring + '通道3:' + FloatToStr(Value_Channel3) + #13;
end;
chr(100):
begin
Value_Channel4 := (CurValue * 3.0 / 4095);
LMDChannel4.Text := FloattoStr(Value_Channel4);
// viewstring + '通道4:' + FloatToStr(Value_Channel4) + #13;
end;
chr(101):
begin
Value_Channel5 := (CurValue * 3.0 / 4095);
LMDChannel5.Text := FloattoStr(Value_Channel5);
// viewstring + '通道5:' + FloatToStr(Value_Channel5) + #13;
end;
chr(102):
begin
Value_Channel6 := (CurValue * 3.0 / 4095);
LMDChannel6.Text := FloattoStr(Value_Channel6);

end;
chr(103):
begin
Current_Value := (CurValue * 3.0 / 4095);
LMDCurrent.Text := FloattoStr(Current_Value);
end;
end;

CurValue := 0;
Delete(AllDataReceive, 1, Length(AllDataReceive)
- Length(AllDataReceive) mod 35);
end;

end;
acDataProcessThread.Synchronize(DrawSeries);//绘制曲线
 
牛人大佬帮帮忙,可以继续加分
 
我认为有两种方案:
1.建立缓存队列
2.自定义流量控制协议
 
请问如何具体实现?
没有做过,请多赐教,
 
你可以尝试使用缓冲方式,并通过读、写指针控制,串口接收控制写指针,数据处理线程控制读指针,如此循环处理即可,由于串口处理毕竟是很慢的,数据处理线程一般都处于等待状态,试一试吧
 
尝试一把,可行的话立即散分
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
633
import
I
后退
顶部