精华内容
下载资源
问答
  • 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模型 输出缓冲区大小 发布者/订阅者
    ATMEGA168 150/150字节 6/6
    ATMEGA328P 280/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 长度 说明
    1 1 起始位
    2 1 协议版本
    3 2 消息长度(len)
    5 1 消息长度校验和
    6 2 主题ID
    8 len 串口消息数据
    len + 1 1 主题ID和数据校验和
    展开全文
  • 在IAR中用寄存器实现STM8S003串口通信,在接收中断中解析通信协议通信协议为两位数据作为头,两位数据作为尾。数据长度为任意长。并且允许发送的数据可以和协议头尾数据相同。大大减小了误判和漏判的几率。
  • vb串口通信协议解析

    2015-06-13 14:51:06
    2,回复给我的代码“AA 12 40 00 43 44 10 00 00 AA AA 06 AF 10 00 00 AA xx 6F 55 73 55 ”,然后对这个xx进行解析。 主发 AA 为起始帧 10 00 00 AA 为表ID, 0x2F 为指令码,只用于测试 接收: xx 为测试结果 ...
  • 一,android串口通信串口通信采用一个第三方开源项目,实现串口数据收发。1. 使用了http://code.google.com/p/android-serialport-api/的项目的serialport api和jni;2. 支持4串口同时收发,有定时自动发送功能,...

    一,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, 0, 2);  
      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.     }  

    转载于:https://www.cnblogs.com/cliuwei/p/5799915.html

    展开全文
  • 关于串口通信协议解析,该怎么解决 www.MyException.Cn 发布于:2012-01-22 22:38:43 浏览:184次 0 关于串口通信协议解析 帧头标志 版本号 类别 帧头校验和 帧号 数据总长度 保留 ...

    关于串口通信协议的解析,该怎么解决

    串口通信协议
        由于本系统采用非规范式输入,导致一帧数据可能分成几次接收。为了能够判断一帧数据是否接收完整,本系统制定了一套特殊的串口通信协议,如附图所示。

    附图  通信协议定义

        在本系统的串口通信协议中,一帧数据包括了帧头、数据长度、数据内容和数据校验这四部分。数据长度、数据内容和数据校验为有效数据区。帧头长度为两个字节,为0xaa、0xbb。当接收到相邻的两个字节为0xaa和0xbb数据时,认为一帧数据开始。数据长度为两个字节,是数据内容的字节数和数据校验的字节数之和。数据校验采用crc16的校验方式,对数据长度和数据内容进行校验,占两个字节。数据内容的最大字节数为65533,即一帧数据最多可以传送65533个字节的数据。
        待发送的数据不可避免地会出现相邻的两个字节为0xaa和0xbb的情况,如不对此中情况进行处理即发送数据,则一帧数据会被误判为两帧。针对这一问题,本系统提出了一种行之有效的解决方法。数据长度、数据内容以及数据校验这三部分数据中一旦出现0xaa,则重复一次0xaa。重复的0xaa不计入数据长度也不进行数据校验。
        接收数据时进行逆向操作。首先根据接收到的两个字节判断是否为帧头,如果是则代表一帧数据开始,继续接收余下的数据,否则循环检测。在接收数据时根据数据长度判断一帧数据是否接收完毕,接收完一帧数据后进行crc校验,校验正确则进行数据处理,否则丢弃这帧数据。在有效数据区内如果出现两个相邻字节为0xaa的数据,则只取其中的一个字节。


    通常是这样处理的:
    1.设置一个循环缓冲区.
    2.串口接收的数据先存入循环缓冲区中,修改写指针位置.
    3.设置协议对象,扫描循环缓冲区中的特征字节(一般是报头).找到了然后看循环缓冲区读写指针的距离是否够一帧数据.
    4.如果够一帧长度,则从报头按照报文长度进行数据校验和解析.
    5.修改读指针位置.
    注意,你可以通过单独的线程处理串口数据写入循环缓冲区.


    www.MyException.Cn   发布于:2012-01-22 22:38:43   浏览:184次
    0
    关于串口通信协议的解析
    帧头标志 版本号 类别 帧头校验和 帧号
    数据总长度 保留
    数据CRC校验 数据区
      数据区

    以上是一个帧的大致结构,在该协议中有以下七类帧,数据帧、压缩数据帧数据应答帧、检测帧、检测应答帧、系统错误帧、ABORT帧,这里面还有接受和发送的之间的同步,异步的问题。帧与帧之间的状态转化等等!

    1.实现串口通信三种方式:串口控件 ,串口类,api函数。用那种实现 要好点?

    2.我的问题的 怎么将数据组织成一帧,接受怎么将帧解析出来?

    ------解决方案--------------------
    1、API,灵活
    2、定义结构,C字符串操作,#program pack(1)即可 
    ------解决方案--------------------
    不用控件,自己用api来实现 
    ------解决方案--------------------
    1.建议使用API或串口类都可以,控件的发布太麻烦
    2.定义两个函数一个封装成帧一个拆帧,串口接受数据的时候判断,当发现接受完一帧就去拆帧解析数据就OK了 
    ------解决方案--------------------
    可以用帧尾或帧的结束符判断是否接收完一帧的,接收完一帧,就进入拆帧函数,根据你的帧的类别进行拆帧 
    ------解决方案--------------------
    在网上找一个串口类吧。很多的。
    至少怎么解释数据,那是基础知识,你应该随便去找本C的基础书看,而不是跑这来问。

    ------解决方案--------------------
    最终发往串口的是字节流。结构体定义与帧格式一致。发送时将结构体转成byte直接往串口发。收的时候策略时根据帧头来,读到帧头后,根据帧格式来得到帧长度。不足长度时,暂存起来等待下次接收(你不可能每次恰好接收一帧吧),下次接收时和暂存区域合并,再次判断帧长度直到足够完整一帧了(若超过完整一帧长,将下一个帧头后内容暂存),完整后开始解析。若数据量较大,建议另开一线程专门解析。线程同步用加锁的方式,取得完整帧加到解析线程缓冲区,解析线程从缓冲区读帧解析,注意线程同步,避免同时操作缓冲区引起异常。。。。。说了一大堆,明白? 
    ------解决方案--------------------
    API和串口类都可以,
    解析的话可以先读取了固定长度的部分,也就是数据区前面........然后校验帧头,读取数据区长度,把数据区读入。然后校验数据区............ 
    ------解决方案--------------------
    重要的是接受处理!

    每次接受的数据都存到buffer里,
    然后根据串口协议从头开始找, 找到第一完整的帧, 解析, 清理buffer中这个帧的数据.

    至于解析过程:
    首先判断帧头, 不对扔, 找到帧头后根据长度和校验位取出一个完整的包, 如果长度不够, 等待下次数据来后重新解析.

    如何处理不定长数据的接收

    在处理串口通讯时,经常会遇到不定长数据的接收。由于通讯任务不同及编程要求的差异所以采用的方法也有所不同。本文就此问题进行探讨。不定长数据从数据格式上分,可分为有格式和无格式。

    一、无格式不定长数据的接收
    这种格式在实际串口通讯中用得不多,一般只用传送字符串数据。问题在于怎么判断接收结束。一般用时间延迟的方法解决。
    A、对于非握手式通讯,可用一个定时器定时轮循接收,并假定每个轮循接收完成。用ONCOMM事件接收也可,只是不如定时器定时轮循接收简便。
    B、对于握手方式通讯,可用直接轮循法提高接收的准确性。下面是实现此法的函数:

    Function sComm(sCommand As String, comReceive As MSComm) As String
    Dim nReceiveCount As Integer
    If comReceive.PortOpen = False Then
    comReceive.PortOpen = True
    End If

    comReceive.Output = sCommand

    Do
    nReceiveCount = comReceive.InBufferCount
    sleep (2) 'API 函数,挂起当前进程一段时间
    Loop Until comReceive.InBufferCount = nReceiveCount
    If comReceive.PortOpen = True Then
    sComm = comReceive.Input
    End If
    End Function
    注:此函数参照了xth一文。
    此法一般是能确保数据接收的正确,但由于WINDOWS是多任务操作系统,当有耗时的进程运行时会丢失数据。如果系统会出现这种情况,可增大函数sleep()的参数值。

    二、不定长格式数据的接收
    对于不定长数据接收最好的方法是制定通讯协议,比如定义开始字符和结束字符。由于单片机系统通讯一般不太复杂,没必要去制定一套象通用计算机间通讯的协议,而根据单片机系统的大小和性能要求制定通讯协议。实际上为便于交流、维护以及一致性,可制定一套可伸缩的通讯协议。定义了开始字符和结束字符就容易实现不定长格式数据通讯,但在实际通讯编程还是容易出现一些比较隐蔽的通讯错误。下面就常用方法分别进行分析。
    A、定时器轮循法。
    假定每个轮循期数据接收完毕,并在每个轮循期处理数据,由于有开始字符和结束字符很容易确定接收数据的完整性。好象合理设定轮循时间值就万无一失了,但被动接收数据时无论如何也找不合适的轮循时间值,因为启动定时器和数据到来基本不同步,这就会出现一次发送的数据被分在两个轮循期接收,所以被动接收数据时不能假定每个轮循期数据接收完毕。在接收到结束字符后才确定一次数据接收完毕就可解决此问题。
    B、OnComm事件法。
    方法和定时器轮循法基本相同,因为每次OnCommg事件也只能接收到一部分数据。在VB的在线帮助中这样注解“设置 Rthreshold 为 1,接收缓冲区收到每一个字符都会使 MSComm 控件产生 OnComm 事件。”。但实际上OnComm事件并不是每收到一个字符便触发一次 OnComm 事件。OnComm事件是在缓冲区收到几个甚至几十个字节数据后才被触发的。版主认为这是WINDOWS多任务使操作系统不能实时响应造成的。如果要在每次OnComm事件接收一个字符似乎可设INPUTLEN属性为1,但实际行不通。VB在线帮助中“有该属性在从输出格式为定长数据的机器读取数据时非常有用”的注解,好象在说对定长字符有效,但版主发现INPUTLEN设为16,接收16个字符定长数据时却被当作两次接收了,一次12个,一次4个。建议在OnComm事件中接收数据要定义通讯协议并检测数据的完整性。 对于不定长格式数据的接收程序员更喜欢定时器轮循法,也许OnComm事件不好控制吧。
    对于不定长数据的接收,最佳方法可能是在OnComm事件中启动定时器轮循接收,并同时停止OnComm事件的触发,接收完毕后或超时开启OnComm事件。 


    展开全文
  • 串口通信协议简介:https://blog.csdn.net/Chen_qi_hai/article/details/96473076 串口通讯分层可以分: (1)物理层 用于支撑数据的传输:如发送和接收 (2)协议层 用于对传输的数据进行定义:如哪些字节...

    引用自:

    串口通信协议简介:https://blog.csdn.net/Chen_qi_hai/article/details/96473076 

    串口通讯分层可以分:

    (1)物理层

               用于支撑数据的传输:如发送和接收

    (2)协议层

              用于对传输的数据进行定义:如哪些字节表示什么意思,这样人们就可以根据定义的字节进行数据的使用

     

    但是最主要的是数据接收的完整性的判断和数据合法性的校验:

    这两者都是根据具体的协议的定义来进行判断,因为协议中是有判断的标志(包头、包尾等)或校验位的计算方式

     

     

    展开全文
  • Android之使用串口通信协议解析

    千次阅读 2017-06-04 10:01:24
    特别声明:尊重原创,原文链接:...串口通信采用一个第三方开源项目,实现串口数据收发。 1. 使用了http://code.google.com/p/android-serialport-api/的项目的serialport api和jni; 2. 支持4串
  • UART串口通讯协议解析

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

    千次阅读 2013-12-17 10:03:24
    android串口通信以及串口协议解析     分类:  java  android 2013-07-15 10:10  694人阅读  评论(3)  收藏  举报  一,android串口通信 串口通信采用一个第三方开源项目,实现
  • 串口通信指串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。物理接口标准1.串行通信接口的基本任务(1)实现数据格式化:因为来自CPU的是...
  • 想不到第一次接触串口就要去写一个... 简单的来说用户层的串口通信协议就是如何定义一个数据包格式,发送端按照规定的数据包格式发送出去,接收端按照规定的数据包格式解析出正确的数据。  那为什么又要在用...
  • 目前在把串口通信的代码整合到团队的类库中(把串口通信与网口Soket通讯整合起来,后面只需要配置参数,就可实现网络与串口通讯的转换),故C#串口编程计划的最后一篇图文“C#通讯类库框架”还在完善中。做通信的...
  • 最近做了几个机型的售货机以及自动贩卖机相关的串口通讯协议对接,包括ADH815、新众聚联标准通信协议TF-SCP 等,如果有需要的可以联系我...
  • 在简单的认识及使用串口通信之后,在实际应用中应该是配合硬件,和负责硬件通信的同事沟通好通信协议,来进行设备的控制及数据获取。 常用的串行通信协议有TTL电平(普通MCU芯片输出的串口电平)、RS232(工业上常用...
  • FPGA串口通信要想应用在实际的工业现场,需要一整套完整的协议,来确保数据传输的可靠性和系统的稳定性。基于协议,进行串口指令解析是控制的关键,对于串口指令解析,有两种方式:逻辑解析和软硬核(我用的Altera的...
  •  private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)//串口数据接收事件  {  int n = mySerialPort.BytesToRead;//获取接收缓冲区读取的字节数;  byte[] buf = new ...
  •  //<协议解析>  //因为恢复的代码在finally中。你可以直接的return   if(line[0] != '$') return;//虽然可能有点垃圾,但是数据不重要。直接丢弃就可以了。后续的都是对的  int star = line....
  • 本文主要介绍如何使用arduinojson库进行arduino的串口通信协议构建。1.环境介绍首先,JSON指的是JavaScript对象表示法(JavaScriptObjectNotation)。json语法的特性:JSON是轻量级的文本数据交换格式JSON独立于语言*...
  • 1.一般自定义的串口协议  串口传输接口底层是按位(bit)发送的,上层是按byte发送和接收的,但协议为了方便描述,每个byte用十六进制数(0x00~0xFF)表示,范相当于十进制的0~255,而byte为八位且是有符号类型,...
  • 串行通信接口标准经过使用和发展,目前已经有几种。但都是在RS-232标准的基础上经过改进而形成的。所以,以RS-232C为主来讨论。 在讨论RS-232C接口标准的内容之前,先说明两点。首先,RS-232-C标准最初是远程通信...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 237
精华内容 94
关键字:

串口通信协议解析