前面幾篇我們學習了如何利用一片或多片級聯的74HC595芯片來驅動顯示數碼管的方法。最開始我們提出的兩個問題:
第一個問題已經利用級聯的74HC595解決了。(不管驅動幾只數碼管,只用3個IO即可)
但第二個問題依然存在,樹莓派仍然需要不停地訪問IO口進行動態掃描。
好,既然動態掃描占用CPU資源太多,那這活兒咱包出去讓別人干不就行了?這就是本文主角MAX7219的特長,動態掃描這活兒MAX7219全包了,干的還比咱自己干得還好,一片MAX7219可最多支持顯示8位8段數碼管,還支持各種設置如亮度設置掃描位數設置等。而我們只用告訴它顯示的內容就行了。
最終效果
視頻演示
硬件
- MAX7219顯示芯片 X 1(2到3元一個)
MAX7219 - 共陰(共陽不可以)4位數碼管 X 2
- 10k電阻一只
- 10uF電容一只
- 0.1uF電容一只
硬件圖
原理說明 未完TODO
注:下面這些圖都是從MAX7219官方資料里截取出來的,官方資料文末提供下載
- 先看一下MAX7219的引腳圖:
MAX7219的引腳圖
MAX7219一共有24根引腳,這里面有一些跟74HC595的引腳功能類似的引腳如下:
可以看出,MAX7219跟74HC595一樣也是通過DIN引腳串行輸入數據,在CLK引腳的上升沿移入移位寄存器,在LOAD引腳的上升沿將位移寄存器的數據復制到內部的各種寄存器里。不同的是:
我們再看一下官方文檔里關于各引腳的功能說明:
MAX7219各引腳的功能說明
上面提過的不再贅述,說一下MAX7219特有的引腳。- DIG0-DIG7這8個引腳作為位選端,分別連到8位數碼管的共陰極,MAX7219在做動態掃描時會依次向共陰極DIG0-DIG7輸出低電平,所以MAX7219不能驅動共陽極的數碼管。其實也不是絕對不能,將位選端和段選端逆接就可以了,不過這樣做的話,有3個弊端:
- 不能使用MAX7219內部的譯碼功能,需要自己編寫數字的字形碼。增加了代碼的復雜度。
- 需要以段單位來傳輸數據,而不能以位單位來傳輸數據。(即每次傳輸的是各位數碼管的某一段的數據,而不是某位數碼管各段的數據。第一次傳所有數碼管的A段數據,第二次傳所有數碼管的B段數據一直到8段數據全部傳完)無疑進一步增加了代碼的復雜度。
- 無法限制掃描位數,只能所有8位數碼管同時掃描。(變成了限制掃描段數,如可以只顯示所有數碼管的A-C段。。。)
- ISET通過一只電阻連上VCC,通過調整這只電阻的阻值可以調整通過這只電阻的電流I,而最后輸出到數碼管上的最大電流就是這個電流I的100倍。如果這只電阻太小,導致輸出到數碼管的電流過大會燒壞數碼管,所以官方文檔里推薦這只電阻最小應該設置為9.7K歐,我手頭上只有10K的電阻也是一樣,只要別低于這個阻值就可以了。根據這個原理我們也可以接一個可調電阻在ISET上,可以隨時調整數碼管亮度。這種調整亮度的方法是通過模擬信號調制。MAX7219也支持通過數字信號來設置亮度(有16級亮度可調)。
MAX7219內部的各模塊的示意圖:
MAX7219內部的各模塊的示意圖
最下面是一個16位的移位寄存器D0-D15,跟74HC595一樣,通過DIN引腳串行輸入數據,在CLK引腳的上升沿移入移位寄存器。
D8-D11這4位數據用來指定內部寄存器地址。D0-D7是具體要傳到寄存器里的數據。
上面的圖看上去有點復雜,其實簡單地說就是我們每次要串行傳輸16位數據進去,然后在LOAD的上升沿,根據D8-D11指定的寄存器地址,將D0-D7存放在指定的寄存器里。這樣多次傳輸數據就可以給所有的寄存器設值了。
下面是MAX7219內部的寄存器一覽:- 關斷寄存器
- 譯碼模式寄存器
- 亮度寄存器
- 掃描限值寄存器
顯示器測試寄存器
每個寄存器都有自己特殊的功能,后面我們會逐一介紹。
串行傳輸時的數據格式如下:
MAX7219串行數據格式
你可能注意到了這幅圖的順序跟模塊示意圖里移位寄存器的順序是相反的。
D15-D0這個反向的順序是你寫代碼時串行傳輸數據時的順序,先傳D15的數據,再傳D14,D13…D0,這樣傳輸完成后。實際的數據順序就變成了D0,D1,D2…D15。為了便于編碼,除了模塊示意圖是按實際順序記載的,后面所有數據格式的示意圖都是倒序記載的。各寄存器地址如下:
MAX7219寄存器地址
關斷寄存器的數據格式:
MAX7219關斷寄存器的數據格式
譯碼模式寄存器的數據格式:
MAX7219譯碼模式寄存器的數據格式
譯碼模式下的原碼和譯碼的對應表:
MAX7219譯碼模式下的原碼和譯碼的對應表
非譯碼模式下的數據和數碼管各段的對應表:
MAX7219非譯碼模式下的數據和數碼管各段的對應表
亮度寄存器的數據格式:
MAX7219亮度寄存器的數據格式
掃描限值寄存器的數據格式:
MAX7219掃描限值寄存器的數據格式
顯示器測試寄存器的數據格式:
MAX7219顯示器測試寄存器的數據格式
硬件連接TODO
模塊1引腳模塊2引腳MAX7219DIN樹莓派GPIO13MAX7219LOAD樹莓派GPIO26MAX7219CLK樹莓派GPIO19MAX7219GNDX2樹莓派GNDMAX7219V+樹莓派5VMAX7219ISET樹莓派5V(需串聯一只10k電阻)MAX7219DIG0數碼管1DIG1(引腳12)MAX7219DIG1數碼管1DIG2(引腳9)MAX7219DIG2數碼管1DIG3(引腳8)MAX7219DIG3數碼管1DIG4(引腳6)MAX7219DIG4數碼管2DIG1(引腳12)MAX7219DIG5數碼管2DIG2(引腳9)MAX7219DIG6數碼管2DIG3(引腳8)MAX7219DIG7數碼管2DIG4(引腳6)MAX7219SEG DP數碼管1/2DPMAX7219SEG G數碼管1/2GMAX7219SEG F數碼管1/2FMAX7219SEG E數碼管1/2EMAX7219SEG D數碼管1/2DMAX7219SEG C數碼管1/2CMAX7219SEG B數碼管1/2BMAX7219SEG A數碼管1/2AMAX7219DOUT(級聯用)(不使用)10/0.1uF電容正極MAX7219V+10/0.1uF電容負極MAX7219GND代碼(Python)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
#!/usr/bin/env python# encoding: utf-8import RPi.GPIOimport time# 串行數據輸入DIN = 13# 時鐘脈沖信號——上升沿有效LOAD = 26# 打入信號————上升沿有效CLK = 19RPi.GPIO.setmode(RPi.GPIO.BCM)RPi.GPIO.setup(DIN, RPi.GPIO.OUT)RPi.GPIO.setup(LOAD, RPi.GPIO.OUT)RPi.GPIO.setup(CLK, RPi.GPIO.OUT)# 傳輸一個8位數def setByte(byteData):for bit in range(0,8):# 傳入的數字從高位到低位依次判斷是否為1,若為1則設置高電平,否則設置低電平# 判斷的方法是先向左移位,把要判斷的位移動到最高位然后跟0x80(1000 0000)相與,# 如果結果仍然是0x80(1000 0000)就表示最高位是1,否則最高位就是0if ((byteData<
評論