樹莓派學習:wiringPi庫學習

最近公司拓展要在樹莓派上研發一些新項目,以前一直只是聽說樹莓派,但是沒接觸過。

而樹莓派關於串口通信有以下三種方案,根據我的項目選擇了wiringPi,

    【python GPIO】
    【開發語言】——python
    【簡單介紹】——該庫更確切的名稱爲raspberry-gpio-python,樹莓派官方資料中推薦且容易上手。python GPIO是一個小型的python庫,可以幫助用戶完成raspberry相關IO口操作。但是python GPIO庫還沒有支持SPI、I2C或者1-wire等總線接口。除了python GPIO之外,還有衆多的python擴展庫(例如webiopi),毫無疑問的說python非常適合樹莓派,樹莓派也非常適合python。

    【wiringPi】
    【開發語言】——C語言
    【簡單介紹】——wiringPi適合那些具有C語言基礎,在接觸樹莓派之前已經接觸過單片機或者嵌入式開發的人羣。wiringPi的API函數和arduino非常相似,這也使得它廣受歡迎。作者給出了大量的說明和示例代碼,這些示例代碼也包括UART設備,I2C設備和SPI設備等,毫無疑問地說wiringPi功能非常強大。

    【BCM2835 C Library】
    【開發語言】——C語言
    【簡單介紹】BCM2835 C Library可以理解爲使用C語言實現的相關底層驅動,它給我的感覺更像STM32的庫函數,BCM2835 C Library的驅動庫包括GPIO、SPI和UART等,可以通過學習BCM2835 C Library熟悉BCM2835相關的寄存器操作。如果有機會開發樹莓派上的linux驅動,或自主開發python或PHP擴展驅動,可以從BCM2835 C Library找到不少的“靈感”。

接下來就瞭解一下wiringPi庫,下面的說明都是我從官方手冊翻譯過來的http://wiringpi.com/

設置

有四種方法來初始化wiringPi

int wiringPiSetup (void) ;
int wiringPiSetupGpio (void) ;
int wiringPiSetupPhys (void) ;
int wiringPiSetupSys (void) ;

必須在程序開始時調用其中一個設置功能,否則您的程序將無法正常運行。您可能會從中遇到一些症狀,而這些症狀根本無法解決段錯誤和計時問題。

注意:如果這些功能由於任何原因失敗,則connectionPi版本1返回錯誤代碼。版本2返回總是返回零。在討論和檢查了connectionPi用戶編寫的許多程序並觀察到很多人都沒有去檢查返回碼後,我採取了這樣的態度:如果connectionPi設置功能之一失敗,則將其視爲致命的程序錯誤,並且此時程序執行將終止,並在終端上顯示一條錯誤消息。

  • 如果要還原v1行爲,則需要設置環境變量:WIRINGPI_CODES(爲任何值,只需要存在即可)

設置功能之間的差異如下:

wiringPiSetup (void) ;

這初始化wiringPi並假定調用程序將要使用wiringPi引腳編號方案。這是一種簡化的編號方案,提供了從0到16的虛擬引腳號到實際的基礎Broadcom GPIO引腳號的映射。請參閱引腳頁面以獲取將接線Pi引腳號與Broadcom GPIO引腳號映射到邊緣連接器上物理位置的表。

需要使用root特權來調用此函數。

routingPiSetupGpio (void) ;

這與上面相同,但是它允許調用程序直接使用Broadcom GPIO引腳號,而無需重新映射。

如上所述,此功能需要使用root特權來調用,並且請注意,某些引腳與版本1到版本2板不同。

connectionPiSetupPhys (void) ;

與上述相同,但是它允許調用程序僅使用P1連接器上的物理引腳號。

如上所述,需要使用root特權來調用此函數。

wiringPiSetupSys (void) ;

這將初始化connectionPi,但是使用/ sys / class / gpio接口,而不是直接訪問硬件。如果事先使用gpio程序導出了GPIO引腳,則可以稱爲非root用戶。在此模式下,引腳編號是本機Broadcom GPIO編號-與上面的connectionPiSetupGpio()相同,因此請注意Rev 1和Rev 2板之間的差異。

注意:在這種模式下,您只能在運行程序之前使用通過/ sys / class / gpio接口導出的引腳。您可以在單獨的shell腳本中執行此操作,也可以在程序內部使用system()函數來調用gpio程序。

另外請注意,某些功能使用此模式時,有沒有影響,因爲他們目前還不能操作,除非稱爲具有root權限。(儘管您可以根據需要使用system()調用gpio來設置/更改模式)

