本文翻譯自 Arduino 串行通訊的官方文檔。
本文的最新版本位于:https://github.com/iwhales/arduino_notes
轉(zhuǎn)載請(qǐng)注明出處:http://www.itdecent.cn/u/5e6f798c903a
1. 簡(jiǎn)介
Arduino 板卡使用 Serial 與電腦或其它設(shè)備進(jìn)行通訊。所有 Arduino 板卡至少擁有一個(gè)串行端口(也稱URAT 或USART):Serial。Serial 工作于數(shù)字引腳 0 (RX) 和 1 (TX) ,同時(shí)也通過 USB 與電腦通訊。因此,如果需要使用 Serial 功能,便不能同時(shí)將引腳 0 和 1 用作數(shù)字輸入和輸出。 我們可以通過 Arduino IDE 內(nèi)置的串口監(jiān)視器與 Arduino 板卡進(jìn)行通訊。在 IDE 的工具欄中點(diǎn)擊串口監(jiān)視器的圖標(biāo),并將波特率設(shè)置為 begin() 的實(shí)參值,便可與 Arduino 進(jìn)行串口通訊。
位于 TX/RX 引腳上的串行通訊采用 TTL 電平(根據(jù)電路板的設(shè)計(jì)方式,可能采用 5V 或 3.3V)。請(qǐng)勿將 TX/RX 引腳直接連接到 RS232 串行端口;RS232 的工作電壓是 +/- 12V,可能會(huì)對(duì) Arduino 造成損壞。
Arduino Mega 擁有三個(gè)額外的串行端口: Serial1 位于 19 (RX) 和 18 (TX) 引腳;Serial2 位于 17 (RX) 和 16 (TX) 引腳;Serial3 位于 15 (RX) 和 14 (TX) 引腳。如果想使用這些引腳與 PC 進(jìn)行通訊,則需要自行提供 USB-to-serial 適配器 —— 因?yàn)檫@些額外的串行端口并沒有被連接到 Mega 自帶的 USB-to-serial 適配器上。如果想要通過這些額外的串行端口與外部 TTL 串行設(shè)備進(jìn)行通訊,那么需要將外部設(shè)備的 TX 和 RX 引腳分別連接至 Mega 的 RX 和 TX 引腳,同時(shí)將 Mega 的地線與外部設(shè)備的地線直接相連。
Arduino Due 擁有三個(gè)額外的 3.3V TTL 串行端口:Serial1 位于 19 (RX) 和 18 (TX) 引腳;Serial2 位于 17 (RX) 和 16 (TX) 引腳;Serial3 位于 15 (RX) 和 14 (TX) 引腳。引腳 0 和 1 同樣也被連接到了 ATmega16U2 USB-to-TTL 串口芯片的對(duì)應(yīng)引腳,用于連接 USB 調(diào)試端口。此外,SAM3X 芯片還擁有一個(gè)原生 USB-serial 端口——SerialUSB' 。
Arduino Leonardo 在引腳 0 (RX) 和 1 (TX) 上使用 Serial1 進(jìn)行通訊,Serial1 也是 5V TTL。Serial 用作 USB CDC 通訊。欲了解更多信息,請(qǐng)參閱 Leonardo 的相關(guān)頁(yè)面。
2. 函數(shù)
if (Serial)
-
描述
用于指示指定的串口是否已準(zhǔn)備就緒。 在 Leonardo 上,
if(Serial)用于指示 USB CDC 串行連接是否開放。對(duì)于所有其他情況,包括 Leonardo 的if (Serial1),將始終返回true。 -
語(yǔ)法
All boards:
if (Serial)Arduino Leonardo specific:
if (Serial1)Arduino Mega specific:
if (Serial1)if (Serial2)if (Serial3) -
參數(shù)
Nothing
-
返回值
boolean:如果指定串口可用,將返回true。僅在 Leonardo 的 USB CDC 串行連接準(zhǔn)備好之前進(jìn)行查詢時(shí),會(huì)返回false。 -
示例代碼
void setup() { //初始化串行端口,并等待端口開啟: Serial.begin(9600); while (!Serial) { ; // 等待串口連接。需要原生USB } } void loop() { //proceed normally }
Serial.available()
-
描述
獲取可以從串行端口讀取的可用字節(jié)(字符)數(shù)。該數(shù)據(jù)表示已經(jīng)到達(dá)并存儲(chǔ)在串行接受緩沖區(qū)中的字節(jié)數(shù)——接受緩沖區(qū)可存儲(chǔ) 64 字節(jié)的數(shù)據(jù)。
available()繼承自 Stream utility class。 -
語(yǔ)法
Serial.available()Arduino Mega only:
Serial1.available()Serial2.available()Serial3.available() -
參數(shù)
Nothing
-
返回值
返回可供讀取的字節(jié)數(shù)
-
示例代碼
以下代碼將返回通過串口接受的字符
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 的某個(gè)串口接受到的數(shù)據(jù)發(fā)送到另一個(gè)串口。利用這段代碼可將串行設(shè)備通過 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()
-
描述
獲取可用于寫入串行緩沖區(qū)的字節(jié)(字符)數(shù),并且不會(huì)阻塞寫入操作。
-
語(yǔ)法
Serial.availableForWrite()Arduino Mega only:
Serial1.availableForWrite()Serial2.availableForWrite()Serial3.availableForWrite() -
參數(shù)
Nothing
-
返回值
可用于寫操作的字節(jié)數(shù)
Serial.begin()
-
描述
設(shè)置串行數(shù)據(jù)傳輸?shù)乃俾?,單位?bits/秒 (baud 波特)。與計(jì)算機(jī)進(jìn)行通訊時(shí),可使用以下速率中的一個(gè):300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, 115200。當(dāng)然,你可以指定其它速率 —— 例如,通過引腳 0 和 1 連接一個(gè)需求特定波特率的元件時(shí)。
可選的第二參數(shù)用于配置數(shù)據(jù)位數(shù)、奇偶校驗(yàn)和停止位。默認(rèn)是 8 數(shù)據(jù)位、無(wú)奇偶校驗(yàn)、1 位停止位。
-
語(yǔ)法
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) -
參數(shù)
speed: bits/秒 (baud) -longconfig: 設(shè)置數(shù)據(jù)位數(shù)、奇偶校驗(yàn)和停止位。 有效值如下SERIAL_5N1SERIAL_6N1SERIAL_7N1SERIAL_8N1(the default)SERIAL_5N2SERIAL_6N2SERIAL_7N2SERIAL_8N2``SERIAL_5E1SERIAL_6E1SERIAL_7E1SERIAL_8E1SERIAL_5E2SERIAL_6E2SERIAL_7E2SERIAL_8E2SERIAL_5O1``SERIAL_6O1SERIAL_7O1SERIAL_8O1SERIAL_5O2SERIAL_6O2SERIAL_7O2SERIAL_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 引腳被用作通用輸入和輸出。再次調(diào)用
Serial.begin()可重新啟用串行通訊,啟用后 RX 和 TX 便不能再被用作通用輸入和輸出。 -
語(yǔ)法
Serial.end()Arduino Mega only:
Serial1.end()Serial2.end()Serial3.end() -
參數(shù)
Nothing
-
返回值
Nothing
Serial.find()
-
描述
需要注意,流解析只過一遍,沒有辦法折返回去試圖發(fā)現(xiàn)或得到更多東西。
Serial.find( )從串口緩沖區(qū)中讀取數(shù)據(jù)直到給定長(zhǎng)度的目標(biāo)字符串被發(fā)現(xiàn)為止。如果發(fā)現(xiàn)目標(biāo)字符串將返回true;如果超時(shí)則返回false。 假如目標(biāo)字符串被發(fā)現(xiàn),該函數(shù)返回 true,如果超時(shí)則為 false。Serial.flush()繼承自 Stream utility class。 -
語(yǔ)法
Serial.find(target) -
參數(shù)
target: 要搜索的字符串(char) -
返回值
boolean
Serial.findUntil()
-
描述
Serial.findUntil()從串口緩沖區(qū)中讀取數(shù)據(jù)直到給定長(zhǎng)度的目標(biāo)字符串,或終止字符串被發(fā)現(xiàn)為止。 如果發(fā)現(xiàn)目標(biāo)字符串將返回true;如果超時(shí)則返回false。Serial.findUntil()繼承自 Stream utility class. -
語(yǔ)法
Serial.findUntil(target, terminal) -
參數(shù)
target: 要搜索的字符串(char)terminal: 終止搜索的字符串(char) -
返回值
boolean
Serial.flush()
-
描述
等待傳出的串行數(shù)據(jù)完成傳輸(在 Arduino 1.0 之前,這反而會(huì)移除任何已緩存的傳入數(shù)據(jù) )。如果需要丟棄接受緩沖區(qū)中的所有數(shù)據(jù),可使用
while(Serial.read( ) >= 0);flush()繼承自 Stream utility class. -
語(yǔ)法
Serial.flush()Arduino Mega only:
Serial1.flush()Serial2.flush()Serial3.flush() -
參數(shù)
Nothing
-
返回值
Nothing
Serial.parseFloat()
-
描述
Serial.parseFloat()返回串行緩沖區(qū)中第一個(gè)有效的浮點(diǎn)數(shù)。解析時(shí),非數(shù)值(或減號(hào))字符會(huì)被跳過。parseFloat()會(huì)在第一個(gè)非浮點(diǎn)數(shù)值處終止。Serial.parseFloat()繼承自 Stream utility class. -
語(yǔ)法
Serial.parseFloat() -
參數(shù)
Nothing
-
返回值
float
Serial.parseInt()
-
描述
在輸入串行數(shù)據(jù)中查找下一個(gè)有效的整型。
stream.parseInt()繼承自 Stream utility class。特點(diǎn):
- 非數(shù)值或負(fù)號(hào)的初始字符會(huì)被跳過;
- 如果在(可配置)超時(shí)值內(nèi)沒有讀取到字符,或是讀取到了一個(gè)非數(shù)值字符,解析將停止。
- 如果發(fā)生超時(shí)(
Serial.setTimeout())時(shí),并沒有讀取到有效數(shù)值,將會(huì)返回 0;
-
語(yǔ)法
Serial.parseInt()Serial.parseInt(char skipChar)Arduino Mega only:
Serial1.parseInt()Serial2.parseInt()Serial3.parseInt() -
參數(shù)
skipChar:在搜索時(shí),用于跳過指定字符。例如用來(lái)跳過千位分隔符,如 32,767 將被解析為 32767。 -
返回值
long:下一個(gè)有效整型
Serial.peek()
-
描述
返回輸入串行數(shù)據(jù)的下一個(gè)字節(jié)(字符),但不會(huì)從內(nèi)部串行緩沖區(qū)移除該字節(jié)。也就是說,在下一次調(diào)用
read()之前,如果連續(xù)調(diào)用peek()的話,將返回相同的字符。peek()繼承自 Stream utility class. -
語(yǔ)法
Serial.peek()Arduino Mega only:
Serial1.peek()Serial2.peek()Serial3.peek() -
參數(shù)
Nothing
-
返回值
輸入串行數(shù)據(jù)的第一個(gè)可用字節(jié)(如果沒有數(shù)據(jù)可用,則返回 -1 )-
int
Serial.print()
-
描述
將數(shù)據(jù)以人類可讀的 ASCII 文本打印到串口。該命令有多重形式。對(duì)于數(shù)值,會(huì)使用 ASCII 字符打印其每個(gè)數(shù)位。對(duì)于浮點(diǎn)數(shù),同樣會(huì)使用 ASCII 打印其每個(gè)數(shù)位,默認(rèn)包含兩位小數(shù)。Bytes 會(huì)以單個(gè)字符發(fā)送。字符和字符串按原樣發(fā)送。例如 -
Serial.print(78) gives "78"Serial.print(1.23456) gives "1.23"Serial.print('N') gives "N"Serial.print("Hello world.") gives "Hello world."
可選的第二參數(shù)用于指定底數(shù)(格式),允許的值有:
BIN(binary, or base 2),OCT(octal, or base 8),DEC(decimal, or base 10),HEX(hexadecimal, or base 16)。對(duì)于浮點(diǎn)數(shù),第二個(gè)參數(shù)用于指定小數(shù)的位數(shù)。例如 -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”))發(fā)送單個(gè) byte,需使用 Serial.write()。
-
語(yǔ)法
Serial.print(val)Serial.print(val, format) -
參數(shù)
val: 用于打印輸出的值 - 任何類型的數(shù)據(jù)。 -
返回值
size_t:print()返回向外寫出的字節(jié)數(shù),但可選擇是否需獲取該返回值。 -
示例代碼
/* 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()將在任何字符被發(fā)送前返回。Serial.print()和Serial.write()不會(huì)阻塞程序。在 1.0 之前,代碼會(huì)等到所有的字符發(fā)送之后才返回。在 1.0 及其以后,Serial.write()會(huì)在后臺(tái)中進(jìn)行(使用了終端處理程序),這使得程序會(huì)理解恢復(fù),并執(zhí)行后續(xù)代碼。這種方式通??墒钩绦蚋涌旖?,但是入股需要等待所有字符發(fā)送完畢??梢酝ㄟ^在Serial.write()之后調(diào)用Serial.flush()來(lái)實(shí)現(xiàn)。
Serial.println()
-
描述
將數(shù)據(jù)以人類可讀的 ASCII 文本打印到串口,并在文本結(jié)尾添加回車字符 (ASCII 13, or '\r') 和換行字符 (ASCII 10, 或 '\n')。該命令采用與 Serial.print() 相同的格式。
-
語(yǔ)法
Serial.println(val)Serial.println(val, format) -
參數(shù)
val: 用于打印輸出的值 - 任何類型的數(shù)據(jù)。format: 指定底數(shù)(對(duì)于整形數(shù)據(jù)類型)或小數(shù)位數(shù)(對(duì)于浮點(diǎn)類型) -
返回值
size_t:println()返回向外寫出的字節(jié)數(shù),但可選擇是否需獲取該返回值 -
示例代碼
/* 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()
-
描述
讀取傳入的串口的數(shù)據(jù)。
read() 繼承自 Stream utility class.
-
語(yǔ)法
Serial.read()Arduino Mega only:
Serial1.read()Serial2.read()Serial3.read() -
參數(shù)
Nothing
-
返回值
串行輸入數(shù)據(jù)的第一個(gè)可用字節(jié)(如果數(shù)據(jù)不可用,則返回 -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()會(huì)從串行端口讀取多個(gè)字符,并將它們存放到一個(gè)緩沖器中。如果已讀取了指定數(shù)量的字符,或發(fā)生了超時(shí) (Serial.setTimeout()),函數(shù)都將終止執(zhí)行。Serial.readBytes()會(huì)返回被存放到緩沖器中的字符數(shù)。0 意味著沒有找到有效數(shù)據(jù)。Serial.readBytes()繼承自 Stream utility class。 -
語(yǔ)法
Serial.readBytes(buffer, length) -
參數(shù)
buffer: 用于存儲(chǔ)字節(jié)的緩沖器 (char[]orbyte[])length: 指定需要讀取的字節(jié)數(shù) (int) -
返回值
放入緩沖區(qū)的字節(jié)數(shù) (
size_t) 。
Serial.readBytesUntil()
-
描述
Serial.readBytesUntil()用于從串口緩沖區(qū)讀取多個(gè)字符到一個(gè)數(shù)組中。如果檢測(cè)到終止字符,或是已讀取了指定數(shù)量的字符,又或是發(fā)生了超時(shí) (Serial.setTimeout()),函數(shù)都將終止執(zhí)行。該函數(shù)讀取的字符不包含終止字符,僅到終止字符的前一個(gè)字符為止。終止字符會(huì)被保留在串口緩沖區(qū)中。Serial.readBytesUntil()會(huì)返回被存放到緩沖器中的字符數(shù)。0 意味著沒有找到有效數(shù)據(jù)。Serial.readBytesUntil()繼承自 Stream utility class. -
語(yǔ)法
Serial.readBytesUntil(character, buffer, length) -
參數(shù)
character: 終止字符 (char)buffer: 用于存儲(chǔ)字節(jié)的緩沖器 (char[]orbyte[])length: 指定需要讀取的字節(jié)數(shù) (int) -
返回值
size_t
Serial.setTimeout()
-
描述
Serial.setTimeout()用于設(shè)置等待串行數(shù)據(jù)的最大毫秒數(shù),對(duì)于 serial.readBytesUntil() 或 serial.readBytes() 有效。默認(rèn)值是 1000 毫秒。Serial.setTimeout()繼承自 Stream utility class. -
語(yǔ)法
Serial.setTimeout(time) -
參數(shù)
time: 超時(shí)持續(xù)時(shí)間,單位是毫秒 (long) 。 返回值
Nothing
Serial.write()
-
描述
向串行端口寫入二進(jìn)制數(shù)據(jù)。數(shù)據(jù)會(huì)以單個(gè)字節(jié),或是以一系列字節(jié)被發(fā)送。如果發(fā)送的 characters 表示的一個(gè)數(shù)值的不同數(shù)位則應(yīng)用
print()函數(shù)代替。直接將變量的值以數(shù)值形式發(fā)送,發(fā)送時(shí)不會(huì)轉(zhuǎn)換為ASCII,如整型值 65,會(huì)以65發(fā)送,若接收方以 ASCII 顯示,則會(huì)顯示A;若以 hex 顯示,則顯示41。
-
語(yǔ)法
Serial.write(val)Serial.write(str)Serial.write(buf, len)Arduino Mega also supports:
Serial1,Serial2,Serial3(in place ofSerial) -
參數(shù)
val: 以單個(gè)字節(jié)的形式發(fā)送值str: 以一系列字節(jié)的形式發(fā)送字符串buf: 以一系列字節(jié)的形式發(fā)送一個(gè)數(shù)組len: 緩沖器的長(zhǎng)度 -
返回值
size_t:write()將返回向外寫出的字節(jié)數(shù),但可選擇是否需獲取該返回值。 示例代碼
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()
串口數(shù)據(jù)可用
-
描述
當(dāng)數(shù)據(jù)可用時(shí)調(diào)用該函數(shù)。使用
Serial.read()便可俘獲可用數(shù)據(jù)。NB : 目前
serialEvent()不兼容 Esplora, Leonardo, 以及 Micro 。 -
語(yǔ)法
void serialEvent(){ //statements }Arduino Mega only:
void serialEvent1(){ //statements } void serialEvent2(){ //statements } void serialEvent3(){ //statements } -
參數(shù)
statements: 任何有效語(yǔ)句 -
返回值
Nothing