如何进行串口通信自定义协议,真心求教

智能硬件 2016-09-23 07:09:23
现在需要通过串口通信向向显示屏传 温度、适度还有心跳,以便在显示屏显示出来,协议自定义。求教,怎么自定义协议呢。求高手指点。谢谢~
...全文
6360 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
gongzf111 2017-03-08
  • 打赏
  • 举报
回复
请问楼主的问题解决了没?现在我也遇到自定义串口协议的问题。。
智能硬件 2016-10-10
  • 打赏
  • 举报
回复
引用 8 楼 of123 的回复:
你从最基本的需求出发,然后一步步考虑是否需要追加附加信息。 比如,你就是要传 3 字节数据,分别是温度、湿度、脉搏。如果间隔时间够长,仅发送这三个字节就可以了。也还是理解为起始信号和结束信号就是至少长度 N 字节的空闲状态,如果你发送此 3 字节的间隔小于 N 的话。 如果你是很频繁地发送,且字节间的间隔不定。那接收方就必须要一个方法找到开头。这样你就会需要加上包头和包尾。不仅仅如此,你的包头和包尾必须不会与实际数据混淆,也就是要用实际数据不会用到的值。比如,你设定包头包尾是 0x4F 和 0xF4,那这两个值就不能出现的实际数据中。一个解决方案就是,实际数据用 ASCII 编码,即数字 0 - 9 用 0x30 - 0x39 表示,如果还要支持十六进制字符 A - F,还要加上 0x41 - 0x46。这样一来,你一个十六进制字节的值,就要用 2 个 ASCII 字符表示。当然,你可以把实际数据都用十进制表示,例如用 3 个 BCD 码,那每个数据域要用 6 个 ASCII 字符,三个域共 18 个 ASCII 字符。 最后,你是否需要纠错。如果你的传输环境不是非常可靠,有可能出现传输错误,你就可能需要在包中加上错误校验域(当然也可以仅仅依赖于串口的奇偶校验),可以用 LRC 或 CRC。 总之,需求越高,系统越复杂。完全取决于你的实际应用需求。
谢谢,可否用代码表示一下怎样组包呢,看的还是有点迷糊。谢谢
of123 2016-10-10
  • 打赏
  • 举报
回复
你从最基本的需求出发,然后一步步考虑是否需要追加附加信息。 比如,你就是要传 3 字节数据,分别是温度、湿度、脉搏。如果间隔时间够长,仅发送这三个字节就可以了。也还是理解为起始信号和结束信号就是至少长度 N 字节的空闲状态,如果你发送此 3 字节的间隔小于 N 的话。 如果你是很频繁地发送,且字节间的间隔不定。那接收方就必须要一个方法找到开头。这样你就会需要加上包头和包尾。不仅仅如此,你的包头和包尾必须不会与实际数据混淆,也就是要用实际数据不会用到的值。比如,你设定包头包尾是 0x4F 和 0xF4,那这两个值就不能出现的实际数据中。一个解决方案就是,实际数据用 ASCII 编码,即数字 0 - 9 用 0x30 - 0x39 表示,如果还要支持十六进制字符 A - F,还要加上 0x41 - 0x46。这样一来,你一个十六进制字节的值,就要用 2 个 ASCII 字符表示。当然,你可以把实际数据都用十进制表示,例如用 3 个 BCD 码,那每个数据域要用 6 个 ASCII 字符,三个域共 18 个 ASCII 字符。 最后,你是否需要纠错。如果你的传输环境不是非常可靠,有可能出现传输错误,你就可能需要在包中加上错误校验域(当然也可以仅仅依赖于串口的奇偶校验),可以用 LRC 或 CRC。 总之,需求越高,系统越复杂。完全取决于你的实际应用需求。
智能硬件 2016-10-08
  • 打赏
  • 举报
