Raspberry Pi 筆記(17):使用MAX7219 控制 8x8 LED Matrix

在使用Arduino時,買了一個8x8的LCD Matrix模組,可是放了好久都沒有時間去瞭解它的應用,剛好在瀏覽樹莓派相關文件時,看到一篇如何運用Python來驅動8x8 LED Matrix,於是就動手接線路,同時也瞭解SPI的使用方法。

[基本知識]

SPI,是Serial Peripheral interface的縮寫,顧名思義就是串列外圍設備介面。最早是Motorola首先在其MC68HCXX系列處理器上定義的。

SPI介面主要應用在 EEPROM,FLASH,實時時鐘,AD轉換器,還有數字信號處理器和數字信號解碼器之間。SPI,是一種高速的,全雙工,同步的通信,並且在晶片的接腳上只佔用四根線,節約了晶片的管腳,同時為PCB的佈局上節省空間。

SPI的通信原理很簡單,它以主從方式工作,這種模式通常有一個主設備和一個或多個從設備,需要至少4根線,事實上3根也可以(單向傳輸時)。也是所有基於SPI的設備共有的,它們是SDI(數據輸入),SDO(數據輸出),SCK(時鐘),CS(片選)。
(1)SDO     – 主設備數據輸出,從設備數據輸入(Serial Data Out)
(2)SDI      – 主設備數據輸入,從設備數據輸出(Serial Data In)
(3)SCLK   – 時鐘信號,由主設備產生(Serial Clock)
(4)CS        – 從設備使能信號,由主設備控制(Chip Select)
其中CS是控制晶片是否被選中,也就是預先讓這個接腳產生信號時(高電位或低電位元),對此晶片的操作才有效。這就允許在同一裝置上連接多個SPI設備成為可能。

負責通訊的3根線,通訊是通過數據交換完成的,SPI串列通訊協議,讓數據是一個位元一個位元傳輸。這就是SCK時鐘線存在的原因,由SCK提供時鐘脈衝,SDI,SDO則基於此脈衝完成數據傳輸。數據輸出透過 SDO線,數據在SCK電位上升或電位下降時改變,在緊接著的下降電壓或上升電壓被讀取。完成一位數據傳輸,輸入也使用同樣原理。這樣,在至少8次時鐘信號的改變(上升電位和下降電位為一次),就可以完成8位數據的傳輸。

要注意的是,SCK信號線只由主設備控制,從設備不能控制信號線。同樣,在一個基於SPI的設備中,至少有一個主控設備。

SPI還是一個數據交換協議:因為SPI的數據輸入和輸出線獨立,所以允許同時完成數據的輸入和輸出,不同的SPI設備的實現方式不盡相同。
在點對點的通信中,SPI介面不需要進行尋址操作,且為全雙工通信,顯得簡單高效。在多個從設備的系統中,每個從設備需要獨立的使能信號,硬體上比I2C系統要稍微複雜一些。

SPI主和從的接線及資料傳輸方式如下圖:
圖片來源:維基百科

[材料]

  • Raspberry Pi 主板 x1
  • 8x8 LED Matrix模組  x1
  • 連接線  x5

[線路連接與電路圖]

  • VCC(+5V Power) 接第 2 Pin(+5V)
  • GND(Ground)    接第 6 Pin(GND)
  • DIN(Data In)   接第 19 Pin(GPIO10, MOSI)
  • CS(Chip Select) 接第 21 Pin(GPIO8, SPI_CS0)
  • CLK(clock)     接第 23 Pin(GPIO11,SPI_CLK)



要執行程式之前要先安裝 max7219 Python套件,可以先到以下網址下載,下載前先建立一個max7219目錄。

$ git clone https://github.com/rm-hull/max7219.git
$ cd max7219
$ sudo python setup.py install

[程式碼]

#!/usr/bin/env python

import max7219.led as led
import max7219.canvas as canvas
import max7219.transitions as transitions
import time
from random import randrange

led.init()
led.show_message("Hello world!", transition = transitions.left_scroll)

for x in range(256):
    led.letter(x)
    time.sleep(0.1)

while True:
    for x in range(500):
        canvas.set_on(4, 4)
        canvas.scroll(randrange(8))
        canvas.render()
        time.sleep(0.01)

我將上述程式改成顯示當時時間,以跑馬燈的方式,向左方捲軸顯示:
import max7219.led as led
import max7219.canvas as canvas
import max7219.transitions as transitions
import time
import datetime
from random import randrange

led.init()

while True:
    t = time.time()
    ctime = datetime.datetime.fromtimestamp(t).strftime('%Y-%m-%d %H:%M:%S')
    led.show_message(ctime, transition = transitions.left_scroll)

顯示結果:

[參考資料]

5 留言

  1. 程式碼是放在模控資料夾中直接運行可是上面說明"No module named 'max7219.led'; 'max7219' is not a package"

    是指下載模塊失敗嗎

    回覆刪除
  2. 不好意思請問如果運行程式後出現 importerror:no module named 'max7219.led';'max7219'is not a package 是表示他找不到下載好的 python的max7219套件嗎

    回覆刪除
    回覆
    1. 是的, 您可能沒有安裝 max7219 的程式,請問以下兩行有執行嗎?
      $ git clone https://github.com/rm-hull/max7219.git
      $ sudo python max7219/setup.py install

      刪除
  3. 請問我下setup.py install 之後出現該錯誤訊息

    pi@raspberrypi:~ $ sudo python max7219/setup.py install
    Traceback (most recent call last):
    File "max7219/setup.py", line 28, in
    README = read_file('README.rst')
    File "max7219/setup.py", line 12, in read_file
    with open(fname, encoding=encoding) as r:
    IOError: [Errno 2] No such file or directory: 'README.rst'

    回覆刪除
    回覆
    1. 執行程式所在目錄的關係,如果將這行 $sudo python max7219/setup.py install 改成:
      $ cd max7219
      $ sudo python setup.py install
      就可以了。

      刪除

張貼留言

較新的 較舊