樹莓派GPIO入門05-驅動數碼管顯示數字(嵌入式很好的連結平臺,見解深刻)

shengDay發表於2017-10-15

樹莓派GPIO入門05-驅動數碼管顯示數字http://blog.mangolovecarrot.net/2015/05/05/raspi-study05/

這次我們用樹莓派的GPIO口驅動數碼管來顯示數字,進而製作一個簡單的電子鐘,通過按鈕來切換顯示時間或日期。

最終效果

樹莓派GPIO入門05-驅動數碼管顯示數字

硬體

  • 數碼管一隻。因為需要顯示日期時間所以需要能顯示4個數字的數碼管,也稱4位數碼管。淘寶買1塊多錢一隻。注意數碼管有共陽和共陰的。我這裡使用的是共陽的。至於區別,下面的原理說明裡會詳細解釋。
  • 杜邦線若干。
  • 麵包板一塊。
  • 按鈕1只。

原理說明

  • 標準的數碼管從顯示內容上分7段和8段數碼管兩種。8段比7段多一個右下角的小數點。還有一些其他特殊的如可以顯示米字形的數碼管不在本文討論範圍內,其實原理都是一樣的。
  • 8段數碼管由8個發光二極體組成,其中7個用於組成數字,1個用於顯示小數點。每一根的編號如下圖的右上角所示(A-G,DP)。
    4位共陽8段數碼管原理圖
  • 數碼管從電源極性上分共陽和共陰兩種。解釋一下,如果數碼管上每一個獨立的發光二極體都單獨引出兩根引腳,一根接正極(陽)一根接負極(陰),那麼一個8段數碼管就需要16根引腳來控制。但其實這8段數碼管完全可以在內部共用一個陽級,只控制各段發光二極體的陰級聯通即可,這就是共陽。反之亦然,叫共陰。共陽或共陰的每個8段數碼管只需要引出9個引腳,1個陽(陰)級接到樹莓派vcc(gnd)上,另外8個分別連到gpio口上,通過控制io口高低電平即可顯示所需數字。比如一隻共陽數碼管想顯示數字1,看LED編號圖可知需要點亮b段和c段,其他全滅。那麼連到共陽端引腳的io口輸出高電平,連到引腳b、c的io口輸出低電平,連到引腳a、d、e、f、g、dp的io口均輸出高電平即可。寫成程式碼就是:
# 定義各段發光二極體對應的GPIO口
LED_A = 26
LED_B = 19
LED_C = 13
LED_D = 6
LED_E = 5
LED_F = 11
LED_G = 9
LED_DP = 10

# 定義數碼管共陽極對應的GPIO口
VCC = 12

# 避免閃爍,在輸出數字字形訊號前先拉低共陽端,關閉顯示
RPi.GPIO.output(VCC, False)

# 輸出數字1的字形訊號
RPi.GPIO.output(LED_A, True)
RPi.GPIO.output(LED_B, False)
RPi.GPIO.output(LED_C, False)
RPi.GPIO.output(LED_D, True)
RPi.GPIO.output(LED_E, True)
RPi.GPIO.output(LED_F, True)
RPi.GPIO.output(LED_G, True)
RPi.GPIO.output(LED_DP, True)

# 最後拉高共陽段,顯示數字
RPi.GPIO.output(VCC, True)
  • 本文使用的數碼管是8段共陽4位(4個數字)數碼管,型號是F3461BH。上面說了共陽數碼管每個數字需要9個引腳來控制,那麼4個數字就需要36個引腳嗎?顯然不現實,樹莓派的io口也完全不夠用。這就引出另一個概念,靜態顯示和動態掃描顯示。
  • 靜態顯示,就是前面說的每一個數字需要佔用8個io口,每多一個數字就需要額外的8個io口,如果數字位數不多,io口夠用的話,這樣做完全沒問題。實際應用中往往需要顯示多個數字,io口基本上是不夠用的。這就需要動態掃描顯示了。下面摘一段百度百科關於動態掃描顯示的說明(稍有改動):

數碼管動態顯示介面是微控制器中應用最為廣泛的一種顯示方式之一,動態驅動是將所有數碼管的8個顯示筆劃"a,b,c,d,e,f,g,dp"的同名端連在一起引出8個引腳,每個數字再單獨引出共陽(陰)端,這樣總引腳數就只要8 + 數字個數即可,本文使用的8段4位數碼管正是引出了12個引腳。至於哪個引腳對應哪一段,哪幾個引腳分別對應各數字的共陽(陰)端,就需要商家提供電路圖了。當然也可以自己慢慢試,這不在本文討論範圍,大家可以自己摸索。當樹莓派輸出8個段訊號時,所有數碼管都會接收到相同的訊號,但究竟是哪個數碼管會顯示出字形,取決於這個數碼管對應的共陽(陰)極(後統稱位選端)有無導通。所以我們只要將需要顯示的數碼管的位選端選通,該位就顯示出字形,沒有選通的數碼管就不會亮。通過分時輪流控制各個數碼管的的位選端,就使各個數碼管輪流受控顯示,這就是動態驅動。在輪流顯示過程中,每位數碼管的點亮時間為1~2ms,由於人的視覺暫留現象及發光二極體的餘輝效應,儘管實際上各位數碼管並非同時點亮,但只要掃描的速度足夠快,給人的印象就是一組穩定的顯示資料,不會有閃爍感,動態顯示的效果和靜態顯示是一樣的,能夠節省大量的I/O埠,而且功耗更低。

  • 綜上,比如我們想要在4位共陽數碼管上顯示1234這4個數字,要做的就是:
    1. 避免閃爍,在輸出數字字形訊號前先拉低所有4個共陽極,關閉所有顯示。
    2. 拉低1號數碼管的共陽極,關閉顯示。
    3. 輸出1號數碼管上希望顯示的數字字形訊號。
    4. 只拉高1號數碼管的共陽極,讓1號數碼管顯示上面設定好的數字字形。
    5. 延時一段時間(1ms左右)
    6. 拉低1號數碼管的共陽極,關閉顯示。
    7. 輸出2號數碼管上希望顯示的數字字形訊號。
    8. 只拉高2號數碼管的共陽極,讓2號數碼管顯示上面設定好的數字字形。
    9. 延時一段時間(1ms左右)
    10. 拉低2號數碼管的共陽極,關閉顯示。
    11. 輸出3號數碼管上希望顯示的數字字形訊號。
    12. 只拉高3號數碼管的共陽極,讓3號數碼管顯示上面設定好的數字字形。
    13. 延時一段時間(1ms左右)
    14. 拉低3號數碼管的共陽極,關閉顯示。
    15. 輸出4號數碼管上希望顯示的數字字形訊號。
    16. 只拉高4號數碼管的共陽極,讓4號數碼管顯示上面設定好的數字字形。
    17. 延時一段時間(1ms左右)
    18. 返回step2,迴圈執行。
  • 取得日期和時間的方法不是本文的重點,大家自己看程式碼。

硬體連線

硬體連線圖

程式碼

#!/usr/bin/env python
# encoding: utf-8

import RPi.GPIO
import time

# 定義單個數碼管各段led對應的GPIO口
LED_A = 26
LED_B = 19
LED_C = 13
LED_D = 6
LED_E = 5
LED_F = 11
LED_G = 9
LED_DP = 10

# 定義1到4號數碼管陽極對應的GPIO口
DIGIT1 = 12
DIGIT2 = 16
DIGIT3 = 20
DIGIT4 = 21

# 定義按鈕輸入的GPIO口
btn = 27

RPi.GPIO.setmode(RPi.GPIO.BCM)

RPi.GPIO.setup(LED_A, RPi.GPIO.OUT)
RPi.GPIO.setup(LED_B, RPi.GPIO.OUT)
RPi.GPIO.setup(LED_C, RPi.GPIO.OUT)
RPi.GPIO.setup(LED_D, RPi.GPIO.OUT)
RPi.GPIO.setup(LED_E, RPi.GPIO.OUT)
RPi.GPIO.setup(LED_F, RPi.GPIO.OUT)
RPi.GPIO.setup(LED_G, RPi.GPIO.OUT)
RPi.GPIO.setup(LED_DP, RPi.GPIO.OUT)
RPi.GPIO.setup(DIGIT1, RPi.GPIO.OUT)
RPi.GPIO.setup(DIGIT2, RPi.GPIO.OUT)
RPi.GPIO.setup(DIGIT3, RPi.GPIO.OUT)
RPi.GPIO.setup(DIGIT4, RPi.GPIO.OUT)

RPi.GPIO.output(DIGIT1, True)
RPi.GPIO.output(DIGIT2, True)
RPi.GPIO.output(DIGIT3, True)
RPi.GPIO.output(DIGIT4, True)

