打印

求思路,关于接收不固定长度数据包

[复制链接]
4307|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lk0623|  楼主 | 2010-12-24 00:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
接收上位机发送过来的长度不固定的数据包,想知道如何实现?
现在固定长度为50的是这样的
void UART_one_Interrupt_Receive(void) interrupt 4
{
      RI  =   0;
      RXDBUFF[i]  =   SBUF;
          i++;
          if(i>49)
          {
           //BEEP();
           i=0;
           uart_flag=1;       
          }                                      
}

相关帖子

沙发
lk0623|  楼主 | 2010-12-24 00:31 | 只看该作者
还有我用的是STC10F04XE的单片机,貌似数组最大能放150,还不够用,有人建议我把数组类型改为xdata 这样可以吗? 还是要分成多个数组存放?

使用特权

评论回复
板凳
chunyang| | 2010-12-24 00:42 | 只看该作者
用协议,协议内包含长度信息或用结束符来表示,接收到的数据可用数组做缓冲,如果数据帧带有长度信息,将长度信息作为数组长度的定义值就是。

使用特权

评论回复
地板
yewuyi| | 2010-12-24 08:36 | 只看该作者
不定长的数据包处理有很多细节需要注意:
例如,你处理数据的速度要够快,否则小心缓冲冒顶。
不定长不代表没有任何限制,可以无限长,如果用数据长度信息的话,那么最大长度就是这个变量的可表最大范围

使用特权

评论回复
5
救火车| | 2010-12-24 09:30 | 只看该作者
用队列。先进先出法。

使用特权

评论回复
6
liaoyaohui| | 2010-12-24 15:36 | 只看该作者
看看

使用特权

评论回复
7
杨工| | 2010-12-24 16:28 | 只看该作者
STC10F04XE有256字节XDATA RAM, 可以作串口接收缓冲区. 省下宝贵的前256字节RAM.
不定长究竟最大是多少呢? 最好限制在256字节以内甚至更小. 处理比较简单.

使用特权

评论回复
8
tyz114499| | 2010-12-24 22:59 | 只看该作者
如果有多余的定时器,可以这样:程序刚启动时关闭这个定时器,定时时间稍大于4个字节的传输时间,当发生串口接收中断时,把这个定时器先关闭,清零,然后启动定时器,串口的中断服务程序中每次都是对该定时器关闭,清零,然后再重新启动,当接收到最后一个字节时,定时器启动后不会再被关闭,4个字节的时间后定时器触发,表示接收完毕,这时可以把定时器关闭,等待下一次数据的到来

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
古道热肠 + 2
9
原野之浪| | 2010-12-24 23:05 | 只看该作者
用8楼的办法 就是MODBUS方法

使用特权

评论回复
10
草根白骨精| | 2010-12-25 00:51 | 只看该作者
采用8楼的方法,但无须关闭定时器,没接收到一个数据中断清零不让定时器中断即可,我所使用的是100ms,没有多余的定时器可以复用,复用则用变量计数

使用特权

评论回复
11
lk0623|  楼主 | 2010-12-26 12:29 | 只看该作者
看了各位大大的解说,结合了下朋友的意见:当缓存区里有数据的时候,就开始启动定时器,等待20ms(最大数据也能接收完成,可计算),然后对于当前缓存区长度进行比对,如果超出最大长度,则将缓存区清0,反之对与接收到的数据处理,

使用特权

评论回复
12
headwolf_83| | 2010-12-26 13:58 | 只看该作者
1、类似MODBUS ASCII,结束符号是固定的。收到结束符号也就差不多了。
2、MODBUS RTU,帧与帧之间的间隔是有限制的,超过一定时间就认为是新的帧,每收到一个字节,复位定时器或者软件计数器。主程序查到定时器超时,就认为是帧结束。
3、没有以上2点信息,一般协议中都要有长度信息,比如HART协议。根据长度信息做判定。
4、没有无限制的协议,一般的协议都是一主一从或者一主多从,PC主,MCU从。这样的模式有一个好处,就是PC没收到应答前,只能通过超时来确认是否要重发。因此MCU可能可以规定一个短的时间,这个时间能保证最长的数据帧已经收到,又不违背上位机的超时要求,时间到了就认为帧结束了,开始处理。这个方法对从机而言,要具体分析协议,未必通用。一般用1,2,3。上位机倒是有人用这个来收串口数据。

使用特权

评论回复
13
headwolf_83| | 2010-12-26 14:01 | 只看该作者
如果协议自定义的又不知道怎么定义好,可以参考MODBUS RTU自己做一些调整,比如调整下大下端点,以方便单片机。

使用特权

评论回复
14
古道热肠| | 2010-12-26 15:10 | 只看该作者
注意用包头字符同步起始位置,接着是附加数据长度,最后是附加数据,最后带上CRC校验,上位机发此包,不响应,重发,下位机用串口中断接收,先取包头进行同步,取得附加数据长度后,收取指定长度的数据,然后进行相应的处理,比较可靠。

使用特权

评论回复
15
lhchen922| | 2013-11-13 08:49 | 只看该作者
用到了。

使用特权

评论回复
16
coody| | 2013-11-13 10:08 | 只看该作者
方法有:
1: 字符同步方式.
2: 超时方式(比如MODBUS协议)

使用特权

评论回复
17
zjxcml| | 2013-11-13 11:19 | 只看该作者
tyz114499 发表于 2010-12-24 22:59
如果有多余的定时器,可以这样:程序刚启动时关闭这个定时器,定时时间稍大于4个字节的传输时间,当发生串口接 ...

呵呵,我就是这样用的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

109

帖子

0

粉丝