Arduino的串口通訊函數

串口通訊是單片機當中用到的最多的一種通訊,對我而言,它最大的一個優勢就是簡單,相對於I2C、SPI等,參與串口通訊的線只有兩根,分別為接收端、發送端,當然還包括電源線,我們暫且不管。

Arduino的串口通訊函數

單片機工作的時候一般都是單片機與之間單片機通訊,還有一種就是單片機與電腦的通訊,與電腦通訊主要是調試單片機的時候使用,那麼串口通訊到底在通訊什麼呢?它主要傳輸一些數據,比如12345、ABCD,也可以傳輸漢字,但是很少有人用漢字傳輸數據的,你知道為什麼嗎?

Arduino的串口通訊函數

單片機之間為什麼要串口通訊呢?是它們閒的無聊?

當然不是,它所傳輸的所有數據都是為控制做準備,那麼這些數據怎麼就能控制外設的呢?比如說LED燈。這些數據是不能直接控制LED燈開關的,比如說電腦給單片機發送“關燈”口令,LED燈就會關閉嗎?不會的,單片機怎麼會知道“關燈”是什麼呢,但是單片機可以判斷接收到的字符串,但是我們可以提前設置好,也就是給單片機編程,當單片機接收到“關燈”這兩個字符時,它就給LED引腳輸出低電平,以此來達到關閉LED燈的目的。

Arduino的串口通訊函數

還有我們所傳輸的“關燈”,在單片機看來就是一堆二進制數字,比如說“10100011”,只有它接收到10100011這一串二進制數字時,單片機才會有所動作。這麼看來單片機似乎有很傻、很死板,單片機是死的,但人是活的,我們可以把我們的思想寫進單片機,這就是單片機的偉大之處。還有越是智能的芯片,人的參與越多,比如說現在流行的語音控制,蘋果的SIRI、小米的小艾同學,它所能聽懂的每一句話,都是軟件工程師提前想好人們要說什麼,並且寫進芯片去的,這個工程就需要龐大的人力去完成。

Arduino的串口通訊函數

Hello world

說了這麼多,我們先來做一個最簡單的小實驗,讓Arduino在電腦上打印,也就是讓Arduino發送數據,電腦就收數據,並且電腦接收到數據之後打印在屏幕上。

void setup() {

Serial.begin(9600);

}

void loop() {

Serial.print("Hello World");

delay(1000);

}

程序中 函數Serial.begin(9600)是設置串口通訊的波特率為9600;

函數Serial.print("Hello World")是單片機的發送端向電腦發送引號之內的數據,即Hello World;

函數delay(1000)是延時1000毫秒,也就是一秒,為什麼要延時呢?如果不延時,電腦接收數據會很頻繁,你根本看不過來,給讓人眼花繚亂的感覺。

在不加延時的情況下,我們可以觀察Arduino板上的發送端LED燈,這時候它肯定是常亮的,正常情況下是隻有接收到數據,LED燈才會閃爍一次,因為無時無刻在往電腦發送數據,我們來看一下是不是這樣呢?可以看到TX(發送端)的LED燈是常亮(由於動圖的清晰度太低,所以用普通照片代替Gif),如果我們加上延時之後LED燈就會每隔一秒閃爍一次。

Arduino的串口通訊函數

實驗現象

每隔一秒向屏幕打印Hello World,但是接收端看上去的感覺很亂,第一個Hello World和第二個Hello World收尾相接,給人很混亂的感覺,這是為什麼呢?

Arduino的串口通訊函數

原因在於Serial.print()函數只支持單純的打印,並不支持換行,這時候我們需要用另外一個函數Serial.println()來解決這個問題,雖然只多了兩個字母,但是打印出來的字符看的就舒服多了,因為它在打印完成之後,會另起一行繼續打印,也可以理解為在打印完成數據之後,給電腦發送了回車鍵的命令。下面來看一下Serial.println()的實驗效果。