核心函數

這些功能可以直接在Raspberry Pi上使用,也可以與外部GPIO模塊(例如GPIO擴展器等)一起使用,儘管並非所有模塊都支持所有功能-例如PiFace已預先配置爲其固定的輸入和輸出,而Raspberry Pi沒有板載模擬硬件。

void pinMode (int pin, int mode) ;

會將引腳的模式設置爲INPUTOUTPUTPWM_OUTPUTGPIO_CLOCK。請注意,只有wireingPi引腳1(BCM_GPIO 18)支持PWM輸出,只有wireingPi引腳7(BCM_GPIO 4)支持CLOCK輸出模式。

Sys模式下,此功能無效。如果您需要更改引腳模式,則可以在啓動程序之前使用腳本中的gpio程序進行操作。

void pullUpDnControl (int pin, int pud) ;

這將在給定的引腳上設置上拉或下拉電阻器模式,應將其設置爲輸入。與Arduino不同,BCM2835都具有下拉內部電阻器。參數pud應該是;PUD_OFF,(不上拉/下拉),PUD_DOWN(上拉至接地)或PUD_UP(上拉至3.3v)在Raspberry Pi上,內部上拉/下拉電阻的阻值約爲50KΩ。

處於Sys模式時,此功能對Raspberry Pi的GPIO引腳無效。如果您需要激活上拉/下拉,則可以在啓動程序之前使用腳本中的gpio程序進行激活。

void digitalWrite (int pin, int value) ;

將值HIGHLOW(1或0)寫入必須預先設置爲輸出的給定引腳。

WiringPi將任何非零數字視爲 HIGH,但是0是 LOW的唯一表示。

void pwmWrite (int pin, int value) ;

將值寫入給定引腳的PWM寄存器。Raspberry Pi有一個板載PWM引腳,即引腳1(BMC_GPIO 18,物理層12),範圍爲0-1024。其他PWM器件可能具有其他PWM範圍。

Sys模式下,此功能無法控制Pi的板載PWM 。

int digitalRead (int pin) ;

該函數返回在給定引腳上讀取的值。根據引腳上的邏輯電平,它將爲高電平低電平(1或0)。

analogRead (int pin) ;

這將返回在提供的模擬輸入引腳上讀取的值。您將需要註冊其他模擬模塊才能爲Gertboard,quick2Wire模擬板等設備啓用此功能。

analogWrite (int pin, int value) ;

這會將給定值寫入提供的模擬引腳。您將需要註冊其他模擬模塊才能爲諸如Gertboard之類的設備啓用此功能。

樹莓派特性

這些功能不是核心connectionPi集中的一部分,而是專門作用於Raspberry Pi硬件本身。但是,某些外部硬件驅動程序模塊可能會提供某些此功能。

void digitalWriteByte (int value) ;

這將寫入提供給前8個GPIO引腳的8位字節。儘管仍然需要對Pi的GPIO硬件進行兩次寫操作,但這是一次將所有8位都設置爲特定值的最快方法。

pwmSetMode (int mode) ;

PWM發生器可以兩種模式運行-“平衡”和“ mark:space”。mark:space模式是傳統模式,但是Pi的默認模式是“平衡”模式。您可以通過提供參數PWM_MODE_BALPWM_MODE_MS來切換模式。

pwmSetRange (unsigned int range) ;

這將在PWM發生器中設置範圍寄存器。默認值爲1024。

pwmSetClock (int divisor) ;

這將設置PWM時鐘的除數。

注意:在Sys模式下不能使用PWM控制功能。要了解有關PWM系統的更多信息,您需要閱讀Broadcom ARM外設手冊。

piBoardRev (void) ;

這將返回Raspberry Pi的主板修訂版。從1版到2版時,某些BCM_GPIO引腳會更改編號和功能,因此,如果您使用的是BCM_GPIO引腳編號,則需要了解它們之間的區別。

wpiPinToGpio (int wPiPin) ;

此返回供給的BCM_GPIO管腳號wiringPi銷。它考慮了董事會修訂。

physPinToGpio (int physPin) ;

這將返回P1連接器上提供的物理引腳的BCM_GPIO引腳號。

setPadDrive (int group, int value) ;

這爲特定的一組引腳設置了焊盤驅動器的“強度”。有3組引腳,驅動強度爲0到7。除非您知道自己在做什麼,否則請不要使用它。

定時

雖然Linux提供了許多系統調用和功能來提供各種定時和睡眠功能,但有時可能會造成很大的混亂,尤其是如果您是Linux的新手,因此此處介紹的功能模仿了Arduino平臺上可用的功能,從而移植了代碼並編寫新代碼要容易一些。

