top of page
搜尋
作家相片Ting Chun Liu

Raspberry Pi 移位暫存器 (shift register) 控制 / 七段顯示器使用

本篇來寫寫當初在月津港(現在在台北數位藝術中心展覽的數位藝術家)很猛的架結構的林瑜亮、跟負責電路板製作焊接(月薪很高小公主)李翎暄跟很廢的我,含辛茹苦的花了18萬的裝置。如何Hardcore的使用python GPIO功能控制移位暫存器,python GPIO的code部分就不多做說明,可以看前面幾篇文章轉換成Arduino,然後這篇也會稍微解釋Latch, Clock, Data三個名稱,以及很簡單很簡單的在這邊使用位元運算。我很廢在此拋磚引玉,還請大大指正。


適用晶片是TPIC6C594,還有74HC595或各種場合燈節超級萬用的燈條WS2812也可以使用同樣方式(還有還有其他的移位暫存器晶片,例如可以控制16個輸出的STP16C596,只是我沒用過不多說)


(這篇先私心問一下 Wix SEO有沒有有經驗的人會用QQ 我發現在wix寫的blog,google都搜不到)



直接控制移位暫存器的好處,是如果沒有適當library(如Arduino的FastLED或Adafruit_NeoPixel)才需要使用。另外如果使用arduino firmata的話也可以用這種方式控制。就可以直接在processing呼叫arduino使用ws2812做mapping唷~~


TPIC6C594非常類似74HC595,只是當需要驅動LED的電壓高於5V,就可以使用這片晶片。邏輯電路的部分我就跳過啦(因為我也看不懂),直接說明code的部分。因為TPIC6C594非常類似74HC595除了可以供更高壓的電流外,我也忘記差別,希望大大指證,所以下面就以74HC595代稱並說明。使用74HC595這種晶片,可以簡單的使用3個pin腳便可以控制八個燈光/元件,當然進行串聯之後便可以控制更多的元件。


Pin腳們的說明

74HC595基本上上頭有16個腳位,分別是DS、SH_CP、ST_CP、Q0-Q7、Q7' ,還有 VCC、GND、OE跟MR。


DS是Serial data input,就是負責給予Data的腳位。

SH_CP是Shift register clock pin,也就是Clock Pin。

ST_CP是Storage register clock pin,作為Latch Pin。

基本上只要使用這三個pin腳,便可以操作七個以上的燈點~~


Q0-Q7是變成接上需要控制的燈或是七段顯示器的八個燈點(包含小數點的小燈),Q7' 可以作為串接的pin腳,後面再作說明。


VCC跟GND,恩.....就是VCC跟GND,請接到供電跟接地的地方。

OE是Output Enable,設成低電位時,便可以允許訊號輸出,在連接七段顯示器時,直接與GND即可。

MR是指Master Reset,設為低電位時,會清除暫存器中所有資料。暫時不會用到,放旁邊。


串連多個74HC595的方式,便是把Q7' 接到 下一個74HC595的DSpin腳,然後並聯SH_CP, ST_CP兩個pin腳。就可以多個輸出囉~~(記得下一顆七段顯示器的GND也要併聯近前一顆的GND喔)


74HC595初始化的部分


Arduino有個函式叫shiftOut(dataPin, clockPin, MSBFIRST, low_Byte);,可以很快地做好這件事,只要開關latch就好,方便快速,但小弟白痴沒用過就跳過不說明,如果想要快速的arduino code,後面我會補上,這邊直接進python的code。


如果只有使用單顆的74HC595,控制的方法就十分簡單。

首先我們先initialize所有的pin腳。

segmentLatch = 23 segmentClock = 24 segmentData = 25

將所有想要輸出的數字做編號以及建成變數,基本上七段顯示器每顆燈的編號如下。

我們可以看到對應的英文,便可以由此建立變數。為了方便我們使用移位暫存器時同時將一卡車位元(一顆七段顯示)送進去,我們要將這些英文對應成正確的位元組。

舉例來說數字1便是B+C,數字7便是A+B+C

