精华内容
下载资源
问答
  • 在IAR中用寄存器实现STM8S003串口通信,在接收中断中解析通信协议通信协议为两位数据作为头,两位数据作为尾。数据长度为任意长。并且允许发送的数据可以和协议头尾数据相同。大大减小了误判和漏判的几率。
  • 串口变长协议解析案例 解析的关键方法直接看SerialControl.java类即可! (为毛这么短的README?因为我编辑了半天的文章一下子就没!) ======================================================== 补上文章链接: ...
  • 串口编程 - 通信协议解析 规定了串口通信协议之后,接下来就是如何解析通信协议

    串口编程 - 通信协议解析


    如需转载请标明出处:http://blog.csdn.net/itas109
    QQ技术交流群:129518033

    前言

    规定了串口通信协议之后,接下来就是如何解析通信协议。

    1. 解析通信协议流程

    +--------------+
    |              |
    |   收到数据   |
    |              |
    +------+-------+
           |
    +------v-------+
    |              |
    |   放入缓冲区 |
    |              |
    +------+-------+
           |
           |
    +------v-------+
    |              |
    |  找到帧头    |
    |              |
    +------+-------+
           |
           |
    +------v-------+
    |              |
    |   根据长度   |
    |   提取数据   |
    +------+-------+
           |
           |
    +------v-------+
    |              |
    |   校验数据   |
    |   移除缓冲   |
    +------+-------+
           |
    +------v-------+
    |              |
    |   解析完成   |
    |   通知上层   |
    +--------------+
    

    2. 伪代码

    // 1. 接收的数据放到缓冲区
    buffer.insert(commReceiveData);
    // 2. 桢解析 
    /*
    EB90 00 0007 20211025000000 7F52
    
    帧头:0xEB90
    版本: 0x00
    数据长度:0x0007
    数据:0x20211025000000
    校验和(CRC-16/MODBUS(0x18005)):0x7F52
    */
    while (buffer.length >= 7) // 缓冲区长度至少为7,包括帧头(2字节)+版本(1字节)+数据长度(2字节)+校验和(2字节)
    {
        //2.1 查找帧头
        int headerIndex = buffer.find(0xEB); // 帧头第一个字符索引
        if(headerIndex >= 0)
        {
            if ( buffer[headerIndex + 1] == 0x90) // 帧头第二个字符
            {
                // 2.2 判断数据长度
                int len = buffer[headerIndex + 3] << 8 + buffer[headerIndex + 4]; // 获取数据长度
    
                // 数据长度不足,则等待下一次判断
                if (buffer.length < len + 5)
                {
                    break;
                }
                else
                {
                    // 2.3 计算校验码
                    string dataNeedCheck = buffer.substring(headerIndex,len + 5);
                    checkSum = checkSumFunction(dataNeedCheck); // 获取从帧头到校验和前的所有数据的校验码
                    dataCheckSum = buffer[headerIndex + len + 5] << 8 + buffer[headerIndex + len + 6]; // 获取缓冲区数据的校验吗
                    if(checkSum == dataCheckSum)
                    {
                        // 数据校验成功,提取数据通知同层业务
                        string dataFrame = buffer.substring(headerIndex,len + 7);
                        notify(dataFrame);
                        continue;
                    }
                    else
                    {
                        // 数据校验失败,继续下一次循环
                        continue;
                    }
                }
            }
            else
            {
                // 帧头0xEB90判断失败,则继续寻找下一个0xEB
                buffer = buffer.substring(2); // buffer指向后面的数据
                continue;
            }
        }
    }
    

    License

    License under CC BY-NC-ND 4.0: 署名-非商业使用-禁止演绎

    如需转载请标明出处:http://blog.csdn.net/itas109
    QQ技术交流群:129518033


    Reference:

    1. NULL
    展开全文
  • ROS串口通信协议解析

    2020-08-12 11:27:04
    ROSserial 串口通信协议解析 1. 总览 ROS-serial是用于包装标准ROS序列化消息并在外部设备(例如串行端口或网络套接字)上多路复用多个主题和服务的协议。 2. 局限性 这里定义了发布主题消息的最大大小,发布者/订阅...

    ROSserial 串口通信协议解析

    1. 总览

    ROS-serial是用于包装标准ROS序列化消息并在外部设备(例如串行端口或网络套接字)上多路复用多个主题和服务的协议。

    2. 局限性

    这里定义了发布主题消息的最大大小,发布者/订阅者的最大数量
    对于rosserial_client,默认情况下,发布者和订阅者的数量限制为25,序列化和反序列化缓冲区的大小限制为512字节。

    但是,这些数目和大小对于SRAM有限的微控制器来说太大了。rosserial_arduino的缓冲区大小和发布者/订阅者的数量现在取决于所使用的芯片:

    AVR模型输出缓冲区大小发布者/订阅者
    ATMEGA168150/150字节6/6
    ATMEGA328P280/280字节25/25
    其他512/512字节25/25

    您可以更改这些数字和大小

    typedef NodeHandle_<HardwareType, MAX_PUBLISHERS, MAX_SUBSCRIBERS, IN_BUFFER_SIZE, OUT_BUFFER_SIZE> NodeHandle;
    

    但是,您应该注意不要消耗Arduino中有限的SRAM。如果Arduino的SRAM用完了,它只会挂起而没有调试信息。

    大于缓冲区大小的消息不会发送。ROS错误消息将被中继,告知该消息是来自设备还是来自设备。

    2.1 Float64

    Arduino不支持64位浮点数据类型。由make_library生成的序列化/反序列化代码将自动将64位浮点数转换为32位数据类型,但是,应注意,可能会导致精度损失!

    2.3 String

    为了节省宝贵的AVR内存,字符串不存储在消息实例内部,而是存储未签名的char *。这有两个影响:

    发布时,必须在其他位置分配存储字符串数据并设置指针:

     std_msgs::string str_msg; 
     unsigned char Hello [13] = "Hello world!" ; 
     str_msg.data = Hello;
    

    订阅包含字符串数据类型的消息时,不会从反序列化缓冲区中复制字符串本身。因此,尽管它在回调函数中有效,但在反序列化任何其他消息时它将消失。如果需要将字符串的值保留在回调之外,则必须手动将字符串复制到其他位置。

    2.4 数组

    数组与字符串具有相似的限制,但是,由于没有简单的方法来查找数组的终止(类似于在字符串末尾找到\ 0),因此我们需要指定数组的大小。一个额外的变量被添加到类定义中以完成此操作。例如,geometry_msgs / PoseArray声明为:

    Header header
    geometry_msgs/Pose[] poses
    

    在Arduino上,这将转换为一个类

    class PoseArray
    {
      Header header;
      int poses_length;
      Pose * poses;
    }
    

    因此,要发送数组消息,我们必须设置长度和指针。反序列化时,我们不能像字符串一样就地反序列化(因为消息的字节实际上是打包的,与以纯格式传递的字符串不同)。因此,反序列化功能将使用realloc()自动分配足够的存储空间,并在可能的情况下尝试重用内存位置,并且仅在收到的新消息大于先前的最大消息时才对其进行扩展。

    某些包含其他数组类型的数组类型将无法正确反序列化,因为子类型的所有元素都将指向同一内存。将来可能会解决此限制。

    3. 协议

    ROS-serial协议通过串口通信实现节点对节点通信。我们使用与标准ROS消息相同的序列化/反序列化,只需添加数据包头和尾即可,这使多个主题可以共享一个公共串行链接。这里描述了数据包头和包尾的详细协议信息,以及一些用于同步的特殊主题。

    串口通信协议采用小端模式,低位在前高位在后。

    3.1 封包格式:

    byte长度说明
    11起始位
    21协议版本
    32消息长度(len)
    51消息长度校验和
    62主题ID
    8len串口消息数据
    len + 11主题ID和数据校验和
    展开全文
  • 通过C#实现串口通信,里面的代码展示了如何监听计算机中的串口,解析数据或者发送数据,做串口开发的可以参考
  • 此程序是基于对话框的MFC程序,能够做到串口实时通信,并且将数据展示到编辑框,而且并对获得的数据进行解析,主要处理的数据是GPGGA报文,安装环境请对照安装包提示,有问题可以发邮件交流学习,liaoby@jmev.com
  • UART串口通讯协议解析

    万次阅读 2021-02-26 11:44:04
    UART串口通讯协议解析概述接口通信协议 概述 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART。它将要传输的资料在串行通信与并行通信之间加以转换。作为把并行输入信号转成串行...

    UART串口通讯协议解析

    概述

    通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),通常称作UART。它将要传输的资料在串行通信与并行通信之间加以转换。作为把并行输入信号转成串行输出信号的芯片,UART通常被集成于其他通讯接口的连结上。
    具体实物表现为独立的模块化芯片,或作为集成于微处理器中的周边设备。一般是RS-232C规格的,与类似Maxim的MAX232之类的标准信号幅度变换芯片进行搭配,作为连接外部设备的接口。在UART上追加同步方式的序列信号变换电路的产品,被称为USART(Universal Synchronous Asynchronous Receiver Transmitter)。

    接口

    在UART通信中,两个UART直接相互通信。发送UART将来自CPU等控制设备的并行数据转换为串行形式,并将其串行发送到接收UART,接收UART然后将串行数据转换回接收设备的并行数据。数据从发送UART的Tx引脚流向接收UART的Rx引脚,硬件连接比较简单,仅需要3条线,如果两个设备UART电平不一致需要转换电平再连接。

    TX - 数据发送接口
    RX - 数据接受接口
    GND - 保证两设备共地,有统一的参考平面
    在这里插入图片描述

    通信协议

    UART串口传输的数据被组织成数据包。每个数据包包含1个起始位,5至9个数据位,可选的奇偶校验位和1或1.5或2个停止位,协议如下:

    起始位数据位奇偶校验位停止位
    1bit5-9bit0-1bit1-2bit

    空闲位:UART协议规定,当总线处于空闲状态时信号线的状态为‘1’即高电平,表示当前线路上没有数据传输。

    起始位:开始进行数据传输时发送方要先发出一个低电平’0’来表示传输字符的开始。因为总线空闲时为高电平所以开始一次通信时先发送一个明显区别于空闲状态的信号即低电平。

    数据位:起始位之后就是要传输需要传输的数据,数据可以是5,6,7,8,9位,构成一个字符,一般都是8位。先发送最低位最后发送最高位,使用低电平表示‘0’高电平表示‘1’完成数据位的传输。
    奇偶校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验数据传送的正确性。校验位其实是调整个数,串口校验分几种方式:

    1. 无校验(no parity)
    2. 奇校验(odd parity):如果数据位中“1”的数目是偶数,则校验位为“1”,如果“1”的数目是奇数,校验位为“0”。
    3. 偶校验(even parity):如果数据为中“1”的数目是偶数,则校验位为“0”,如果为奇数,校验位为“1”。
    4. mark parity:校验位始终为1(不常用)。
    5. parity:校验位始终为0(不常用)。

    停止位:数据结束标志,可以是1位,1.5位,2位的高电平。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备之间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟的机会。停止位个数越多,数据传输越稳定,但是数据传输速度也越慢。
    传输方向:即数据是从高位(MSB)开始传输还是从低位(LSB)开始传输。

    波特率

    在电子通信领域,波特(Baud)即调制速率,指的是有效数据讯号调制载波的速率,即单位时间内载波调制状态变化的次数。
    波特率表示每秒钟传送的码元符号的个数,它是对符号传输速率的一种度量,它用单位时间内载波调制状态改变的次数来表示,1波特即指每秒传输1个符号。
    数据传输速率使用波特率来表示。单位bps(bits per second),常见的波特率9600bps、115200bps等等,其他标准的波特率是1200,2400,4800,19200,38400,57600。举个例子,如果串口波特率设置为115200bps,那么传输一个比特需要的时间是1/115200≈8.68us。

    示例

    设置115200,传输单个0x62的数据,使用示波器抓得的波形如下所示。
    在这里插入图片描述
    上图是uart协议传输一个0x62的数据,通过示波器的uart解码而得到的波形示意图,由于未设置奇偶校验位,故在上图未显示出来;比特流格式为LSB,故从低位开始传输,接收数据为0100 0110,实际的数据应该反过来,即0110 0010(0x62)。

    设置115200,传输0x55,0xAA,0x03等多个数据时,使用示波器抓得的波形如下所示。
    在这里插入图片描述

    上图是uart协议传输0x55,0xAA,0x03等多个数据,通过示波器的uart解码而得到的波形示意图,由于未设置奇偶校验位,故在上图未显示出来,设置的停止位为1位;比特流格式为LSB,故从低位开始传输,接收三个数据分别为1010 1010、0101 0101、1100 0000,实际的数据应该反过来,即0101 0101(0x55)、1010 1010(0xAA)、0000 0011(0x03)。

    最后

    以上的代码会在Q群里分享。QQ群:615061293。
    关注微信公众号『记贴』,持续更新文章和学习资料,可加作者的微信交流学习!
    在这里插入图片描述

    展开全文
  • android串口通信以及串口协议解析

    千次阅读 2018-06-19 13:42:01
    http://blog.csdn.net/junfeng120125/article/details/9328947一,android串口通信串口通信采用一个第三方开源项目,实现串口数据收发。1. 使用了http://code.google.com/p/android-serialport-api/的项目的...

    http://blog.csdn.net/junfeng120125/article/details/9328947

    一,android串口通信

    串口通信采用一个第三方开源项目,实现串口数据收发。
    1. 使用了http://code.google.com/p/android-serialport-api/的项目的serialport api和jni;
    2. 支持4串口同时收发,有定时自动发送功能,收发模式可选Txt或Hex模式;
    3.  n,8,1,没得选;
    4. 为减轻界面卡顿的情况,接收区的刷新采用单独的线程进行定时刷新;
    5. 发送区的数据以及一些设置项,在程序关闭时会自动保存,打开时自动载入;
    6. jni使用最新的NDKr8b重新编译了一下


    简单编写步骤:
    1.新建一个项目,自己起个名字
    2.直接复制serialport api和jni文件夹到新建的工程,如果不想自己编译jni,就连libs文件夹也一起复制
    3.去android官方网站下载NDK,解压,在CMD中转到jni目录,并执行 绝对路径\ndk-build
    4.自己再封装一个工具类或直接使用SerialPort类都行,举个直接使用的例:
    直接剽窃原项目的SerialPortActivity.java,并稍微改一下,重点改这里
    mSerialPort = mApplication.getSerialPort();
    这里可以改成
    new SerialPort(new File("/dev/s3c2410_serial0"), 9600, 0);//COM0,波特率9600
    5. SerialPortFinder的使用就没什么好讲的了,实例化后用.getAllDevicesPath()就能获取到所有设备了。
    其它如数据转换等请参考源码


    源码可以参考谷歌android-serialport-api例子 
    http://code.google.com/p/android-serialport-api/source/checkout 
    svn checkout http://android-serialport-api.googlecode.com/svn/trunk


    二,串口通信协议解析
    1.通信基本格式
    字段描述长度(字节)
    起始符0F,十六进制码 1
    信息类型一个字节,十六进制码(0F,F0,FF等保留码不用)1
    信息长度是信息内容的长度,ASCII码表示(0~9,A~F,最大长度为256)(例如长为11个,十六进制是0B,则两个字节就写0x30 0x42)。
    注:因为最大长度256不能满足有些指令的要求,所以对长度做了扩展,下面是扩展说明:
    如果第一个字节的最高位为1,则表示扩展长度。在扩展长度状态下,其他15个字节通过16进制大端模式来保存长度。比如:0x80 0x12表示长度为0x001 2,0x81 0x12表示长度为0x0112。2
    信息内容一组十六进制码 N
    校验一个字节,十六进制码,是自信息类型起至对象号止所有码的异或。1
    结束符F0,一个字节,十六进制码 (为了保证可靠性,车机下发的结束符为F0 FF)1

    2.协议解析

    [java]  view plain  copy
    1. /** 
    2.      * 读取终端设备数据 
    3.      * @author Administrator 
    4.      */  
    5.     private class ReadThread extends Thread {  
    6.   
    7.         @Override  
    8.         public void run() {  
    9.             super.run();  
    10.   
    11.             // 定义一个包的最大长度  
    12.             int maxLength = 2048;  
    13.             byte[] buffer = new byte[maxLength];  
    14.             // 每次收到实际长度  
    15.             int available = 0;  
    16.             // 当前已经收到包的总长度  
    17.             int currentLength = 0;  
    18.             // 协议头长度4个字节(开始符1,类型1,长度2)  
    19.             int headerLength = 4;  
    20.   
    21.             while (!isInterrupted()) {  
    22.                 try {  
    23.                     available = mInputStream.available();  
    24.                     if (available > 0) {  
    25.                         // 防止超出数组最大长度导致溢出  
    26.                         if (available > maxLength - currentLength) {  
    27.                             available = maxLength - currentLength;  
    28.                         }  
    29.                         mInputStream.read(buffer, currentLength, available);  
    30.                         currentLength += available;  
    31.                     }  
    32.                       
    33.                 }  
    34.                 catch (Exception e) {  
    35.                     e.printStackTrace();  
    36.                 }  
    37.   
    38.                 int cursor = 0;  
    39.                 // 如果当前收到包大于头的长度,则解析当前包  
    40.                 while (currentLength >= headerLength) {  
    41.                     // 取到头部第一个字节  
    42.                     if (buffer[cursor] != 0x0F) {  
    43.                         --currentLength;  
    44.                         ++cursor;  
    45.                         continue;  
    46.                     }  
    47.                       
    48.                     int contentLenght = parseLen(buffer, cursor, headerLength);  
    49.                     // 如果内容包的长度大于最大内容长度或者小于等于0,则说明这个包有问题,丢弃  
    50.                     if (contentLenght <= 0 || contentLenght > maxLength - 5) {  
    51.                         currentLength = 0;  
    52.                         break;  
    53.                     }  
    54.                     // 如果当前获取到长度小于整个包的长度,则跳出循环等待继续接收数据  
    55.                     int factPackLen = contentLenght + 5;  
    56.                     if (currentLength < contentLenght + 5) {  
    57.                         break;  
    58.                     }  
    59.   
    60.                     // 一个完整包即产生  
    61.                     // proceOnePacket(buffer,i,factPackLen);  
    62.                     onDataReceived(buffer, cursor, factPackLen);  
    63.                     currentLength -= factPackLen;  
    64.                     cursor += factPackLen;   
    65.                 }  
    66.                 // 残留字节移到缓冲区首  
    67.                 if (currentLength > 0 && cursor > 0) {  
    68.                     System.arraycopy(buffer, cursor, buffer, 0, currentLength);  
    69.                 }  
    70.             }  
    71.         }  
    72.     }  
    73.   
    74.     /** 
    75.      * 获取协议内容长度 
    76.      * @param header 
    77.      * @return 
    78.      */  
    79.     public int parseLen(byte buffer[], int index, int headerLength) {  
    80.   
    81. //      if (buffer.length - index < headerLength) { return 0; }  
    82.         byte a = buffer[index + 2];  
    83.         byte b = buffer[index + 3];  
    84.         int rlt = 0;  
    85.         if (((a >> 7) & 0x1) == 0x1) {  
    86.             rlt = (((a & 0x7f) << 8) | b);  
    87.         }  
    88.         else {  
    89.             char[] tmp = new char[2];  
    90.             tmp[0] = (char) a;  
    91.             tmp[1] = (char) b;  
    92.             String s = new String(tmp, 02);  
    93.             rlt = Integer.parseInt(s, 16);  
    94.         }  
    95.   
    96.         return rlt;  
    97.     }  
    98.   
    99. protected void onDataReceived(final byte[] buffer, final int index, final int packlen) {  
    100.         System.out.println("收到信息");  
    101.         byte[] buf = new byte[packlen];  
    102.         System.arraycopy(buffer, index, buf, 0, packlen);  
    103.         ProtocolAnalyze.getInstance(myHandler).analyze(buf);   
    104.     }  

    展开全文
  • 后来又需要调试UART串口,将MCU传输的协议数据分参数在桌面打印出来,这样应该利于第一时间检查协议数据每一个参数是否满足要求。 这个现有在串口调试助手中尽管可以打印,可以过滤,但是并不能满足自定义的个性要求...
  • 串口通信协议源代码篇一:串口通信源代码#include#define uchar unsigned charuchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uchar a,b,flag;.//定义...
  • 串口通信协议简介:https://blog.csdn.net/Chen_qi_hai/article/details/96473076 串口通讯分层可以分: (1)物理层 用于支撑数据的传输:如发送和接收 (2)协议层 用于对传输的数据进行定义:如哪些字节...
  • stm32串口通信协议简单教程,stm32串口通信协议简单教程
  • 串口协议解析方法

    2021-06-04 23:29:33
    这个逻辑就比较yani
  • 串口通信协议编制原理和格式

    千次阅读 2019-08-12 19:33:23
    在用户层的串口通信协议中,一般是围绕发送方如何建立数据包和接收方如何处理数据包,并从数据包中提取出我们关心的信息。有几个原则需要我们严格遵守: 1)数据包必须有包头 包头是供接收方判断一个数据包开始传输的...
  • 关于串口通信协议解析,该怎么解决 www.MyException.Cn 发布于:2012-01-22 22:38:43 浏览:184次 0 关于串口通信协议解析 帧头标志 版本号 类别 帧头校验和 帧号 数据总长度 保留 ...
  • 基于32位MCU,解析GPS协议完整代码
  • 别找了,本人搜集的,史上最全,另外还有惊喜,长期积累的结果
  • STM32串口通信协议和状态机模式程序,亲测能用。内有详细的讲解文档,很好的学习资料。
  • 串口通信之数据包解析

    万次阅读 2017-09-30 09:56:06
    //解析协议的,提取数据并将16进制转换为10进制, Ctrl_Pitch = (float)(((short)((buffer[6] ) | buffer[7])) / 100.0); Ctrl_Yaw = (float)(((short)((buffer[8] ) | buffer[9])) / 10.0); data_1_catched = true;...
  • linux串口通信协议编程详解

    万次阅读 热门讨论 2014-09-17 17:07:25
    linux串口通信协议编程详解: 1.
  • 数字示波器的发展极大的降低了低速总线调试的难度,传闻近日有一台示波器可以直接破解30多种通信协议,这是怎么回事呢?下面就来看看随着示波器的发展,协议解码出现了哪些变化吧
  • 在简单的认识及使用串口通信之后,在实际应用中应该是配合硬件,和负责硬件通信的同事沟通好通信协议,来进行设备的控制及数据获取。 常用的串行通信协议有TTL电平(普通MCU芯片输出的串口电平)、RS232(工业上常用...
  • 一个基于Qt的串口通信协议解析和串口通信的程序,能实现串口的读写,和自定串口协议的解析,十分方便。
  • STM32串口通信协议

    2021-07-28 06:51:26
    好文网为大家准备了关于STM32串口通信协议范文,好文网里面收集了五十多篇关于好STM32串口通信协议好文,希望可以帮助大家。更多关于STM32串口通信协议内容请关注好文网篇一:STM32串口中断接收方式详细比较串口中断...
  • 关注、星标公众号,直达精彩内容作者 | strongerHuang微信公众号|嵌入式专栏有一些初学者总觉得通信协议是一个很复杂的知识,把它想的很高深,导致不知道该怎么学。同时,偶尔有读...
  • DSP串口通信协议

    千次阅读 2019-12-25 16:47:45
    DSP串口通信协议 功能:实现串口调试助手发送区发送8个字节,接受区收到8个字节;当发送区小于8个字节,接收区等待收到8个后才显示8个字节;当发送区大于8个字节,则接收前8个字节。 #include "DSP2833x_Device.h...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,732
精华内容 4,292
关键字:

串口通信协议解析