注意:即使您沒有使用任何輸入/輸出功能,您仍需要調用其中的一項connectionPi設置功能– 如果您不需要在程序中進行超級用戶訪問,請僅使用connectioningPiSetupSys(),並記住#include <wiringPi .h>

unsigned int millis (void)

這將返回一個數字,該數字表示自您的程序調用wireingPiSetup函數之一以來的毫秒數。它返回一個無符號的32位數字,該數字在49天后自動換行。

unsigned int micros (void)

這將返回一個數字,該數字表示自您的程序調用wireingPiSetup函數之一以來的微秒數。它返回一個無符號的32位數字,該數字會在大約71分鐘後自動換行。

void delay (unsigned int howLong)

這將導致程序執行至少暫停 毫秒由於Linux的多任務性質,它可能會更長。請注意,最大延遲是無符號的32位整數或大約49天。

void delayMicroseconds (unsigned int howLong)

這將導致程序執行暫停至少howLong 微秒由於Linux的多任務性質,它可能會更長。請注意,最大延遲是無符號的32位整數微秒或大約71分鐘。

小於100微秒的延遲是通過持續輪詢系統時間的硬編碼循環來計時的,大於100微秒的延遲是使用系統nanosleep()函數完成的–您可能需要考慮非常短的延遲對系統整體性能的影響,尤其是在使用線程的情況下。

 

串口庫

WiringPi包括一個簡化的串行端口處理庫。它可以使用板載串行端口,也可以使用任何沒有特殊區別的USB串行設備。您只需在初始打開功能中指定設備名稱。

若要使用,請確保您的程序包含以下文件:

#include <wiringSerial.h>

然後可以使用以下功能:

int serialOpen (char *device, int baud) ;

這將打開並初始化串行設備並設置波特率。它將端口設置爲“原始”模式(一次爲字符且不進行翻譯),並將讀取超時設置爲10秒。返回值是文件描述符或任何錯誤的-1,在這種情況下,將適當地設置errno

void serialClose (int fd) ;

關閉由給定文件描述符標識的設備。

void  serialPutchar (int fd, unsigned char c) ;

將單個字節發送到給定文件描述符標識的串行設備。

void  serialPuts (int fd, char *s) ;

將以nul結尾的字符串發送到由給定文件描述符標識的串行設備。

void  serialPrintf (int fd, char *message, …) ;

將系統printf功能仿真到串行設備。

int   serialDataAvail (int fd) ;

返回可讀取的字符數,或者對於任何錯誤情況返回-1,在這種情況下,將正確設置errno

int serialGetchar (int fd) ;

返回串行設備上可用的下一個字符。如果沒有可用數據,此調用將最多阻塞10秒鐘(返回-1時)

這裏我想說一句他這裏的阻塞時間太長,最好不要直接調用這個函數,而採用下面的方式

int recbytenum = serialDataAvail(filedevid);
if(recbytenum > 0)
{
	i=0;
	while(recbytenum--)
	{
		buf[i++] = serialGetchar(filedevid);
	}
}
void serialFlush (int fd) ;

這會丟棄接收到的所有數據,或等待向下發送給定設備的所有數據。

注意:返回的文件描述符(fd)是標準的Linux文件描述符。您可以根據需要在此文件描述符上使用標準的read(),write()等系統調用。例如,您可能希望編寫更大的二進制數據塊,其中serialPutchar()或serialPuts()函數可能不是最適合使用的函數,在這種情況下,可以使用write()發送數據。

先進的串口控制

wiringSerial庫旨在提供簡化的控制-適用於大多數應用,但是如果你需要先進的控制- (!通過USB適配器,有沒有對皮的板載UART),例如奇偶性控制,調制解調器控制線等,那麼您需要以“老式”方式進行一些此類操作。

例如–要將串行線設置爲7位模式加上偶數奇偶校驗,您需要執行此操作…

在您的程序中:

#include <termios.h>

並在一個函數中:

  struct termios options ;

  tcgetattr (fd, &options) ;   // Read current options
  options.c_cflag &= ~CSIZE ;  // Mask out size
  options.c_cflag |= CS7 ;     // Or in 7-bits
  options.c_cflag |= PARENB ;  // Enable Parity - even by default
  tcsetattr (fd, &options) ;   // Set new options

 上面的'fd'變量是serialOpen()返回的文件描述符。

有關可以設置的所有選項,請參見tcgetattr的手冊頁。

man tcgetattr

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章