RPi.GPIO.setup(btn, RPi.GPIO.IN, pull_up_down=RPi.GPIO.PUD_UP)

# 指定no(1-4)號數碼管顯示數字num(0-9),第三個引數是顯示不顯示小數點(true/false)
def showDigit(no, num, showDotPoint):
    # 先將正極拉低,關掉顯示
    RPi.GPIO.output(DIGIT1, False)
    RPi.GPIO.output(DIGIT2, False)
    RPi.GPIO.output(DIGIT3, False)
    RPi.GPIO.output(DIGIT4, False)
    
    if (num == 0) :
        RPi.GPIO.output(LED_A, False)
        RPi.GPIO.output(LED_B, False)
        RPi.GPIO.output(LED_C, False)
        RPi.GPIO.output(LED_D, False)
        RPi.GPIO.output(LED_E, False)
        RPi.GPIO.output(LED_F, False)
        RPi.GPIO.output(LED_G, True)
        RPi.GPIO.output(LED_DP, not showDotPoint)
    elif (num == 1) :
        RPi.GPIO.output(LED_A, True)
        RPi.GPIO.output(LED_B, False)
        RPi.GPIO.output(LED_C, False)
        RPi.GPIO.output(LED_D, True)
        RPi.GPIO.output(LED_E, True)
        RPi.GPIO.output(LED_F, True)
        RPi.GPIO.output(LED_G, True)
        RPi.GPIO.output(LED_DP, not showDotPoint)
    elif (num == 2) :
        RPi.GPIO.output(LED_A, False)
        RPi.GPIO.output(LED_B, False)
        RPi.GPIO.output(LED_C, True)
        RPi.GPIO.output(LED_D, False)
        RPi.GPIO.output(LED_E, False)
        RPi.GPIO.output(LED_F, True)
        RPi.GPIO.output(LED_G, False)
        RPi.GPIO.output(LED_DP, not showDotPoint)
    elif (num == 3) :
        RPi.GPIO.output(LED_A, False)
        RPi.GPIO.output(LED_B, False)
        RPi.GPIO.output(LED_C, False)
        RPi.GPIO.output(LED_D, False)
        RPi.GPIO.output(LED_E, True)
        RPi.GPIO.output(LED_F, True)
        RPi.GPIO.output(LED_G, False)
        RPi.GPIO.output(LED_DP, not showDotPoint)
    elif (num == 4) :
        RPi.GPIO.output(LED_A, True)
        RPi.GPIO.output(LED_B, False)
        RPi.GPIO.output(LED_C, False)
        RPi.GPIO.output(LED_D, True)
        RPi.GPIO.output(LED_E, True)
        RPi.GPIO.output(LED_F, False)
        RPi.GPIO.output(LED_G, False)
        RPi.GPIO.output(LED_DP, not showDotPoint)
    elif (num == 5) :
        RPi.GPIO.output(LED_A, False)
        RPi.GPIO.output(LED_B, True)
        RPi.GPIO.output(LED_C, False)
        RPi.GPIO.output(LED_D, False)
        RPi.GPIO.output(LED_E, True)
        RPi.GPIO.output(LED_F, False)
        RPi.GPIO.output(LED_G, False)
        RPi.GPIO.output(LED_DP, not showDotPoint)
    elif (num == 6) :
        RPi.GPIO.output(LED_A, False)
        RPi.GPIO.output(LED_B, True)
        RPi.GPIO.output(LED_C, False)
        RPi.GPIO.output(LED_D, False)
        RPi.GPIO.output(LED_E, False)
        RPi.GPIO.output(LED_F, False)
        RPi.GPIO.output(LED_G, False)
        RPi.GPIO.output(LED_DP, not showDotPoint)
    elif (num == 7) :
        RPi.GPIO.output(LED_A, False)
        RPi.GPIO.output(LED_B, False)
        RPi.GPIO.output(LED_C, False)
        RPi.GPIO.output(LED_D, True)
        RPi.GPIO.output(LED_E, True)
        RPi.GPIO.output(LED_F, True)
        RPi.GPIO.output(LED_G, True)
        RPi.GPIO.output(LED_DP, not showDotPoint)
    elif (num == 8) :
        RPi.GPIO.output(LED_A, False)
        RPi.GPIO.output(LED_B, False)
        RPi.GPIO.output(LED_C, False)
        RPi.GPIO.output(LED_D, False)
        RPi.GPIO.output(LED_E, False)
        RPi.GPIO.output(LED_F, False)
        RPi.GPIO.output(LED_G, False)
        RPi.GPIO.output(LED_DP, not showDotPoint)
    elif (num == 9) :
        RPi.GPIO.output(LED_A, False)
        RPi.GPIO.output(LED_B, False)
        RPi.GPIO.output(LED_C, False)
        RPi.GPIO.output(LED_D, False)
        RPi.GPIO.output(LED_E, True)
        RPi.GPIO.output(LED_F, False)
        RPi.GPIO.output(LED_G, False)
        RPi.GPIO.output(LED_DP, not showDotPoint)
    
    if (no == 1) :
        RPi.GPIO.output(DIGIT1, True)
    elif (no == 2) :
        RPi.GPIO.output(DIGIT2, True)
    elif (no == 3) :
        RPi.GPIO.output(DIGIT3, True)
    elif (no == 4) :
        RPi.GPIO.output(DIGIT4, True)