Arduino的串口通訊函數

電腦向單片機發數據

上面的實驗是Arduino向電腦發送數據,我們現在讓電腦向Arduino發送數據,比如發送0或者1。發送數據很簡單,只需要我們在串口監視助手上面輸入0或者1即可把我們想要發送的數據傳給單片機。但是問題來了,我們怎麼知道單片機收到數據了,從Arduino往電腦上發數據,因為電腦有屏幕,我們可以看到現象,Arduino沒有屏幕怎麼辦呢?

這時候就需要依靠強大的Arduino庫函數,比如我們前面所說的 Serial.begin(9600)、delay(1000)等都是庫函數,我們可以直接調用,而無需知道他的源代碼。依靠庫函數可以看到我們發送數據時應有的現象,比如說我們給Arduino發送1,當Arduino收到1之後點亮LED,而收到0之後熄滅LED。

Arduino的串口通訊函數

程序

int x = 0; //定義變量xvoid setup() { pinMode(13,OUTPUT); //設置13引腳為輸出模式 Serial.begin(9600); //設置波特率為9600}void loop(){ if (Serial.available() > 0) //返回串口緩衝區中當前剩餘的字符個數 { x = Serial.read();//把收到的數據賦給x if(x=='1') //如果收到的是1 digitalWrite(13,HIGH); //點亮LED if(x=='0') //如果收到的是0 digitalWrite(13,LOW); //熄滅LED}} 

程序裡面寫註釋了,在這裡就不多作解釋。

實驗現象

當我們向Arduino發送1之後的實驗現象,可以看到LED燈13亮了,然而屏幕上並沒有顯示任何東西,在點亮LED燈之後,Arduino是不是應該向電腦發送一些數據,比如發送“已經為你開燈”,當收到0之後,向電腦發送“已經為你關燈”。

Arduino的串口通訊函數

進階程序

這個程序也很簡單,只需要把我們最開始的串口打印函數加上就可以了, 代碼基本上和上面的差不多程序如下:

int x = 0; //定義變量x

void setup() {

pinMode(13,OUTPUT); //設置13引腳為輸出模式

Serial.begin(9600); //設置波特率為9600

}

void loop()

{

if (Serial.available() > 0) //返回串口緩衝區中當前剩餘的字符個數

{

x = Serial.read();//把收到的數據賦給x

if(x=='1') //如果收到的是1

{

digitalWrite(13,HIGH); //點亮LED

Serial.println("已經為你開燈");

}

if(x=='0') //如果收到的是0

{

digitalWrite(13,LOW); //熄滅LED

Serial.println("已經為你關燈");

}

}

}

實驗現象

當收到1時,可以看到屏幕上的串口助手顯示了“已經為你開燈”

Arduino的串口通訊函數

當收到0時的實驗現象

Arduino的串口通訊函數

不止0和1

除了用0和1之外,我們還可以用“漢字”開燈控制LED燈,道理是一樣的,如果有功放的話,還可以做語音播報,還有現在大火的物聯網領域所使用的8266WIFI模塊所使用的就是串口透傳,只不過那個8266WiFi模塊可以無線傳輸,甚至可以把我們上面程序之外的0和1穿到大洋彼岸的美國。我們現在做實驗可以用0和1直接控制,但是等我們真正做產品時,如果像剛才那樣是斷然不可以的,一般所發送的數據可能是十幾位數或更多,這是為了保證數據的可靠性和防干擾。

Arduino的串口通訊函數

Final

列舉一下我們用到的Arduino函數。

Serial.begin(); 設置串口波特率

Serial.print(); 不換行打印

Serial.println(); 換行打印

Serial.available() ;返回串口緩衝區中當前剩餘的字符個數

Serial.read();讀取一個字節

delay(); 延時函數

pinMode(); 設置引腳的輸入輸出

digitalWrite();給引腳高低電平


分享到:


相關文章: