不使用延迟实现数据帧间的发送

1.      说在前面

       写这篇文章主要是为了记录本人(刚入职的小菜鸟)在从事嵌入式软件开发过程中所积累的方法以及经验,可能网上有类似的方法,本文主要记录一下自己的理解与思路,也希望和大家一起探讨。

2.      应用范围

        本文主要记录一下通过串口发送数据过程中如何实现帧与帧之间的发送间隔,对于帧内字节间的间隔不作详细讨论。所谓帧与帧之间的发送间隔是指通过串口发送数据的时候,对于接收方判断一个完整帧的时间间隔。比如帧A与帧B发送间隔超过3ms(本文以3ms间隔为例),接收方会认为是两个不同的数据帧,如果小于这个时间间隔则认为发送的是同一个数据帧,会认为帧A和帧B加在一起作为一个完整的数据帧。所以帧与帧之间必须要有一定的时间间隔。

3.      解决方法

        对于新手程序员可能会使用硬件延迟函数delay或者delay_ms进行简单的延迟,对于这种处理方法好处就是简单,仅此而已。但是这种实现方法在一个需要发送大量数据进行通信的时候会严重影响系统的性能,因为没发送一个数据帧都会使系统延迟3ms,发送大量的数据的时候这个延迟就会被放大,从而影响系统的整体性能。本文主要是针对这个原因进行改善。

        总体的思路是:把每次所要发送的数据帧进行分类(比如:控制、响应、业务的其它不同需求等),发送之前分别存储在相应的数组里,这些数组是一个全局变量,里面存放所需要发送的数据帧,长度固定(不同的数据帧类型的数组长度不一定相同)。在发送模块建立一个全局结构体数组(暂且称为发送缓冲区),每一个数组成员都是一个结构体,这个结构体里存放两个变量,一个是需要发送的数据帧的首地址(就是前面提到的全局数组的首地址),另一个是这个数据帧的长度。这样就可以实现发送的时候把数据放在对应的全局数组里,通过全局结构体数组进行统一管理。这个全局结构体数组大小为SendNmMax(根据系统需求而定),对于这个结构体还有三个变量SendPtr、RecvPtr和CurSendNum,分别表示当前接收数据的位置和待发送的数据的位置以及当前还剩余待发送的数据个数。每当有数据需要发送,就把地址和长度存在这个全局结构体数组里,每当3ms时间达到就从这个发送缓冲区里发送对应的数据。每次有需要发送的数据存进来就把RecvPtr加1,CurSendNum也加1,每当发送了一个数据就把SendPtr加1,并且把CurSendNum减1(同时注意RecvPtr和SendPtr加到最大值SendNmMax-1的时候要从0开始计数),程序每次判断发送缓冲区的SendNmMax大小,如为0则直接退出,非0就按照SendPtr的位置发送数据。大体的框架如下:


总结一下:

我们需要两个函数就可以搞定,一个是把要发送的数据帧的地址和长度赋值给发送缓冲区的结构体数组里(copy_data_to_send_module),另一个是发送数据的函数(send_data)。

这样每次有需要发送的数据就调用copy_data_to_send_module函数使其地址和长度存放到发送缓冲区,定时器定时,超过3ms就调用send_data发送数据即可,这个发送函数send_data可以放在main函数的while(1)里也可以通过调度进行调度(没有操作系统的话就自己写一个简单的调度系统了)。

4.      结束语

        由于工作原因代码不能贴出来,其实弄懂了原理之后编写代码只是分分钟的事(思路清晰写起来就快了),如果有描述不清楚的地方或者不太明白的可以留言一起讨论。希望大家多做总结和本菜鸟一起在菜鸟的路上越走越远吧(谁都想成为大神不是么)!转载请注明原文链接http://blog.csdn.net/qq_23538907/article/details/78857053。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值