在使用樹莓派時,你會發現Python和Scratch是許多任務(包括GPIO編程)中最常用的編程語言。但你知道嗎,你也可以使用C++進行GPIO編程,而且這樣做還有不少好處。
借助WiringPi和PiGPIO等庫,C++可用于編程控制樹莓派的GPIO引腳。它提供了更好的性能和控制能力,非常適合對速度和精度要求較高的硬件項目。
在樹莓派社區中,關于“Python與C++哪個更適合樹莓派”的討論十分熱烈。Python因其簡單易用和龐大的生態系統而備受青睞,而C++則在性能和精確的硬件控制方面表現出色。這一特性使C++成為某些項目的可靠選擇。
目錄
先決條件
了解C/C++的不同GPIO庫
搭建開發環境
搭建電路
編寫GPIO程序以使LED閃爍
常見問題解答(FAQ)
先決條件
以下是使用C++進行GPIO編程所需的一些條件:
樹莓派開發板:你可以使用任何符合項目資源需求的樹莓派型號。本教程中,我將使用配備2GB內存的樹莓派4B。
操作系統要求:任何受樹莓派支持的操作系統均可。但如果你是初學者,我建議先使用樹莓派操作系統(Raspberry Pi OS)。等你熟練掌握了在樹莓派上使用C++編程后,再切換其他系統也不遲。
C++編譯器(g++):這是C++的命令行編譯器,預裝在樹莓派操作系統中。
所需庫(WiringPi、PiGPIO):這些C++庫用于與樹莓派的GPIO引腳進行交互。
一個LED燈:本教程至少需要一個LED燈。
了解C/C++的不同GPIO庫
在深入探討各種可用庫之前,我們先來了解一下為什么在使用GPIO引腳時需要庫。
主要原因在于簡化操作。庫讓我們無需處理復雜的底層硬件控制,就能輕松與GPIO引腳進行交互,既節省時間又降低了難度。
例如,如果我想打開/關閉一個GPIO引腳,只需使用以下這行代碼:
digitalWrite(pin,HIGH);// Turn on an LED
但如果沒有庫,我就得直接操作內存寄存器,這要復雜得多。
WiringPi
WiringPi是樹莓派上與GPIO引腳交互最受歡迎的庫之一。我曾用它完成過搭建循線機器人等復雜項目,從未遇到過任何問題。
不過,在使用WiringPi之前,你應該知道它的引腳編號系統可能會讓人困惑。
WiringPi并不遵循標準的BCM(GPIO)編號或樹莓派的物理引腳布局。當第一款樹莓派發布時,它只有少數幾個可用的GPIO引腳,WiringPi以自己的方式將這些引腳編號為0到7。隨著新款樹莓派型號引入了更多GPIO引腳,WiringPi為了保持向后兼容性,保留了原有的編號方式。
這意味著WiringPi的引腳編號并不總是與實際的GPIO編號或電路板上的物理引腳位置相對應。不過別擔心!你可以參考下表,查看每個樹莓派引腳在WiringPi中的映射關系。

pigpio是另一個用于控制樹莓派GPIO引腳的C++庫。在撰寫本文時,我雖未廣泛使用過它,但從有限的幾次使用經驗來看,我發現它比WiringPi更強大,但我強烈建議僅將其用于高級任務。
與WiringPi不同,pigpio作為后臺服務(守護進程)運行,非常適合精確的GPIO控制。如果你正在進行一個需要平穩精確控制電機或伺服器的項目,那么pigpio值得考慮。
然而,這一關鍵特性也是它的最大缺點。由于pigpio依賴于其守護進程,在資源(CPU和內存)有限的老款樹莓派型號上,它可能無法很好地工作,尤其是在運行繁重的GPIO操作時。此外,你不能將其與WiringPi等其他庫同時使用,因為它們可能會產生沖突。
注意:在本教程中,我將使用WiringPi,因為我只編寫一個點亮LED的小程序。WiringPi對初學者友好,是開始在樹莓派上進行GPIO編程的最簡單方法之一。
搭建開發環境
現在,你已經掌握了使用C++控制GPIO引腳所需的所有信息。接下來,讓我們深入探討設置過程。
安裝必要的開發包
如果你使用的是樹莓派操作系統完整版,它已經預裝了許多開發包。但如果你使用的是樹莓派操作系統精簡版(Lite)或其他基于Debian的發行版,則需要手動安裝C++編譯器和其他依賴項。
你可以通過運行以下命令來完成安裝:
sudoapt updatesudo apt install g++ build-essential

