Arduino 串行通讯

作者: import_hello | 来源:发表于2018-05-28 16:43 被阅读0次

    本文翻译自 Arduino 串行通讯的官方文档。

    本文的最新版本位于:https://github.com/iwhales/arduino_notes
    转载请注明出处:https://www.jianshu.com/u/5e6f798c903a

    1. 简介

    Serial Communication URL

    Arduino 板卡使用 Serial 与电脑或其它设备进行通讯。所有 Arduino 板卡至少拥有一个串行端口(也称URAT 或USART):Serial。Serial 工作于数字引脚 0 (RX) 和 1 (TX) ,同时也通过 USB 与电脑通讯。因此,如果需要使用 Serial 功能,便不能同时将引脚 0 和 1 用作数字输入和输出。 我们可以通过 Arduino IDE 内置的串口监视器与 Arduino 板卡进行通讯。在 IDE 的工具栏中点击串口监视器的图标,并将波特率设置为 begin() 的实参值,便可与 Arduino 进行串口通讯。

    位于 TX/RX 引脚上的串行通讯采用 TTL 电平(根据电路板的设计方式,可能采用 5V 或 3.3V)。请勿将 TX/RX 引脚直接连接到 RS232 串行端口;RS232 的工作电压是 +/- 12V,可能会对 Arduino 造成损坏。

    Arduino Mega 拥有三个额外的串行端口: Serial1 位于 19 (RX) 和 18 (TX) 引脚;Serial2 位于 17 (RX) 和 16 (TX) 引脚;Serial3 位于 15 (RX) 和 14 (TX) 引脚。如果想使用这些引脚与 PC 进行通讯,则需要自行提供 USB-to-serial 适配器 —— 因为这些额外的串行端口并没有被连接到 Mega 自带的 USB-to-serial 适配器上。如果想要通过这些额外的串行端口与外部 TTL 串行设备进行通讯,那么需要将外部设备的 TX 和 RX 引脚分别连接至 Mega 的 RX 和 TX 引脚,同时将 Mega 的地线与外部设备的地线直接相连。

    Arduino Due 拥有三个额外的 3.3V TTL 串行端口:Serial1 位于 19 (RX) 和 18 (TX) 引脚;Serial2 位于 17 (RX) 和 16 (TX) 引脚;Serial3 位于 15 (RX) 和 14 (TX) 引脚。引脚 0 和 1 同样也被连接到了 ATmega16U2 USB-to-TTL 串口芯片的对应引脚,用于连接 USB 调试端口。此外,SAM3X 芯片还拥有一个原生 USB-serial 端口——SerialUSB' 。

    Arduino Leonardo 在引脚 0 (RX) 和 1 (TX) 上使用 Serial1 进行通讯,Serial1 也是 5V TTL。Serial 用作 USB CDC 通讯。欲了解更多信息,请参阅 Leonardo 的相关页面。

    2. 函数

    if (Serial)

    • 描述

      用于指示指定的串口是否已准备就绪。 在 Leonardo 上,if(Serial) 用于指示 USB CDC 串行连接是否开放。对于所有其他情况,包括 Leonardo 的 if (Serial1) ,将始终返回 true

    • 语法

      All boards:

      if (Serial)

      Arduino Leonardo specific:

      if (Serial1)

      Arduino Mega specific:

      if (Serial1) if (Serial2) if (Serial3)

    • 参数

      Nothing

    • 返回值

      boolean:如果指定串口可用,将返回 true 。仅在 Leonardo 的 USB CDC 串行连接准备好之前进行查询时,会返回 false

    • 示例代码

      void setup() {
       //初始化串行端口,并等待端口开启:
        Serial.begin(9600);
        while (!Serial) {
          ; // 等待串口连接。需要原生USB
        }
      }
      
      void loop() {
       //proceed normally
      }
      

    Serial.available()

    • 描述

      获取可以从串行端口读取的可用字节(字符)数。该数据表示已经到达并存储在串行接受缓冲区中的字节数——接受缓冲区可存储 64 字节的数据。

      available() 继承自 Stream utility class。

    • 语法

      Serial.available()

      Arduino Mega only:

      Serial1.available()

      Serial2.available()

      Serial3.available()

    • 参数

      Nothing

    • 返回值

      返回可供读取的字节数

    • 示例代码

      以下代码将返回通过串口接受的字符

      int incomingByte = 0;   // for incoming serial data
      
      void setup() {
          Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
      }
      
      void loop() {
      
          // reply only when you receive data:
          if (Serial.available() > 0) {
              // read the incoming byte:
              incomingByte = Serial.read();
      
              // say what you got:
              Serial.print("I received: ");
              Serial.println(incomingByte, DEC);
          }
      }
      

      Arduino Mega 的示例:该代码可以将从 Arduino Mega 的某个串口接受到的数据发送到另一个串口。利用这段代码可将串行设备通过 Arduino 连接到电脑。

      void setup() {
        Serial.begin(9600);
        Serial1.begin(9600);
      
      }
      
      void loop() {
        // read from port 0, send to port 1:
        if (Serial.available()) {
          int inByte = Serial.read();
          Serial1.print(inByte, DEC);
      
        }
        // read from port 1, send to port 0:
        if (Serial1.available()) {
          int inByte = Serial1.read();
          Serial.print(inByte, DEC);
        }
      }
      

    Serial.availableForWrite()

    • 描述

      获取可用于写入串行缓冲区的字节(字符)数,并且不会阻塞写入操作。

    • 语法

      Serial.availableForWrite()

      Arduino Mega only:

      Serial1.availableForWrite() Serial2.availableForWrite() Serial3.availableForWrite()

    • 参数

      Nothing

    • 返回值

      可用于写操作的字节数

    Serial.begin()

    • 描述

      设置串行数据传输的速率,单位是 bits/秒 (baud 波特)。与计算机进行通讯时,可使用以下速率中的一个:300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200。当然,你可以指定其它速率 —— 例如,通过引脚 0 和 1 连接一个需求特定波特率的元件时。

      可选的第二参数用于配置数据位数、奇偶校验和停止位。默认是 8 数据位、无奇偶校验、1 位停止位。

    • 语法

      Serial.begin(speed) Serial.begin(speed, config)

      Arduino Mega only:

      Serial1.begin(speed) Serial2.begin(speed) Serial3.begin(speed) Serial1.begin(speed, config)``Serial2.begin(speed, config) Serial3.begin(speed, config)

    • 参数

      speed: bits/秒 (baud) - long

      config: 设置数据位数、奇偶校验和停止位。 有效值如下

      SERIAL_5N1 SERIAL_6N1 SERIAL_7N1 SERIAL_8N1 (the default) SERIAL_5N2 SERIAL_6N2 SERIAL_7N2 SERIAL_8N2``SERIAL_5E1 SERIAL_6E1 SERIAL_7E1 SERIAL_8E1 SERIAL_5E2 SERIAL_6E2 SERIAL_7E2 SERIAL_8E2 SERIAL_5O1``SERIAL_6O1 SERIAL_7O1 SERIAL_8O1 SERIAL_5O2 SERIAL_6O2 SERIAL_7O2 SERIAL_8O2

    • 返回值

      Nothing

    • 示例代码

      void setup() {
          Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
      }
      
      void loop() {}
      

      Arduino Mega example:

      // Arduino Mega using all four of its Serial ports
      // (Serial, Serial1, Serial2, Serial3),
      // with different baud rates:
      
      void setup(){
        Serial.begin(9600);
        Serial1.begin(38400);
        Serial2.begin(19200);
        Serial3.begin(4800);
      
        Serial.println("Hello Computer");
        Serial1.println("Hello Serial 1");
        Serial2.println("Hello Serial 2");
        Serial3.println("Hello Serial 3");
      }
      void loop() {}
      

    Serial.end()

    • 描述

      禁用串行通讯,并允许 RX 和 TX 引脚被用作通用输入和输出。再次调用 Serial.begin() 可重新启用串行通讯,启用后 RX 和 TX 便不能再被用作通用输入和输出。

    • 语法

      Serial.end()

      Arduino Mega only:

      Serial1.end() Serial2.end() Serial3.end()

    • 参数

      Nothing

    • 返回值

      Nothing

    Serial.find()

    • 描述

      需要注意,流解析只过一遍,没有办法折返回去试图发现或得到更多东西。

      Serial.find( ) 从串口缓冲区中读取数据直到给定长度的目标字符串被发现为止。如果发现目标字符串将返回 true;如果超时则返回 false。 假如目标字符串被发现,该函数返回 true,如果超时则为 false。

      Serial.flush() 继承自 Stream utility class。

    • 语法

      Serial.find(target)

    • 参数

      target : 要搜索的字符串(char)

    • 返回值

      boolean

    Serial.findUntil()

    • 描述

      Serial.findUntil() 从串口缓冲区中读取数据直到给定长度的目标字符串,或终止字符串被发现为止。 如果发现目标字符串将返回 true;如果超时则返回 false

      Serial.findUntil() 继承自 Stream utility class.

    • 语法

      Serial.findUntil(target, terminal)

    • 参数

      target : 要搜索的字符串(char) terminal : 终止搜索的字符串(char)

    • 返回值

      boolean

    Serial.flush()

    • 描述

      等待传出的串行数据完成传输(在 Arduino 1.0 之前,这反而会移除任何已缓存的传入数据 )。如果需要丢弃接受缓冲区中的所有数据,可使用 while(Serial.read( ) >= 0);

      flush() 继承自 Stream utility class.

    • 语法

      Serial.flush()

      Arduino Mega only:

      Serial1.flush() Serial2.flush() Serial3.flush()

    • 参数

      Nothing

    • 返回值

      Nothing

    Serial.parseFloat()

    • 描述

      Serial.parseFloat() 返回串行缓冲区中第一个有效的浮点数。解析时,非数值(或减号)字符会被跳过。parseFloat()会在第一个非浮点数值处终止。

      Serial.parseFloat() 继承自 Stream utility class.

    • 语法

      Serial.parseFloat()

    • 参数

      Nothing

    • 返回值

      float

    Serial.parseInt()

    • 描述

      在输入串行数据中查找下一个有效的整型。

      stream.parseInt() 继承自 Stream utility class。

      特点:

      • 非数值或负号的初始字符会被跳过;
      • 如果在(可配置)超时值内没有读取到字符,或是读取到了一个非数值字符,解析将停止。
      • 如果发生超时( Serial.setTimeout() )时,并没有读取到有效数值,将会返回 0;
    • 语法

      Serial.parseInt() Serial.parseInt(char skipChar)

      Arduino Mega only:

      Serial1.parseInt() Serial2.parseInt() Serial3.parseInt()

    • 参数

      skipChar:在搜索时,用于跳过指定字符。例如用来跳过千位分隔符,如 32,767 将被解析为 32767。

    • 返回值

      long :下一个有效整型

    Serial.peek()

    • 描述

      返回输入串行数据的下一个字节(字符),但不会从内部串行缓冲区移除该字节。也就是说,在下一次调用 read()之前,如果连续调用 peek() 的话,将返回相同的字符。

      peek() 继承自 Stream utility class.

    • 语法

      Serial.peek()

      Arduino Mega only:

      Serial1.peek() Serial2.peek() Serial3.peek()

    • 参数

      Nothing

    • 返回值

      输入串行数据的第一个可用字节(如果没有数据可用,则返回 -1 )- int

    Serial.print()

    • 描述

      将数据以人类可读的 ASCII 文本打印到串口。该命令有多重形式。对于数值,会使用 ASCII 字符打印其每个数位。对于浮点数,同样会使用 ASCII 打印其每个数位,默认包含两位小数。Bytes 会以单个字符发送。字符和字符串按原样发送。例如 -

      • Serial.print(78) gives "78"
      • Serial.print(1.23456) gives "1.23"
      • Serial.print('N') gives "N"
      • Serial.print("Hello world.") gives "Hello world."

      可选的第二参数用于指定底数(格式),允许的值有:BIN(binary, or base 2), OCT(octal, or base 8), DEC(decimal, or base 10), HEX(hexadecimal, or base 16)。对于浮点数,第二个参数用于指定小数的位数。例如 -

      • Serial.print(78, BIN) gives "1001110"
      • Serial.print(78, OCT) gives "116"
      • Serial.print(78, DEC) gives "78"
      • Serial.print(78, HEX) gives "4E"
      • Serial.println(1.23456, 0) gives "1"
      • Serial.println(1.23456, 2) gives "1.23"
      • Serial.println(1.23456, 4) gives "1.2346"

      可以将基于 flash-memory 的字符串通过 F() 包装(wrapping)后,传递到 Serial.print() 中。例如

      Serial.print(F(“Hello World”))

      发送单个 byte,需使用 Serial.write()

    • 语法

      Serial.print(val)

      Serial.print(val, format)

    • 参数

      val: 用于打印输出的值 - 任何类型的数据。

    • 返回值

      size_t: print() 返回向外写出的字节数,但可选择是否需获取该返回值。

    • 示例代码

      /*
      Uses a FOR loop for data and prints a number in various formats.
      */
      int x = 0;    // variable
      
      void setup() {
        Serial.begin(9600);      // open the serial port at 9600 bps:
      }
      
      void loop() {
        // print labels
        Serial.print("NO FORMAT");       // prints a label
        Serial.print("\t");              // prints a tab
      
        Serial.print("DEC");
        Serial.print("\t");
      
        Serial.print("HEX");
        Serial.print("\t");
      
        Serial.print("OCT");
        Serial.print("\t");
      
        Serial.print("BIN");
        Serial.println("\t");           // carriage return after the last label
      
        for(x=0; x< 64; x++){    // only part of the ASCII chart, change to suit
      
          // print it out in many formats:
          Serial.print(x);       // print as an ASCII-encoded decimal - same as "DEC"
          Serial.print("\t\t");  // prints two tabs to accomodate the label lenght
      
          Serial.print(x, DEC);  // print as an ASCII-encoded decimal
          Serial.print("\t");    // prints a tab
      
          Serial.print(x, HEX);  // print as an ASCII-encoded hexadecimal
          Serial.print("\t");    // prints a tab
      
          Serial.print(x, OCT);  // print as an ASCII-encoded octal
          Serial.print("\t");    // prints a tab
      
          Serial.println(x, BIN);  // print as an ASCII-encoded binary
          //                             then adds the carriage return with "println"
          delay(200);            // delay 200 milliseconds
        }
        Serial.println("");      // prints another carriage return
      }
      
      
    • 注意和警告

      从 1.0 版本开始,串行传输是异步的;Serial.print() 将在任何字符被发送前返回。 Serial.print()Serial.write() 不会阻塞程序。在 1.0 之前,代码会等到所有的字符发送之后才返回。在 1.0 及其以后,Serial.write()会在后台中进行(使用了终端处理程序),这使得程序会理解恢复,并执行后续代码。这种方式通常可使程序更加快捷,但是入股需要等待所有字符发送完毕。可以通过在 Serial.write() 之后调用 Serial.flush() 来实现。

    Serial.println()

    • 描述

      将数据以人类可读的 ASCII 文本打印到串口,并在文本结尾添加回车字符 (ASCII 13, or '\r') 和换行字符 (ASCII 10, 或 '\n')。该命令采用与 Serial.print() 相同的格式。

    • 语法

      Serial.println(val)

      Serial.println(val, format)

    • 参数

      val: 用于打印输出的值 - 任何类型的数据。

      format: 指定底数(对于整形数据类型)或小数位数(对于浮点类型)

    • 返回值

      size_t: println()返回向外写出的字节数,但可选择是否需获取该返回值

    • 示例代码

      /*
       Analog input reads an analog input on analog in 0, prints the value out.
       created 24 March 2006
       by Tom Igoe
       */
      
      int analogValue = 0;    // variable to hold the analog value
      
      void setup() {
        // open the serial port at 9600 bps:
        Serial.begin(9600);
      }
      
      void loop() {
        // read the analog input on pin 0:
        analogValue = analogRead(0);
      
        // print it out in many formats:
        Serial.println(analogValue);       // print as an ASCII-encoded decimal
        Serial.println(analogValue, DEC);  // print as an ASCII-encoded decimal
        Serial.println(analogValue, HEX);  // print as an ASCII-encoded hexadecimal
        Serial.println(analogValue, OCT);  // print as an ASCII-encoded octal
        Serial.println(analogValue, BIN);  // print as an ASCII-encoded binary
      
        // delay 10 milliseconds before the next reading:
        delay(10);
      

    Serial.read()

    • 描述

      读取传入的串口的数据。

      read() 继承自 Stream utility class.

    • 语法

      Serial.read()

      Arduino Mega only:

      Serial1.read() Serial2.read() Serial3.read()

    • 参数

      Nothing

    • 返回值

      串行输入数据的第一个可用字节(如果数据不可用,则返回 -1)- int

    • 示例代码

      int incomingByte = 0;   // for incoming serial data
      
      void setup() {
              Serial.begin(9600);     // opens serial port, sets data rate to 9600 bps
      }
      
      void loop() {
      
              // send data only when you receive data:
              if (Serial.available() > 0) {
                      // read the incoming byte:
                      incomingByte = Serial.read();
      
                      // say what you got:
                      Serial.print("I received: ");
                      Serial.println(incomingByte, DEC);
              }
      }
      

    Serial.readBytes()

    • 描述

      Serial.readBytes() 会从串行端口读取多个字符,并将它们存放到一个缓冲器中。如果已读取了指定数量的字符,或发生了超时 (Serial.setTimeout()),函数都将终止执行。 Serial.readBytes() 会返回被存放到缓冲器中的字符数。0 意味着没有找到有效数据。

      Serial.readBytes() 继承自 Stream utility class。

    • 语法

      Serial.readBytes(buffer, length)

    • 参数

      buffer: 用于存储字节的缓冲器 (char[] or byte[])

      length : 指定需要读取的字节数 (int)

    • 返回值

      放入缓冲区的字节数 (size_t) 。

    Serial.readBytesUntil()

    • 描述

      Serial.readBytesUntil() 用于从串口缓冲区读取多个字符到一个数组中。如果检测到终止字符,或是已读取了指定数量的字符,又或是发生了超时 (Serial.setTimeout()),函数都将终止执行。该函数读取的字符不包含终止字符,仅到终止字符的前一个字符为止。终止字符会被保留在串口缓冲区中。

      Serial.readBytesUntil() 会返回被存放到缓冲器中的字符数。0 意味着没有找到有效数据。

      Serial.readBytesUntil()继承自 Stream utility class.

    • 语法

      Serial.readBytesUntil(character, buffer, length)

    • 参数

      character : 终止字符 (char)

      buffer: 用于存储字节的缓冲器 (char[] or byte[])

      length : 指定需要读取的字节数 (int)

    • 返回值

      size_t

    Serial.setTimeout()

    • 描述

      Serial.setTimeout() 用于设置等待串行数据的最大毫秒数,对于 serial.readBytesUntil()serial.readBytes() 有效。默认值是 1000 毫秒。

      Serial.setTimeout()继承自 Stream utility class.

    • 语法

      Serial.setTimeout(time)

    • 参数

      time : 超时持续时间,单位是毫秒 (long) 。

    • 返回值

    • Nothing

    Serial.write()

    • 描述

      向串行端口写入二进制数据。数据会以单个字节,或是以一系列字节被发送。如果发送的 characters 表示的一个数值的不同数位则应用 print() 函数代替。

      直接将变量的值以数值形式发送,发送时不会转换为ASCII,如整型值 65,会以65发送,若接收方以 ASCII 显示,则会显示A;若以 hex 显示,则显示41。

    • 语法

      Serial.write(val) Serial.write(str) Serial.write(buf, len)

      Arduino Mega also supports:

      Serial1, Serial2, Serial3 (in place of Serial)

    • 参数

      val: 以单个字节的形式发送值

      str: 以一系列字节的形式发送字符串

      buf: 以一系列字节的形式发送一个数组

      len: 缓冲器的长度

    • 返回值

      size_t : write() 将返回向外写出的字节数,但可选择是否需获取该返回值。

    • 示例代码

    void setup(){
      Serial.begin(9600);
    }
    
    void loop(){
      Serial.write(45); // send a byte with the value 45
    
       int bytesSent = Serial.write(“hello”); //send the string “hello” and return the length of the string.
    }
    

    Description

    Writes binary data to the serial port. This data is sent as a byte or series系列 of bytes; to send the characters representing表示的 the digits of a number use the print() function instead.

    Serial.serialEvent()

    串口数据可用

    • 描述

      当数据可用时调用该函数。使用 Serial.read() 便可俘获可用数据。

      NB : 目前 serialEvent() 不兼容 Esplora, Leonardo, 以及 Micro 。

    • 语法

      void serialEvent(){
      //statements
      }
      

      Arduino Mega only:

      void serialEvent1(){
      //statements
      }
      
      void serialEvent2(){
      //statements
      }
      
      void serialEvent3(){
      //statements
      }
      
    • 参数

      statements : 任何有效语句

    • 返回值

      Nothing

    相关文章

      网友评论

        本文标题:Arduino 串行通讯

        本文链接:https://www.haomeiwen.com/subject/zkvgjftx.html