一、實驗要求
利用樹莓派驅動數碼管,使數碼管能在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/