安裝并設置WiringPi
你必須在樹莓派上安裝WiringPi才能將其用于GPIO項目。首先,通過運行以下命令更新系統:
sudoapt update
以前,你可以輕松地使用apt命令從樹莓派軟件源中安裝WiringPi。然而,由于WiringPi已停止支持,你需要從WiringPi的GitHub倉庫克隆它:
gitclonehttps://github.com/WiringPi/WiringPi.gitcdWiringPi./build debiancddebian-templatesudo apt install ./wiringpi_3.14_arm64.deb
文件名可能有所不同,請根據設備生成的文件調整最后一條命令。

完成后,你可以通過運行以下命令驗證安裝是否成功:
gpio-v

現在,我們已經準備好了軟件需求,接下來進入設置電路的步驟。
搭建電路
下一步是搭建電路。這一步需要你親自動手,將LED燈連接到樹莓派的GPIO引腳上。
了解樹莓派GPIO布局
在繼續之前,你需要明白不能將LED燈連接到樹莓派的任意引腳上。每個引腳都有特定的功能,且只能用于該功能。有些引腳用于輸入/輸出,有些用于供電(3.3V或5V),還有些用于接地。
如果你之前沒有做過涉及GPIO引腳的項目,我建議你快速瀏覽一下我們關于樹莓派GPIO引腳入門的全面文章。它將幫助你更好地理解本教程的內容。
將LED燈連接到樹莓派
現在,我將直接連接LED燈到樹莓派,不使用電阻。我知道這不是理想的方法,但我之前這樣做過,沒有出現過任何問題。而且,我知道我的LED燈額定電壓為3V,處于安全范圍,不會損壞樹莓派。
我將使用一個擴展板,因為它更整潔、更方便,但你也可以直接將LED燈連接到樹莓派的引腳上,如果你覺得這樣更方便的話。我將把LED燈連接到GPIO 26和接地(GND)引腳上。

編寫GPIO程序以使LED閃爍
設置好電路后,我們就可以編寫代碼了。你可以使用許多編輯器在樹莓派上編寫程序。你可以選擇基于命令行的編輯器(如Nano)或基于圖形界面的編輯器(如Geany)。在本教程中,我將使用nano編輯器。
首先,打開終端,使用以下命令導航到“文檔”目錄并創建一個程序文件:
cdDocumentsmkdirBlinkLEDProgramtouchblink_led.cpp

