前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >串口通信用户层协议编制技巧与实现

串口通信用户层协议编制技巧与实现

作者头像
bigmagic
发布2020-03-17 14:54:49
1.8K0
发布2020-03-17 14:54:49
举报
文章被收录于专栏:嵌入式iot嵌入式iot

前言

协议就是约束双方通信的一种规范,只有严格遵守这种协议的设备才能进行相互的通信。比如串口通信协议,必须包含起始位、主体数据、校验位及停止位,双方需要约定一致的数据包格式才能正常收发数据的有关规范。在串口通信中,常用的协议包括RS-232、RS-422和RS-485等。与此类似还有I2C通信协议。但是往往这些只是底层的通信协议,很多外设都已经集成好了,只需配置相关的寄存器就能够得到数据主体了。根本不需要用户去关注协议的组成,而我这篇文章主要讲的是用户层协议的编制原理和实现手段。

什么是用户层协议?简单的说就是用户自定义的某种数据格式,有包头,心跳帧,命令字,数据帧,校验帧,结尾帧等。当需要接受数据帧的设备收到一帧数据后,进行解包,并且校验,将有用的数据帧提取出来,然后根据具体的数据帧执行相应的动作。这就是用户协议编制的基本原理。下面来具体讲一下这个过程。

什么情况下会用到用户层协议

做嵌入式肯定会遇到两个模块进行通信的情景,比如两个mcu或者两个mpu,mcu与mpu之间的交互,往往涉及到多种逻辑。不像单功能模块一样只做一件事,可能涉及到许多的交互,比如状态上传,控制逻辑等等。举个例子来说,mcu要和智能电表进行交互。此时mcu不仅可以读取到电表电能,电量等信息,也可以控制空开的开合闸。同时,电表也可能主动向mcu上传一些报警信息。针对这样的情况,就需要制定电表协议,电表按照这样的协议进行数据收发,mcu也需要有发出或者解析这样格式的能力。

从modbus协议开始分析

首先Modbus是一种工业上常用的通信协议,其中包含RTU,ASCII,TCP等等,其中MODBUS-RTU比较容易实现。一般的文档写的都比较复杂,将用最简单的方式讲述一下这个过程。我们不分析协议内容,只讲协议的实现。

假如我们从串口收到了一条报文:01 06 00 01 00 17 98 04。这一串16进制的数据被存放在一个buf数组中,首先编程人员要理解这一串数据的含义,所以先进行拆包。

01

06

00 01

00 17

98 04

从机地址

功能号

数据地址

数据

CRC校验

从机地址:

一条总线上可能挂载多个设备(对于串口一般是RS-485)。所以需要广播这个消息是发送给哪个设备的,01表示告诉的是地址编号为01的设备。

功能号:

顾名思义,功能号就是通知该设备执行什么动作,比如控制LED灯,或者打开某个寄存器等等。每一项动作都是有特定的功能号。

数据地址:

数据地址就是操作的设备的寄存器,这个在modbus协议特有,暂时不做分析。自定义协议时也很少用到。

数据:

这部分就是将特定的数据交给设备,比如可以自定义开灯动作为数据”1“,关灯动作为数据"0"。设备接收到特定的功能号,然后解析这个数据,就能够执行具体的动作了。

CRC校验:

校验的目的就是为了保证这一包数据的完整性,发送过来的数据是主机已经算好了CRC校验码,然后设备收到数据后,再次将前面的数据算一遍,然后与接收到的CRC校验码进行对比,如果数据是准确的,就证明数据完整且传输过程中没有出现错误数据。然后才能开始执行动作。如果校验有误,应该丢弃该包数据,请求重传,以免造成不可预知的后果。

主机发送完这串字符串后,可以看到编号为01的从机开始执行动作了。这只是一个最简单的例子,但是也能说明白用户层协议是怎么一回事。

开始一个简单的应用

协议制定

在做项目之前,先设计需求,假如我们有这样一个需求:现在做了一个从机的板子,上边只有一个按键和一个led。这块板子和另一块主机通过串口方式进行连接。当主机发送数据包:命令码0x01,控制码0x01的数据过来时,点亮模块板上的LED,当主机发送数据包:命令码0x01,控制码0x00的数据过来时,熄灭板子上的LED。当按键按下时,板子主动上传:命令码0x02,控制码0x00的数据。

功能已经明确,接着就开始写协议文档。

协议文档就是约束通信双方的通信格式,一般用word文档比较正式也比较好交接。首先可以规定串口波特率,有无校验位,停止位。然后开始规范包格式。根据这个简单的应用需求,我可以先制定包格式如下

包头

命令码

控制码

CRC校验

2字节

1字节

1字节

2字节

制定完基本格式,然后一条一条的完善这个协议

LED控制(0x01)

数据格式

包头

命令码

控制码

CRC校验

0xAA 0xBB

0x01

0x00(关灯) 0x01(熄灯)

--

说明:

当收到命令为0x01的命令码时,需要判断控制码执行的动作,然后进行关灯和开灯的操作。

按键状态上传(0x02)

数据格式

包头

命令码

控制码

CRC校验

0xAA 0xBB

0x02

0x00

--

说明:

当按键按下时,模块主动向主机发送命令码为0x02的数据包,其他情况下不会发送。

程序分析

可以用在stm32f103cbt6上进行实验,在写代码时,先设计程序的框架。用到的资源:

1.串口

2.rt-thread操作系统

3.按键中断

4.led

如果用到了rt-thread系统,就不用从头开始,我们只专注于协议部分的实现就好。点灯操作可以采用pin驱动模型。程序部分的设计我将在下一篇文章中详细介绍。

总结

用户协议的制定是非常重要,也是非常的关键的,前面很多人都不理解协议,这篇文章写得很基础,也非常容易理解,希望能够给大家一点帮助。下一篇文章将从协议的去耦合性以及可扩展性上详细设计一下代码。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-11-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 嵌入式IoT 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 什么情况下会用到用户层协议
  • 从modbus协议开始分析
  • 开始一个简单的应用
    • 协议制定
      • 程序分析
      • 总结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档