Raspberry Pi Model B+擁有40個PIN,其有20幾個GPIO,在大部份的情形下其實是夠用了。可是,一台樹莓派不便宜,如果要放在需要控制很多元件的場所,其實要好好的發揮其用處才行。例如,一個7段顯示器需要有7個信號來控制,理論上,把a~g等7個LED都接上GPIO,也是可以透過GPIO來顯示任意的數字,但是,這樣一個7段顯示器就會用掉7個GPIO的針腳,也就是一台樹莓派如果用這種方式的話,那麼總共也只能輸出大約3個7段顯示器所組成的數字。

反之,如果善用7447這顆BCD轉7段顯示器的IC,那麼就可以使用4個資料輸入訊號,轉換成7段顯示器可以顯示的數字,那麼一個7段顯示器只要使用4條信號線就可以了。這也是作者之前這篇文章【使用7447控制7段顯示器】所介紹的內容。而在這篇文章【使用74595控制8個LED】中,我們瞭解到74959這顆Shift Register位移暫存器IC,可以使用3個GPIO控制8個LED,不知道讀者有沒有想到什麼了?沒錯,8個輸出即可當做2個7447的BCD輸入端,也就是1個74595連接2個7447,其中一個使用位元組中的高位元nibble,而另外一個使用低位元部份的nibble,如此,就可以達成用3個GPIO獨立控制2個7段顯示器數字的目標了。先看以下的影片:

在這個範例中,我們讓2個數字其中一個正數,另外一個倒數,當然,如果程式做修改,它們可以各自顯示不同的數字,完全可以獨立運作。那麼如何達成呢?

首先,硬體連接的部份,整合前面2篇文章的內容,由於74595和7447都是TTL IC,所以,在本篇文章【使用74595控制8個LED】中,原本74595輸出到LED的部份,不需要串接任何電阻,直接把它們高位元的nibble4個位元依序連接到其中一顆7447的ABCD輸入,而另外低位元的nibble 4個位元依序接到另外一顆7447的ABCD輸入,其它的部份就依原有的接法即可。

2016-07-01 20.10.09

而連接到Raspberry Pi,除了電源線和接地線之外,就只要3條GPIO線:

2016-07-01 20.10.23

其實,Raspberry Pi最重要的是軟體的部份,因為只要硬碟接好線確定可以運作之後,其它的部份,其實都用軟體控制即可。上述影片的程式如下所示:

import RPi.GPIO as gpio
import time

DS = 22
LTH = 18
CLK = 16
DLY = 0.01
gpio.setwarnings(False)
gpio.setmode(gpio.BOARD)
gpio.setup(DS, gpio.OUT)
gpio.setup(LTH, gpio.OUT)
gpio.setup(CLK, gpio.OUT)

def clk():
    gpio.output(CLK, gpio.HIGH)
    time.sleep(DLY)
    gpio.output(CLK, gpio.LOW)

def clear_output():
    for i in range(8):
        gpio.output(DS, gpio.LOW)
        clk()
    data_out()

def data_out():
    gpio.output(LTH, gpio.HIGH)
    time.sleep(DLY)
    gpio.output(LTH, gpio.LOW)

def bit_input(b):
    gpio.output(DS, b & True)
    clk()
       

def digit_output(num):
    bin = list()
    while num > 0:
        bin.append(num % 2)
        num = num / 2
    for i in range(8-len(bin)):
        bin.append(0)
    bin.reverse()
    for b in bin:
        bit_input(b)
    data_out()

clear_output()
for n in range(10):
    for i in range(10):
        digit_output((9-i)*16+i)
        time.sleep(1)
clear_output()
gpio.cleanup()

主要是修改自上一篇文章程式的內容,前面的設定是一樣的,而clk()、clear_output()、bit_input()以及data_out()也是都一樣。但是,在digit_output()函數我們做了一些修改。主要的原因是,之前要控制LED時,10進位轉換為2進位之後,由於之前有清過輸出了,所以有多少位元轉換多少位元就好了。例如10進位的5,只要轉換為二進位的101,而9則轉換為1001,位數不同沒關係。但是,現在這個例子不一樣,因為8個位元全部用上,如果低位元組的部份轉換位數不足4位,就沒辦法把高位元組推到正確的位置上。因此,所有的轉換一定要正確地轉換為8個位元才行。因此,此函數如果輸入是10進位的數字5,轉換後必須是00000101才行。我們在digit_output(num)函數中,用一個for迴圈來把字數補足。

而在本程式的倒數第4行digit_output((9-i)*16+i),其實就是如果我們要輸出2個數字分別到不同的2個7段顯示器,假設其中一個是d1,另外一個是d2,則輸出時就是使用digit_output(d1*16+d2)即可。為什麼是乘上16?因為16就是2的4次方,也就相當於是把數字上移到高位元的nibble處的意思。

(1197)

%d 位部落客按了讚: