2013年4月21日 星期日

Raspberry Pi 硬體控制-- C 語言篇


上一篇我們用了Python語言來控制GPIO功能, 本篇接著下來討論如何使用C語言來控制GPIO功能。按照Benchmarking Raspberry Pi GPIO Speed這篇文章所述,如果你的需求是在控制硬體上反應速度快的話 C 語言就很適合了。
Raspberry Pi目前網路上資料中,用C來控制GPIO硬體大致上有兩個專案的資源比較完整,一個是WiringPi專案;另一個是bcm2835專案。兩者不同專案的差別在於上述的Benchmark反應時間,看起來WiringPi所寫的程式反應時間是最快的了。
所以本篇就透過WiringPi實作一下用C語言來控制GPIO。


實作環境、電路圖跟上一篇一樣,這裡就不再詳述。實作步驟如下:

安裝WiringPi
官網中有兩種方式安裝,一種使用的是GIT方式;另一種使用的是下載包方式,兩者選擇其一即可。
由於我使用的是第一種GIT方式,所以要先安裝GIT相關套件:
sudo apt-get install git-core

接著更新最新的套件資訊及套件軟體
sudo apt-get update && sudo apt-get -y upgrade

用GIT取得WiringPi:
git clone git://git.drogon.net/wiringPi

當GIT下載完成後會出現一個wiringPi目錄,接著執行下列指令:
cd wiringPi
git pull origin

這個時候wiringPi內會出現最新版本的軟體,然後這個目錄下執行:
cd wiringPi
./build

當指令執行結束後便完成安裝WiringPi步驟。
至於第二種方式,我就沒試過了詳細安裝說明可以參考官方網站

撰寫程式:
當安裝完成WiringPi函式庫後,接下來用文字編輯器命名一個檔案名稱為HelloTest.c ,內容如下:

#include <wiringPi.h>
#include <stdlib.h>
#include <stdio.h>

#define LED     1         //wiringPi pin 1 is BCM_GPIO 18.
#define BUTTON  6  //wiringPi pin 6 is BCM_GPIO 22 25.
void all_leds_off();
void init_pins();

int main (void) {
  printf ("Raspberry Pi - Button and Blink\n") ;
  //Check we have wiringPi
  if (wiringPiSetup () == -1 ) exit (1);
  init_pins();
  all_leds_off();
  int i = 0;
  for (;;) {
    if (digitalRead (BUTTON) == 0 ) {
        i++;
        printf ("Button pressed (%d)\n", i) ;
        digitalWrite (LED,1);
        delay (100);
    }
    all_leds_off();
    delay (50);
  }
}

void init_pins() {
  //set led as outputs...
  printf ("Setup Pin 12 is Output...\n") ;
  pinMode(LED, OUTPUT);

  // set button as an input...
  printf ("Setup Pin 22 is Input..\n") ;
  pinMode(BUTTON, INPUT);
}

void all_leds_off() {
    digitalWrite (LED,0);
}


接著gcc編譯程式:
gcc -o HelloTest HelloTest.c -lwiringPi

然後執行 :
sudo ./HelloTest

執行結果與上一篇中的第三個結果一樣程式透過一個無窮迴圈在每隔0.05秒鐘偵測按鍵是否按下,當按下按鈕後點亮LED 0.1秒,欲離開程式按下CTRL-C即可。


上述程式由於include wiringPi.h的函式庫,透過
wiringPiSetup () -- 檢查是否有WiringPi並允需程式使用它。
pinMode() -- 指定Pin腳為輸入/輸出狀態。
digitalWrite() -- 輸出或偵測輸入一個值( 0 或 1)  到 pin腳。

另外WiringPi定義的GPIO pin腳位與Python或其他的定義不同,請參考下表。
(出處:Raspberry Pi GPIO Pins @ Drogon)

參考資料:
1.WiringPi
https://projects.drogon.net/raspberry-pi/

2.bcm2835
http://www.airspayce.com/mikem/bcm2835/index.html

3.RPi Low-level peripherals
http://elinux.org/RPi_Low-level_peripherals#GPIO_Driving_Example_.28C.29

4.Download and Install - WiringPi
https://projects.drogon.net/raspberry-pi/wiringpi/download-and-install/

5. Blink - WiringPi
https://projects.drogon.net/raspberry-pi/gertboard-and-wiringpi/blink/


6. Raspberry Pi GPIO Pins - WiringPi
https://projects.drogon.net/raspberry-pi/wiringpi/pins/

==============延伸閱讀=====================
1. Raspberry Pi 第一次接觸
http://cheng-min-i-taiwan.blogspot.tw/2013/02/raspberry-pi.html

2.Raspberry Pi 網路設定
http://cheng-min-i-taiwan.blogspot.tw/2013/02/raspberry-pi_23.html

3.Raspberry Pi 應用之Windows檔案伺服器
http://cheng-min-i-taiwan.blogspot.tw/2013/02/raspberry-pi-windows.html

4.Raspberry Pi 應用之DLNA影音伺服器
http://cheng-min-i-taiwan.blogspot.tw/2013/02/raspberry-pi-dlna.html

5.Raspberry Pi 硬體控制-- Python 語言篇
http://cheng-min-i-taiwan.blogspot.tw/2013/04/raspberry-pi-python.html

6.Raspberry Pi 硬體控制-- C 語言篇
http://cheng-min-i-taiwan.blogspot.tw/2013/04/raspberry-pi-c.html

7.Raspberry Pi 2 Model B 使用心得
http://www.cheng-min-i-taiwan.blogspot.tw/2015/02/raspberry-pi-2-model-b.html

8.Raspberry Pi 藍牙4.0應用之iBeacon 發射器
http://www.cheng-min-i-taiwan.blogspot.tw/2015/03/raspberry-pi-40ibeacon.html

9.Raspberry Pi安裝MQTT之應用 -- Android訊息推播
http://www.cheng-min-i-taiwan.blogspot.tw/2015/03/raspberry-pimqtt-android.html

10. Raspberry Pi安裝MQTT之IoT應用 -- Android示範
http://cheng-min-i-taiwan.blogspot.tw/2015/03/raspberry-pimqttiot-android.html#more

8 則留言:

  1. 可以幫我看一下這篇的LOG嗎?這是您3月所PO的文章。
    http://cheng-min-i-taiwan.blogspot.tw/2012/01/android-bluetooth-hellobtuartrs-232.html

    回覆刪除
  2. 版主你好:
    我有依照你的程序完成安裝WiringPi
    但是gcc compile error message as below ::
    hellotest.c:(.text+0x14):undefined reference to 'wiringPiSetup'
    :undefined reference to 'digitalRead'
    :undefined reference to 'digitalWrite'
    :undefined reference to 'delay'
    :undefined reference to 'pinMode'
    do you have any comments ?
    Thanks.
    B.R. rodney131@gmail.com

    回覆刪除
    回覆
    1. 1.確認是否有include wiringPi.h
      2.確認WiringPi的函式庫有沒裝好,錯誤訊息是沒有找到wiringPiSetup(),你確認一下安裝步驟是否有問題,如果還是同樣錯誤你試試看官網上第二種方法看看!!(文章中有連結..)

      刪除
  3. 好像有寫錯 pin mapping
    //wiringPi pin 6 is BCM_GPIO 22. <-- 這一行有錯
    //wiringPi pin 6 is BCM_GPIO 25 or header pin 22. <-- 這才是正確的

    回覆刪除
  4. 版主你好,最近剛接觸樹莓派,在做這個練習的時候到最後一步驟 sudo ./HelloTest時會出現 sudo: ./HelloTest: command not found 這個問題,剛接觸,不知道怎麼排除。不好意思!!

    回覆刪除
    回覆
    1. 這個是找不到你編譯後的HelloTest,用ls確認一下在你的目錄下有沒有該檔案。

      刪除