重工电子论坛

标题: 串口通信-协议 [打印本页]

作者: 程浥    时间: 2015-6-4 23:17
标题: 串口通信-协议
本帖最后由 程浥 于 2016-7-20 10:04 编辑

       首先还是简单说一下串口,串口是一种非常通用的设备通信协议,这个是51有的唯一的硬件通信设备,并且现在有很多利用串口进行操作的模块,比如有很多无线通信模块、TTL串口转以太网模块、串口转XXX之类的东东,所以呢串口还是比较重要的。
        正常配置波特率和模式后,单片机就可以进行串口的收发了。一般情况下,是用中断收,数据会不定时来,用while等的话有点废资源;在外面发,发的时候不用while,稍加延时就好。单片机数据收发一般是不会出错的,但是:
        1.万一出错了呢
        2.当串口设备大于二的时候了呢
        3.暂时没想到。。。。。
        所以来个简单的串口协议,也是可以接受的嘛。{0x00//包头     0x01//发送方地址 0x02 //接收方地址   0x33***0x35 0x0B //校验位     0xff//包尾}      当然用多位替代更加好了,例如包头改为0x00 0x00 0x00,校验位相当于对此串数据是否正确的校验,一般是和校验,将数据全累加得到一个8位的值,如果接收方检验后与校验位比较相等,说明正确接收。
        发送包:当单片机检测到发送命令后,首选进入发送程序,并将发送忙位置位,将校验位前面的所有数据累加并存入校验位,通过for循环发送,发送间需要延时1-2ms,保证串口正常发送时序。发送完毕后,将发送忙位清零。
        接收包:当单片机检测到数据后,首选判断是否是0x00,如果是则开始写如数组,当最后一位数据位收完后,前面数据全部累加,存入接收校验符中,然后继续接收,当接收到0xff且是数据最后一位时,发出接收完毕信号。
      
        能收发数据包就好说了,当单片机接收到数据包以后,首先进行地址验证,确定是否是发给自己的,然后进行数据校验,将数据包里面的校验位和累加的校验位对比,成功则发送OK回去,不成功则发送NO,如果发送NO多次,系统自动停止发送。校验成功后将数据存入新的数组中,准备调用。搞个流程图看起更舒服的有没有,画得丑,见谅 file:///C:\Users\Y\AppData\Local\Temp\ksohtml\wps8684.tmp.png
      
        特别说一下,有些带NUM的数字,是为了缓冲区可以伸缩而设置的,这些数字计算是根据原来实际数字而变换过来的,变换后可以通过更改BUF_NUM进行数据包大小的伸缩。

        考虑到代码的移植,并且一般的单片机都会有发和收的中断标志,在不同单片机的初始化里,标志也不同。所以用#define 将TI和RI放在头文件里,而不是在程序里直接写TI=0、TI=1之类的。下面两段是stm32的代码,stm32有很多中断标志位,但是也能提取出类似TI RI的东西,其实也比较简单,但是还是有些地方不足:
        1.没有发送忙判断,导致两包一起进去时会出错,这点可以在收到OK哪里处理。
        2.不能发送不定长度的数据包,这点可以改变包头,比如改为 0x00 0x长度 0x00 然后长度与num处理下,大概就可以了
        3.见楼下评论。。。


串口.zip

4.9 MB, 下载次数: 23


作者: 周鹏    时间: 2015-6-5 17:43
第一个问题是这样的,通信的冲突处理通常较为复杂

常见的方式可以用信号量,锁等进行处理

比较单纯的处理办法就是从机制上解决,比如强制为半双工,比如设定只能一主多从

从机都是被动的,所有的通信由主机发起,从机不会无缘无故返回数据

从机制上从根本上避免出现竞争
作者: 胡小均    时间: 2015-6-5 23:13
stm32的东西欢迎大到STM模块发帖!!!
作者: 程浥    时间: 2015-6-5 23:46
胡小均 发表于 2015-6-5 23:13
stm32的东西欢迎大到STM模块发帖!!!

。。。。




欢迎光临 重工电子论坛 (http://www.cqutlab.cn/) Powered by Discuz! X3.1