|
自己在写一个PC机串口接收下位机ARM发送的AD转换的数据,并显示实时波形的东东,使用Delphi7+ComPort控件。
使用ComPort的OnRxFlag事件,事件字符设置为#10,当接收到数据帧头0x0a 时,触发这个事件,然后在事件句柄中调用ReadStr(Str,26)读取26个字节到Str中,这26个字节有一个字节的帧头0x0a,一个字节的帧尾0x0c,中间是AD采集到的数据24个字节(8通道*3字节)。
我用ARM发送26字节的固定数据到PC:
0x0a,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0xFE,0x0b,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,0xF9,0xFa,0xFb,0xFc,0xFD,0x0c。
用串口调试助手接收数据没有问题,可是用我自己编写的Delphi程序接收时经常会接收出错,具体是周期性发生读取到的Str不是要求的26字节,一会对,一会不对,大部分情况下是26字节,但偶尔会8个字节或18个字节,而且第一帧必是错误的。
后来我加上了判断帧头和帧尾,这样能够接收到正确数据,但是中间有大量数据被丢弃,按道理讲,每次接收到0x0a,则应该将其后的25个字节一起读取到Str中,为什么会少读呢,而且第一组数据必少?
源代码:(ComPort的RxFlag事件句柄)
procedure TForm1.ComPortRx(Sender: TObject);
var
Str:String; // 每次接受的字符串
Ch1,Ch2,Ch3,Ch4,Ch5,Ch6,Ch7,Ch8: Integer; //三个字符连接得到整形(24位AD)
Cch1,Cch2,Cch3,Cch4,Cch5,Cch6,Cch7,Cch8: Single; //与参考电压计算后得到的电压值
begin
k :=ComPort1.ReadStr(Str, 26); //读取26个字节到Str
(*判断帧头和帧尾是否是0x0a和0x0c*)
if ((Str[1] =Chr($0a)) and (Str[26] =Chr($0c)))then
begin
(*接受到正确的数据次数加一,并用Label2显示*)
j :=j+1;
Label2.Caption :=IntToStr(j);
(*连接三个字符,并转化为整形*)
Ch1 :=StrByteToInt(Str[4]+Str[3]+Str[2]);
Ch2 :=StrByteToInt(Str[7]+Str[6]+Str[5]);
Ch3 :=StrByteToInt(Str[10]+Str[9]+Str[8]);
Ch4 :=StrByteToInt(Str[13]+Str[12]+Str[11]);
Ch5 :=StrByteToInt(Str[16]+Str[15]+Str[14]);
Ch6 :=StrByteToInt(Str[19]+Str[18]+Str[17]);
Ch7 :=StrByteToInt(Str[22]+Str[21]+Str[20]);
Ch8 :=StrByteToInt(Str[25]+Str[24]+Str[23]);
(*与参考电压计算,得到实际电压值*)
Cch1 :=3*Ch1/10000000;
Cch2 :=3*Ch2/10000000;
Cch3 :=3*Ch3/10000000;
Cch4 :=3*Ch4/10000000;
Cch5 :=3*Ch5/10000000;
Cch6 :=3*Ch6/10000000;
Cch7 :=3*Ch7/10000000;
Cch8 :=3*Ch8/10000000;
(*超过参考电压(2.5V)的转化为负数*)
if Cch1>2.5 then
begin
Cch1 :=Cch1-5
end;
if Cch2>2.5 then
begin
Cch2 :=Cch2-5
end;
if Cch3>2.5 then
begin
Cch3 :=Cch3-5
end;
if Cch4>2.5 then
begin
Cch4 :=Cch4-5
end;
if Cch5>2.5 then
begin
Cch5 :=Cch5-5
end;
if Cch6>2.5 then
begin
Cch6 :=Cch6-5
end;
if Cch7>2.5 then
begin
Cch7 :=Cch7-5
end;
if Cch8>2.5 then
begin
Cch8 :=Cch8-5
end;
(*实时波形显示,使用Iocomp控件*)
iPlot1.Channel[0].AddXY(px,Cch1);
iPlot1.Channel[1].AddXY(px,Cch2);
iPlot1.Channel[2].AddXY(px,Cch3);
iPlot1.Channel[3].AddXY(px,Cch4);
iPlot1.Channel[4].AddXY(px,Cch5);
iPlot1.Channel[5].AddXY(px,Cch6);
iPlot1.Channel[6].AddXY(px,Cch7);
iPlot1.Channel[7].AddXY(px,Cch8);
px :=px+1;
end
(*不是合法的数据帧*)
else
begin
(*接收到错误数据次数加一,并送Label显示*)
i :=i+1;
Label1.Caption :=IntToStr(i);
//k :=Length(Str);
//Memo1.Lines.Add (Str);
Memo1.Lines.Add (IntToStr(k)); //显示不合法数据帧包含字节的个数
end;
end;
1 (原文件名:1.JPG)
2 (原文件名:2.JPG) |
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|