如何用MSCOMM采集串口不定长度的实时数据,并取得指定字节开头的12个字节???(100分)

  • 主题发起人 主题发起人 wangwa
  • 开始时间 开始时间
W

wangwa

Unregistered / Unconfirmed
GUEST, unregistred user!
如何用MSCOMM采集串口不定长度的实时数据,并取得指定字节(DD)开头的12个字节??
我正在做采集串口的一个程序,我需要从实时接收的串口中取得如下面这样的串,DD,6A,12,XX,XX,XX,XX,F3,XX,XX,45,X3
我用串口助手,采集实时数据如下:
CA 2E 00 00 00 00 00 0E CA 2F 00 00 00 00 00 0F
CA 30 00 00 00 00 00 00 CA 31 00 00 00 00 00 01
CA 01 00 01 00 00 00 02
CA 02 00 00 00 00 00 02 CA 03 00 00 00 00 00 03
CA 04 00 00 00 00 00 04 CA 05 00 00 00 00 00 05
CA 06 00 00 00 00 00 06 CA 07 00 00 00 00 00 07
CA 08 00 00 00 00 00 08 CA 09 00 00 00 00 00 09
CA 0A 00 00 00 00 00 0A CA 0B 00 00 00 00 00 0B
CA 0C 00 01 00 00 00 0D CA 0D 00 01 00 00 00 0E
CA 0E 00 01 00 00 00 0F CA 0F 00 00 00 00 00 0F
CA 10 00 00 00 00 00 00 CA 11 00 00 00 00 00 01
CA 12 00 00 00 00 00 02 CA 13 00 00 00 00 00 03
CA 14 00 00 00 00 00 04 CA 15 00 00 00 00 00 05
CA 16 00 00 00 00 00 06 CA 17 00 00 00 00 00 07
CA 18 00 00 00 00 00 08 CA 19 00 00 00 00 00 09
CA 1A 00 00 00 00 00 0A CA 1B 00 00 00 00 00 0B
CA 1C 00 00 00 00 00 0C CA 1D 00 00 00 00 00 0D
CA 1E 00 00 00 00 00 0E CA 1F 00 00 00 00 00 0F
CA 20 00 00 00 00 00 00 CA 21 00 00 00 00 00 01
CA 22 00 00 00 00 00 02 CA 23 00 00 00 00 00 03
CA 24 00 00 00 00 00 04 CA 25 00 00 00 00 00 05
CA 26 00 00 00 00 00 06 CA 27 00 00 00 00 00 07
CA 28 00 00 00 00 00 08 CA 29 00 00 00 00 00 09
CA 2A 00 00 00 00 00 0A CA 2B 00 00 00 00 00 0B
CA 2C 00 00 00 00 00 0C CA 2D 00 00 00 00 00 0D
CA 2E 00 00 00 00 00 0E CA 2F 00 00 00 00 00 0F
CA 30 00 00 00 00 00 00 CA 31 00 00 00 00 00 01
CA 01 00 01 00 00 00 02 F3 00 00 01 00 DD 65 04 01 00 00 00 F3 00 00 01 00 0B

100分请高手解答,要求有代码!!
 
楼主:我也正在做类似的东西,有效消息请通知我啊,谢谢!dongfang320@163.com
 
用定时器来做,mscomm设置为1个字节一触发,在定时器里进行判断
 
SPCOMM很好用的哟
 
很久没有用过MSCOMM了不知道说的对不对.(其实串口编程用API函数挺简单的.)
这样看来,你是把DD做为协议头.协议长为12字节.没有协议结束字节(串).
你可以这样定义一个长度为12字节的字符串(Char数组),在MSCOMM的接收事件触发后,检索MSCOMM的接收缓区如果找到DD那么反向将DD前12个字节拷贝到你的数据中去.
前提是MSCOMM接收事件触发条件是接收完所有字节(协议).
按照你的意思可能是不好定义这个条件.
那么你可以定义一个足够长的缓冲区(视你的最长协议而顶,这时MSCOMM接收事件的触发条件可随意定).每次接收到数据,将数据压入缓冲区(注意这里是压入,缓冲区并不为空.).并检索本次数据中是否含有DD如果包含DD就将DD前12字节拷贝出来清空你定义的缓冲区.如果没有等待下次接收事件并保持原有的缓冲区数据(不清空缓冲区).
MSCOMM接收到的数据相对发送方来说是反向的.所以DD前12个数据,即为发送方DD后12个数据.
 
定义一个长度为12字节的数组:char buf[12];

把所有收到的字节都用下面的代码过滤:
for (i=0;i<12;i++) buf=buf[i+1];
buf[11]:=收到的数据;
if ((buf[0] == 0xDD) && (buf[1] == 0x6A) && (buf[2] == 0x12)
&& (buf[7] == 0xF3) && (buf[10]=0x45) && ((buf[11] & 0x0F) == 0x03))
{
/* 满足条件 buf就是你要的数据了 */
}

buf就像是一个先进先出的栈,每收的一个数据就放进栈里,任何时候满足条件,栈里就是所要的数据了。
 
建议看一下
http://zhaokaien.17757.com
里面关于协议的一节会对你有帮助
 
DD,6A,12,XX,XX,XX,XX,F3,XX,XX,45,X3
MSCOMM设为每一个字节触发一次.在触发事件里对收到的数据进行逐一判断,
如果前三个字节等于DD,6A,12的话,就认为可以连续接收十二个字节.
这样的话应该可以的.
 
(现在结帖,自己经过努力早就搞定了!只是现在才结贴)
对于实时不定长数据分析,主要思路应该是设置接收1个字节产生OnComm 事件,然后读取全部缓存区内容,进行处理就可以了!
定义参数如下
MSComm1.CommPort := 1;//设置端口1
MSComm1.Settings := '9600,n,8,1';//9600波特率,无校验,8位数据位,1位停止位
MSComm1.InputLen := 0;//读取缓冲区全部内容(32个字节)
MSComm1.InBufferCount := 0;// 清除接收缓冲区
MSComm1.OutBufferCount:=0;// 清除发送缓冲区
MSComm1.RThreshold := 1;//设置接收1个字节产生OnComm 事件
//MSComm1.InputMode := comInputModeText;//文本方式
MSComm1.InputMode := comInputModeBinary;//二进制方式
MSComm1.PortOpen := true;//打开端口
。。。。。。。。。。。。。。
procedure TForm1.MSComm1Comm(Sender: TObject);
var
buffer: Olevariant;//MSComm1.InputMode = comInputModeBinary
info: string;//MSComm1.InputMode = comInputModeText
i,j: integer;
begin
case MSComm1.CommEvent of
comEvReceive: //串行接收事件处理
begin
j:= MSComm1.InBufferCount;
MSComm1.InputLen:=j;
buffer := MSComm1.Input;//读出后会自动清除接收缓冲区
 
后退
顶部