創建文件后,我們可以使用nano編輯器打開它:
nanoblink_led.cpp
編寫代碼
這將打開一個空文本編輯器,你可以在其中開始編寫代碼。我將把這段代碼分成幾個部分,以便你更好地理解。
#include#include#include#include
#include :這行代碼包含了WiringPi庫,使你能夠控制樹莓派的GPIO引腳。這是與LED等硬件交互所必需的。
#include :這用于輸入輸出操作。在本例中,我們將使用它來向終端打印文本。
#include :這提供了時間工具。在我們的程序中,我們將使用毫秒等工具來控制延遲。
#include :我們將使用它來暫停程序執行指定的時間。它與Python中的sleep()函數類似。
constexprintLED_PIN =25;
在這里,我們定義了一個常量LED引腳,它將與樹莓派上的引腳進行交互。你會注意到,我將其設置為25,但在搭建電路時,我明確表示將把LED燈連接到GPIO 26。
這是因為WiringPi使用了不同的GPIO編號方式。如果你參考上面的表格,你會發現樹莓派上的GPIO 26在WiringPi庫中被映射為引腳25。
usingnamespacestd;usingnamespacestd::chrono;usingnamespacestd::this_thread;
using namespace std;:這意味著我們可以使用標準的C++特性(如cout、cerr、endl等),而無需總是使用std::前綴。
std::
using namespace std::chrono;和using namespace std::this_thread;:這些使我們能夠直接使用時間相關函數(如milliseconds和sleep_for),而無需每次都寫出std::milliseconds或std::sleep_for。
intmain(intargc,char* argv[])
這是程序的入口點,程序從這里開始執行。
if(wiringPiSetup() == -1){ cerr<"Failed to initialize wiringPi"?<< endl;? ? return?1;}
wiringPiSetup():這個函數初始化WiringPi庫。如果它返回-1,說明出現了問題,庫無法初始化。
cerr << "Failed to initialize wiringPi" << endl;:如果WiringPi設置失敗,這將在終端打印一條錯誤信息。
return 1;:如果設置失敗,這將結束程序。1表示發生了錯誤。
pinMode(LED_PIN, OUTPUT); //Setthe LED pinasoutput
pinMode(LED_PIN, OUTPUT);:這告訴樹莓派,GPIO引腳25(連接LED燈的引腳)將用于輸出。這很重要,因為引腳可以設置為輸入(讀取數據)或輸出(發送數據)。
cout <"Blinking LED connected to GPIO pin "?<
cout:這將在終端打印一條信息,告訴你程序正在運行,并且正在GPIO引腳25上使LED燈閃爍。這就像是對用戶的一個快速狀態更新。
while(true){ digitalWrite(LED_PIN,HIGH); sleep_for(milliseconds(500)); digitalWrite(LED_PIN,LOW); //Correctedfrom'Low'to'LOW' sleep_for(milliseconds(500));}
while (true):這開始一個無限循環。循環內的代碼將一直運行,直到你手動停止程序。這用于使LED燈持續閃爍。
digitalWrite(LED_PIN, HIGH);:這通過向GPIO引腳25發送高電平信號來打開LED燈。HIGH是一個常量,表示“開”。
sleep_for(milliseconds(500));:這暫停程序執行500毫秒(0.5秒),因此LED燈將保持亮起半秒鐘。
digitalWrite(LED_PIN, LOW);:這通過向GPIO引腳25發送低電平信號來關閉LED燈。LOW表示“關”。
sleep_for(milliseconds(500));:這再次暫停程序執行500毫秒,因此LED燈將保持熄滅半秒鐘。
這個循環使LED燈每半秒閃爍一次。
return0;
這行代碼標志著程序的結束,并返回0表示一切運行正常。然而,由于我們有一個無限的while (true)循環,除非你手動通過鍵盤按下Ctrl + C停止程序,否則這行代碼永遠不會被執行。
最終的代碼看起來與下圖類似。

完成后,使用Ctrl + S保存代碼并退出(Ctrl + X)。
編譯并運行代碼
要編譯這個程序,請執行以下命令:
g++ -std=c++17-o blink_led blink_led.cpp -lwiringPi
g++:這是GNU C++編譯器。
-std=c++17:指定代碼應使用C++17標準進行編譯。
-o blink_led:這告訴編譯器創建一個名為blink_led的輸出文件(可執行文件)。
blink_led.cpp:這是我們編寫代碼的源文件。
-lwiringPi:鏈接WiringPi庫,這是控制樹莓派GPIO引腳所必需的。
成功執行后,你可以使用以下命令運行程序:
./blink_led

下面的視頻展示了我這邊的輸出結果。一切都很順利,我的LED燈按預期閃爍。
排查錯誤
代碼中的大多數錯誤將在編譯過程中被捕獲并顯示在屏幕上。然而,還有其他一些問題可能會導致程序無法運行或LED燈無法閃爍。
如果你嘗試運行程序時遇到類似以下錯誤:
wiringPiSetup:commandnot found
這意味著WiringPi沒有正確安裝。你可以按照上面“安裝并設置WiringPi”部分中的說明重新安裝它。
另一種排查問題的先進方法是使用gpio readall命令:
gpioreadall
它顯示一個表格,展示所有GPIO引腳的當前引腳狀態、模式和編號。你可以使用這些信息來解決LED燈不閃爍的多個問題。
檢查引腳編號:由于不同的庫(BCM、WiringPi和物理編號)使用不同的編號方式,gpio readall幫助你確認程序應該使用哪種編號方式。
驗證引腳模式:你可以檢查引腳是設置為輸入、輸出還是ALT模式。
檢查引腳狀態:該命令顯示引腳當前是高電平(1)還是低電平(0)。因此,如果你的LED燈應該亮起但引腳仍然是低電平(0),那么你可能存在接線或軟件問題。
檢測沖突:你還可以使用這些信息來檢查引腳是否被另一個進程或庫使用。
就這樣!你現在應該已經了解了如何在樹莓派上使用C++控制GPIO引腳。在本教程中,我只使用了WiringPi庫使LED燈閃爍的一個小例子。你可以通過使用更多組件和參與更復雜的項目來進一步探索。
FAQ
能否不使用任何庫來編程GPIO?
是的,但難度要大得多。你將需要直接與內存寄存器或系統文件(如/sys/class/gpio/)進行交互。像WiringPi和PiGPIO這樣的庫使這一過程變得簡單得多。
在C++中控制GPIO是否需要root權限?
這取決于你使用的庫。WiringPi需要root權限(sudo)來訪問GPIO引腳,因為它直接與硬件交互。PiGPIO作為后臺服務(守護進程)運行,因此并不總是需要sudo,但這取決于守護進程的設置方式。
原文地址:
https://raspberrytips.com/control-gpio-with-c-on-raspberry-pi/
-
操作系統
+關注
關注
37文章
7401瀏覽量
129284 -
GPIO
+關注
關注
16文章
1328瀏覽量
56219 -
樹莓派
+關注
關注
122文章
2078瀏覽量
110462
發布評論請先 登錄
如何使用Telegram控制樹莓派上的GPIO引腳
如何在樹莓派上安裝Ubuntu MATE ?
樹莓派MCC118
如何在樹莓派上裝一個codesys的runtime
如何在樹莓派上運行Fedora
樹莓派使用C/C++基于Bcm2835操作GPIO學習記錄
C++ 與 Python:樹莓派上哪種語言更優?
技能+1!如何在樹莓派上使用C++控制GPIO?
評論