a = 1 << 0 b = 1 << 6 c = 1 << 5 d = 1 << 4 e = 1 << 3 f = 1 << 1 g = 1 << 2 dp = 1 << 7

「<<」是位元運算中推一個位元的意思。<<6則是推6個位元,天呀我不知道這篇怎麼解釋又懶得畫圖。

舉例來說假使這邊有個位元組

00000000

當我寫下 1 << 2 時便會將1(正)推兩個位元,就成了

00000100


之後我們需要用到「且」這個運算子(|),來組合我們得到的位置。

segments = 0 //首先建立segment變數來儲存要送的data if number == 1: segments = b | c elif number == 2: segments = a | b | d | e | g elif number == 3: segments = a | b | c | d | g elif number == 4: segments = f | g | b | c elif number == 5: segments = a | f | g | c | d elif number == 6: segments = a | f | g | e | c | d elif number == 7: segments = a | b | c elif number == 8: segments = a | b | c | d | e | f | g elif number == 9: segments = a | b | c | d | f | g elif number == 0: segments = a | b | c | d | e | f else: segments = 0

且的運算組,可以將兩個位元作且運算,下面附圖表XDDD

舉例來說:

a(1<<0) 在我們剛剛的data assignment之後,視為00000001

b(1<<6) 在剛剛建立成01000000,c(1<<5))在剛剛建立成00100000

當我們把a,b,c三個組合做了且運算,便是以下運作邏輯

00000001 |

01000000 |

00100000 |

----------------

01100001

對於七段顯示器而言,1便是所有要亮的點,0便是不亮的,我們便會形成數字「7」

以此方式我們便建議好了各種輸入方法的變數,當然也可以以個人使用自行斟酌~~~


開始輸出資料進去


開始輸出時,我們先latch拉至低電位,便可以送data進去,再把latch設為高電位關起來~~

而每一次送出一個位元時,我們必須把clock設為低電位初始化,送一個值,再把clock設為高電位。把這個值往前推一個位元。


Latch在此指的是便是整個晶片接收資料的開關。

Clock則是每一次設置為高電位時,便會推送一個值到下一個位元,以此來說,當我串接一大堆的74HC595我便可以不斷開關clock把所有數字一直一直推送到下一個暫存器。

GPIO.output(segmentLatch, GPIO.LOW) n = 0 while n < 8: GPIO.output(segmentclock, GPIO.LOW) GPIO.output(segmentdata, segments & 1 << (7 - n)) GPIO.output(segmentclock, GPIO.HIGH) n += 1 GPIO.output(segmentLatch, GPIO.LOW)

這邊的解釋有點玄,我們就先以「7」這個數字(01100001)來說明

首先設計 n = 0 初始化

跑一個當n不小於8時會停止的回圈每次不段開關clock

segments & 1 << (7-n)這個運算式,便是一次一次把下一個數字送去data

這邊有個且運作子(&),便是做且運算,我們一樣附圖耶~

剛開始 segments 為 01100001

第一次跑回圈時n==0,我們便會將1 << (7-0),得位元組為10000000

01100001 &

10000000

-----------------

00000000

便是我們送進去的第一組資料


第二個數字為n==1 我們便會將 1 << 6,得位元組01000000做且運算

01100001 &

01000000

-----------------

01000000

便是我們送的第二組資料。


如此一來,我們便可以送入這些資料之後迴圈變會結束。

00000000

01000000

00100000

00000000

00000000

00000000

00000000

00000001


而七段顯示器便會得到這串數字 01100001 視為 「7」

如此一來,我們便可以寫出很快速的一套function來負責解釋我要送的數字。


而當我們需要串接更多的數字時,我只需要不斷的呼叫這套函式,他便會送入不同的74HC595當中。每次呼叫時便會完成一顆七段顯示器的顯示。


附上當時的code,寫了一些函式來執行不同的效果,包含當我收到數字10的時候,會跑隨機的效果等等



附個很隨便的影片



(紅色小光段版本是用Arduino Mega硬幹的,因為很酷所以想放一下,但是code完全不一樣)



1,285 次查看0 則留言

Comments


bottom of page