樹莓派GPIO入門(四) :用數碼管做個簡單的計數器

一、實驗要求

利用樹莓派驅動數碼管,使數碼管能在0000-9999之間進行計數,當按下按鍵時,數值會清零。

二、實驗材料

  • 按鍵1個
  • 4位8段數碼管(共陰極) 1個
  • 杜邦線若干
  • 樹莓派4B、RPi.GPIO庫

三、數碼管簡介

(1)一般來說,標準的數碼管從顯示內容上分7段和8段數碼管兩種。8段比7段多一個右下角的小數點。8段數碼管由8個發光二極管組成,其中7個用於組成數字,1個用於顯示小數點。每一根的編號如下圖的右上角所示(A-G,DP)。

(2)數碼管從電源極性上分共陽和共陰兩種。如果數碼管上每一個獨立的發光二極管都單獨引出兩根引腳,一根接正極(陽)一根接負極(陰),那麼一個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口均輸出高電平即可。

四、動態掃描顯示

 數碼管動態顯示接口是單片機中應用最爲廣泛的一種顯示方式之一,動態驅動是將所有數碼管的8個顯示筆劃"a,b,c,d,e,f,g,dp"的同名端連在一起引出8個引腳,每個數字再單獨引出共陽(陰)端,這樣總引腳數就只要8 + 數字個數即可,本文使用的8段4位數碼管正是引出了12個引腳。至於哪個引腳對應哪一段,哪幾個引腳分別對應各數字的共陽(陰)端,就需要商家提供電路圖了。

當樹莓派輸出8個段信號時,所有數碼管都會接收到相同的信號,但究竟是哪個數碼管會顯示出字形,取決於這個數碼管對應的共陽(陰)極(後統稱位選端)有無導通。所以我們只要將需要顯示的數碼管的位選端選通,該位就顯示出字形,沒有選通的數碼管就不會亮。通過分時輪流控制各個數碼管的的位選端,就使各個數碼管輪流受控顯示,這就是動態驅動。

在輪流顯示過程中,每位數碼管的點亮時間爲1~2ms,由於人的視覺暫留現象及發光二極管的餘輝效應,儘管實際上各位數碼管並非同時點亮,但只要掃描的速度足夠快,給人的印象就是一組穩定的顯示數據,不會有閃爍感,動態顯示的效果和靜態顯示是一樣的,能夠節省大量的I/O端口,而且功耗更低。

五、實驗代碼

import RPi.GPIO as GPIO 
import time

GPIO.setmode(GPIO.BCM)

# 定義單個數碼管各段led對應的GPIO口
LED_A = 26
LED_B = 19
LED_C = 13
LED_D = 6
LED_E = 5
LED_F = 22
LED_G = 27
LED_pins = [LED_A,LED_B,LED_C,LED_D,LED_E,LED_F,LED_G]

# 定義1到4號數碼管陰極對應的GPIO口
DIG1 = 12
DIG2 = 16
DIG3 = 20
DIG4 = 21
All_dig = [DIG1, DIG2, DIG3, DIG4]
All_pins = [LED_A,LED_B,LED_C,LED_D,LED_E,LED_F,LED_G,DIG1,DIG2,DIG3,DIG4]

# 定義按鈕輸入的GPIO口
btn = 24
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_UP)  #在24號引腳處設置上拉電阻

#將數碼管LED段引腳設置爲輸出模式
GPIO.setup(All_pins, GPIO.OUT)


#0-9的各段LED狀態,1表示高電平,0表示低電平
zero = [1, 1, 1, 1, 1, 1, 0]
one = [0, 1, 1, 0, 0, 0, 0]
two = [1, 1, 0, 1, 1, 0, 1]
three = [1, 1, 1, 1, 0, 0, 1]
four = [0, 1, 1, 0, 0, 1, 1]
five = [1, 0, 1, 1, 0, 1, 1]
six = [1, 0, 1, 1, 1, 1, 1]
seven = [1, 1, 1, 0, 0, 0, 0]
eight = [1, 1, 1, 1, 1, 1, 1]
nine = [1, 1, 1, 1, 0, 1, 1]



#初始化,讓所有LED段熄滅狀態
GPIO.output(All_pins, False)

def showDigit(order, num):
    # 先將負極拉高,關掉顯示
    GPIO.output(All_dig, True)
    
    if (num == 0):
        GPIO.output(LED_pins, zero)    
    elif (num == 1):
        GPIO.output(LED_pins, one)    
    elif (num == 2):
        GPIO.output(LED_pins, two)    
    elif (num == 3):        
        GPIO.output(LED_pins, three)    
    elif (num == 4):
        GPIO.output(LED_pins, four)    
    elif (num == 5):
        GPIO.output(LED_pins, five)    
    elif (num == 6):
        GPIO.output(LED_pins, six)    
    elif (num == 7):
        GPIO.output(LED_pins, seven)    
    elif (num == 8):
        GPIO.output(LED_pins, eight)    
    elif (num == 9):
        GPIO.output(LED_pins, nine)    
    
    if (order == 1):
        GPIO.output(DIG1, False)
    elif (order == 2):
        GPIO.output(DIG2, False)
    elif (order == 3):
        GPIO.output(DIG3, False)
    elif (order == 4):
        GPIO.output(DIG4, False)
        
try:
    t=0.005
    start = time.time()
    while True:
        if (GPIO.input(btn) == 0):
            time.sleep(t)
            start = time.time()
        else:
            now = time.time()
            count = now - start            
            time.sleep(t)
            showDigit(1, int(count / 1000))       
            time.sleep(t)
            showDigit(2, int(count % 1000 / 100))   
            time.sleep(t)
            showDigit(3, int(count % 100 / 10)) 
            time.sleep(t)
            showDigit(4, int(count % 10))           
except KeyboardInterrupt:
    pass
GPIO.cleanup()  #最後清理GPIO口

六、視頻演示

七、參考資料

http://blog.mangolovecarrot.net/2015/05/05/raspi-study05/

 

 

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