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輸入,其它的部份就依原有的接法即可。
而連接到Raspberry Pi,除了電源線和接地線之外,就只要3條GPIO線:
其實,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處的意思。
(2851)
博客不错,嘎嘎!