回复
引用 6 楼 91program 的回复:
[quote=引用 5 楼 qq_27639619 的回复:] ,如何将这些头、标志位、温度、心跳等信息组成一个数据包呢?直接做成字符串好像是不行的。谢谢
怎么个不行呢? 如果 LZ 你是担心出现零等异常字符,可以考虑在发送将将字符串格式化。 但这样做,就要求接收方对接收到的字符也进行相应的反处理。 例如:将 0 使用 Format 格式化成字符串 00,这样发送的时候字符都是可见的。[/quote] 谢谢您指点,我现在还是有点迷糊。例如:协议中规定传输格式如下,定长: 头(1字节)、数据类别的标志位(1字节)、温度(3字节)、心跳(2字节)、校验位(1字节)、尾(1字节), 其中头为0X4F,尾为0XF4,现在既传温度也传心跳,其中温度为37度,心跳为68下,此时温度心跳均显示时标志位为0X03,校验位按求和校验(此时可以先不管),这样的数据传输如何用代码表示呢? 其中发送代码还是 int SerialPortSend(int fd, char *send_buf,int data_len) { int len = 0; len = write(fd,send_buf,data_len); if (len == data_len ) { return len; } else { tcflush(fd,TCOFLUSH); return 0; } }
91program 2016-10-08
  • 打赏
  • 举报
回复
引用 5 楼 qq_27639619 的回复:
,如何将这些头、标志位、温度、心跳等信息组成一个数据包呢?直接做成字符串好像是不行的。谢谢
怎么个不行呢? 如果 LZ 你是担心出现零等异常字符,可以考虑在发送将将字符串格式化。 但这样做,就要求接收方对接收到的字符也进行相应的反处理。 例如:将 0 使用 Format 格式化成字符串 00,这样发送的时候字符都是可见的。
智能硬件 2016-10-08
  • 打赏
  • 举报
回复
引用 4 楼 91program 的回复:
[quote=引用 3 楼 qq_27639619 的回复:] 谢谢,当open、初始化好串口,然后发送数据的时候,怎么把这一串数据包发送出去呢,谢谢
怎么发送?组好包就是一串字符串,直接调用发送功能就行。 不清楚你想要什么![/quote] int SerialPortSend(int fd, char *send_buf,int data_len) { int len = 0; len = write(fd,send_buf,data_len); if (len == data_len ) { return len; } else { tcflush(fd,TCOFLUSH); return 0; } } 以上是一个发送的程序, send_buf是要发送内容的地址,,而数据包里包含头、数据类别的标志位、温度、心跳、校验位、尾, 每一部分占得字节数不同:头(1字节)、数据类别的标志位(1字节)、温度(3字节)、心跳(2字节)、校验位(1字节)、尾(1字节), ,如何将这些头、标志位、温度、心跳等信息组成一个数据包呢?直接做成字符串好像是不行的。谢谢
91program 2016-10-08
  • 打赏
  • 举报
回复
引用 3 楼 qq_27639619 的回复:
谢谢,当open、初始化好串口,然后发送数据的时候,怎么把这一串数据包发送出去呢,谢谢
怎么发送?组好包就是一串字符串,直接调用发送功能就行。 不清楚你想要什么!
智能硬件 2016-10-08
  • 打赏
  • 举报
回复
引用 1 楼 91program 的回复:
这是完全的自定义协议,你想怎么定义都行。例如一帧数据: 帧头(两个字节)+标识位(一个字节)+类型(一个字节)+数据长度(一个字节,或者多个字节)+数据(多个字节)+校验位(一个字节)+帧尾(一个字节) 等等,你可以增加。
谢谢,当open、初始化好串口,然后发送数据的时候,怎么把这一串数据包发送出去呢,谢谢
侦探蜡笔小新 2016-09-23
  • 打赏
  • 举报
回复
自定义协议,一般包含帧头,功能码,数据,校验等
91program 2016-09-23
  • 打赏
  • 举报
回复
这是完全的自定义协议,你想怎么定义都行。例如一帧数据: 帧头(两个字节)+标识位(一个字节)+类型(一个字节)+数据长度(一个字节,或者多个字节)+数据(多个字节)+校验位(一个字节)+帧尾(一个字节) 等等,你可以增加。

3,849

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 无线
社区管理员
  • 无线
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