try:
    t=0.005
    while True:
        # 按鈕按下時顯示日期,否則顯示時間
        # 為了區別左右的數字,讓第二個數碼管的小數點顯示出來
        #(本來應該是一個冒號,我們這個數碼管沒有,就用小數點代替了)
        if (RPi.GPIO.input(btn) == 1):
            time.sleep(t)
            showDigit(1, int(time.strftime("%H",time.localtime(time.time()))) / 10, False)
            time.sleep(t)
            showDigit(2, int(time.strftime("%H",time.localtime(time.time()))) % 10, True)
            time.sleep(t)
            showDigit(3, int(time.strftime("%M",time.localtime(time.time()))) / 10, False)
            time.sleep(t)
            showDigit(4, int(time.strftime("%M",time.localtime(time.time()))) % 10, False)
        else:
            time.sleep(t)
            showDigit(1, int(time.strftime("%m",time.localtime(time.time()))) / 10, False)
            time.sleep(t)
            showDigit(2, int(time.strftime("%m",time.localtime(time.time()))) % 10, True)
            time.sleep(t)
            showDigit(3, int(time.strftime("%d",time.localtime(time.time()))) / 10, False)
            time.sleep(t)
            showDigit(4, int(time.strftime("%d",time.localtime(time.time()))) % 10, False)
            
except KeyboardInterrupt:
    pass

# 最後清理GPIO口(不做也可以,建議每次程式結束時清理一下,好習慣)
RPi.GPIO.cleanup()

效能改善

當你照著這篇文章成功在數碼管上顯示出數字後,你可能會鬱悶的發現數字有一點點閃爍,顯示的不是非常穩定,這種情況在樹莓派1代上更明顯。

  • python庫對gpio口不停操作時對cpu的佔用率很高,而一旦cpu的佔用率一高,就不能保證延時函式的準確性,而在動態掃描時延時的不準確會導致數碼管的亮度不穩定,比如第一隻數碼管顯示了2ms而第二隻顯示了1ms的話,第一隻數碼管的亮度就會略高於第二隻數碼管,而參差不齊的延時最後就表現為數字顯示有閃爍的感覺。
  • python庫本身翻轉gpio口的效率就不高,有興趣可以參照這個頁面,有各種語言各種庫對gpio的操作速度比較。比較結果是c的wiringPi庫完勝其他方式。其實python庫已經是表現不錯的了,但還是被c甩了N條街。python翻轉io口的頻率在70kHz左右,而wiringPi則可以達到4MHz!這個已經是數量級上的差距了。
  • 抱著試一試的心情,我用c語言的wiringPi庫把上面這個程式重寫了一遍,程式碼是這個樣子的:
#include <wiringPi.h>
#include <unistd.h>
#include <time.h>

// 定義單個數碼管各段led對應的GPIO口
// 使用命令 "gpio readall" 來獲取當前pi版本對應的各引腳的wiringPi和BCM的編號
// 再本程式中應該使用wiringPi編號
// 我的pi2 Mode B執行結果如下:(wPi列就是wiringPi編號)
// 之前Python版本的程式碼使用的是BCM編號,所以在不改變硬體接線的情況下,我們需要把原來BCM編號改成對應的wiringPi編號。
/* 
 +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5V      |     |     |
 |   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 1 | ALT0 | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | ALT0 | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |  OUT | 0 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 0 | 23 || 24 | 1 | IN   | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | IN   | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+
*/

