最近文章

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

[2014/03/28]
在使用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目錄。

$ mkdir max7219
$ cd max7219
$ git clone https://github.com/rm-hull/max7219.git
$ 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)

顯示結果:
video

[參考資料]

RasPi.TV:8 x 8 LED array driven by max7219 on the Raspberry Pi via python
程序員聯合開發網:read.pudn.com‎


沒有留言