#define LED_A 25 //BCM:26
#define LED_B 24 //BCM:19
#define LED_C 23 //BCM:13
#define LED_D 22 //BCM:6
#define LED_E 21 //BCM:5
#define LED_F 14 //BCM:11
#define LED_G 13 //BCM:9
#define LED_DP 12 //BCM:10

// 定義1到4號數碼管陽極對應的GPIO口
#define DIGIT1 26 //BCM:12
#define DIGIT2 27 //BCM:16
#define DIGIT3 28 //BCM:20
#define DIGIT4 29 //BCM:21

// 定義按鈕輸入的GPIO口
#define btn 2 //BCM:27

#define FALSE 0
#define TRUE  1

#define t 5000 //usleep延時長度(單位um微秒,1000um=1ms,1000ms=1s)

// 指定no(1-4)號數碼管顯示數字num(0-9),第三個引數是顯示不顯示小數點(1/0)
void showDigit(int no, int num, int showDotPoint);

time_t now;
struct tm *tm_now;

int main (void) {
  wiringPiSetup () ;

  pinMode (LED_A, OUTPUT) ;
  pinMode (LED_B, OUTPUT) ;
  pinMode (LED_C, OUTPUT) ;
  pinMode (LED_D, OUTPUT) ;
  pinMode (LED_E, OUTPUT) ;
  pinMode (LED_F, OUTPUT) ;
  pinMode (LED_G, OUTPUT) ;
  pinMode (LED_DP, OUTPUT) ;

  pinMode (DIGIT1, OUTPUT) ;
  pinMode (DIGIT2, OUTPUT) ;
  pinMode (DIGIT3, OUTPUT) ;
  pinMode (DIGIT4, OUTPUT) ;

  pinMode (btn, INPUT) ;
  pullUpDnControl (btn, PUD_UP) ;

  digitalWrite (DIGIT1, HIGH) ;
  digitalWrite (DIGIT2, HIGH) ;
  digitalWrite (DIGIT3, HIGH) ;
  digitalWrite (DIGIT4, HIGH) ;

  for (; ; )
  {
    time(&now);
    tm_now=localtime(&now);

    // 按鈕按下時顯示日期,否則顯示時間
    // 為了區別左右的數字,讓第二個數碼管的小數點顯示出來
    //(本來應該是一個冒號,我們這個數碼管沒有,就用小數點代替了)
    if (digitalRead(btn) == HIGH) {
      usleep(t);
      showDigit(1, tm_now->tm_hour / 10, FALSE);
      usleep(t);
      showDigit(2, tm_now->tm_hour % 10, TRUE);
      usleep(t);
      showDigit(3, tm_now->tm_min / 10, FALSE);
      usleep(t);
      showDigit(4, tm_now->tm_min % 10, FALSE);
    } else {
      // 取得的月份和日期都是從0開始的,所以顯示前需要加1
      usleep(t);
      showDigit(1, (tm_now->tm_mon+1) / 10, FALSE);
      usleep(t);
      showDigit(2, (tm_now->tm_mon+1) % 10, TRUE);
      usleep(t);
      showDigit(3, (tm_now->tm_mday+1) / 10, FALSE);
      usleep(t);
      showDigit(4, (tm_now->tm_mday+1) % 10, FALSE);
    }
  }
  return 0 ;
}

void showDigit(int no, int num, int showDotPoint) {
  // 先將正極拉低,關掉顯示
  digitalWrite (DIGIT1, LOW) ;
  digitalWrite (DIGIT2, LOW) ;
  digitalWrite (DIGIT3, LOW) ;
  digitalWrite (DIGIT4, LOW) ;

  if (num == 0) {
    digitalWrite (LED_A, LOW) ;
    digitalWrite (LED_B, LOW) ;
    digitalWrite (LED_C, LOW) ;
    digitalWrite (LED_D, LOW) ;
    digitalWrite (LED_E, LOW) ;
    digitalWrite (LED_F, LOW) ;
    digitalWrite (LED_G, HIGH) ;
  } else if (num == 1) {
    digitalWrite (LED_A, HIGH) ;
    digitalWrite (LED_B, LOW) ;
    digitalWrite (LED_C, LOW) ;
    digitalWrite (LED_D, HIGH) ;
    digitalWrite (LED_E, HIGH) ;
    digitalWrite (LED_F, HIGH) ;
    digitalWrite (LED_G, HIGH) ;
  } else if (num == 2) {
    digitalWrite (LED_A, LOW) ;
    digitalWrite (LED_B, LOW) ;
    digitalWrite (LED_C, HIGH) ;
    digitalWrite (LED_D, LOW) ;
    digitalWrite (LED_E, LOW) ;
    digitalWrite (LED_F, HIGH) ;
    digitalWrite (LED_G, LOW) ;
  } else if (num == 3) {
    digitalWrite (LED_A, LOW) ;
    digitalWrite (LED_B, LOW) ;
    digitalWrite (LED_C, LOW) ;
    digitalWrite (LED_D, LOW) ;
    digitalWrite (LED_E, HIGH) ;
    digitalWrite (LED_F, HIGH) ;
    digitalWrite (LED_G, LOW) ;
  } else if (num == 4) {
    digitalWrite (LED_A, HIGH) ;
    digitalWrite (LED_B, LOW) ;
    digitalWrite (LED_C, LOW) ;
    digitalWrite (LED_D, HIGH) ;
    digitalWrite (LED_E, HIGH) ;
    digitalWrite (LED_F, LOW) ;
    digitalWrite (LED_G, LOW) ;
  } else if (num == 5) {
    digitalWrite (LED_A, LOW) ;
    digitalWrite (LED_B, HIGH) ;
    digitalWrite (LED_C, LOW) ;
    digitalWrite (LED_D, LOW) ;
    digitalWrite (LED_E, HIGH) ;
    digitalWrite (LED_F, LOW) ;
    digitalWrite (LED_G, LOW) ;
  } else if (num == 6) {
    digitalWrite (LED_A, LOW) ;
    digitalWrite (LED_B, HIGH) ;
    digitalWrite (LED_C, LOW) ;
    digitalWrite (LED_D, LOW) ;
    digitalWrite (LED_E, LOW) ;
    digitalWrite (LED_F, LOW) ;
    digitalWrite (LED_G, LOW) ;
  } else if (num == 7) {
    digitalWrite (LED_A, LOW) ;
    digitalWrite (LED_B, LOW) ;
    digitalWrite (LED_C, LOW) ;
    digitalWrite (LED_D, HIGH) ;
    digitalWrite (LED_E, HIGH) ;
    digitalWrite (LED_F, HIGH) ;
    digitalWrite (LED_G, HIGH) ;
  } else if (num == 8) {
    digitalWrite (LED_A, LOW) ;
    digitalWrite (LED_B, LOW) ;
    digitalWrite (LED_C, LOW) ;
    digitalWrite (LED_D, LOW) ;
    digitalWrite (LED_E, LOW) ;
    digitalWrite (LED_F, LOW) ;
    digitalWrite (LED_G, LOW) ;
  } else if (num == 9) {
    digitalWrite (LED_A, LOW) ;
    digitalWrite (LED_B, LOW) ;
    digitalWrite (LED_C, LOW) ;
    digitalWrite (LED_D, LOW) ;
    digitalWrite (LED_E, HIGH) ;
    digitalWrite (LED_F, LOW) ;
    digitalWrite (LED_G, LOW) ;
  }
  
  if (showDotPoint == 1) {
    digitalWrite (LED_DP, LOW) ;
  } else {
    digitalWrite (LED_DP, HIGH) ;
  }

  if (no == 1) {
    digitalWrite (DIGIT1, HIGH) ;
  } else if (no == 2) {
    digitalWrite (DIGIT2, HIGH) ;
  } else if (no == 3) {
    digitalWrite (DIGIT3, HIGH) ;
  } else if (no == 4) {
    digitalWrite (DIGIT4, HIGH) ;
  }
}
  • c的wiringPi庫的安裝和程式碼的編譯執行方法請自行百度。

  • c語言測試結果是顯示穩定了很多,但仍然有一點不穩定不仔細觀察基本看不出來了。這個應該跟我程式碼的效率有關,邏輯應該還可以精簡節省cpu資源。這個以後再試了。我們這個系列主要是讓大家瞭解各種基本外設感測器的原理和使用方法。用c語言也只是做一點延伸,以後的教程還是以python為主。

原始碼下載

點選下載Python原始碼
點選下載c原始碼


相關文章