Skip to content

SPI API

Tom Lin edited this page Feb 2, 2020 · 2 revisions

SPI (master side)

串行外設介面(Serial Peripheral Interface Bus,SPI),是一種用於晶片通信的同步串行通信介面 規範,主要應用於單晶片系統中。類似I2C。然後發展成了一種行業規範。典型應用包含SD卡和液晶顯示器。

  • SPI是一種4線同步序列資料協定,適用於可攜式裝置平臺系
  • 串列外設介面一般是4線,有時亦可為3線,SS信號管理進行Slave選用,因此SS號經由machine.Pin實作
    • SCLK(Serial Clock):串列時脈,由主機發出
    • MOSI(Master Output,Slave Input):主機輸出從機輸入訊號,由主機發出
    • MISO(Master Input,Slave Output):主機輸入從機輸出訊號,由從機發出
    • SS(CS)(Slave Selected)(Chip Select):選擇訊號,由主機發出,一般是低電位有效SS腳位平時為在高 電位,Master要送或接收資料之前,必須指定Slave的SS腳設定成0,然後隨MOIS或MISO結速動作後再裝SS腳設定為1。
  • SPI提供兩種序列傳輸協定,分別是SPI protocol跟I2S audio protocol,預設是用SPI protocol ,可藉由software來做轉換

SPI_single_slave

SPI裝置之間使用全雙工模式通信,是一個主機和一個或多個從機的主從模式。主機產生待讀或待寫的影格資料, 多個從機通過一個片選線路決定哪個來回應主機的請求。

SPI_three_slaves svg

Constructors

class machine.SPI(id, ...)

建構一個SPI物件,id值取決於晶片提供SPI模組,id值0、1等通常用於選擇硬體SPI模組#0,#1等,當id 值為-1時可以用軟體實作。其額外參數為參考SPI.init有關參數。 Example:

採用SPI硬體方式

from machine import SPI
spi = SPI(0)

採用SPI軟體方式

from machine import SPI, Pin
cs = Pin(10, Pin.OUT)
spi = SPI(mosi=Pin(11) ,miso=Pin(12), sck=Pin(13))

Methods

SPI.init(baudrate=1000000, *, polarity=0, phase=0, bits=8, firstbit=SPI.MSB,
  sck=None, mosi=None, miso=None, pins=(SCK, MOSI, MISO))

SPI bus初始化參數:

  • baudrate:是SCK頻率。
  • polarity:可以設定為0或1為閒置時SCK所在電位為低準位或高準位。
  • phase:相位可以設定為0或1在採樣數據分別第1或第2邊沿區分。
  • bits:每次傳輸的寬度(以bits為單位)。8bits保證所有硬體支援。
  • firstbit:可以設定SPI.MSB或SPI.LSB。
  • sck, miso, mosi:在硬體設定中MT7697以固定為P13、P12、P11, 對於採用軟體擬模SPI部份的 信號針腳則是採用 machine.Pin 所建構可以任意分配針腳,一切決定於建構SPI物件時 id 設定值。
  • pins:在MT7697的MicroPython系統裡只被用於軟體擬模SPI時使用,允許將指為pins為tuple 用於設定 SCKMOISMISO

對於硬體SPI傳輸時頻率的部份,需以實際硬體可以作操的規範為主,取得決於硬體特性以MT7697硬體部分

  • 最低頻率:30000Hz
  • 最高頻率:60000000Hz
SPI.deinit()

關閉SPI匯流排

SPI.read(nbytes, write=0x00)

nbytes 指讀取byte的量,經 write 傳送給單一byte資料後,將會返回讀取的bytes資料。

SPI.readinto(buf, write=0x00)

設立一個 buf, 當 write 傳送給單一byte資料後,返回資料將指定於 buf 取回資料長度 有 buf 建構大小決定,再讀取 buf 內資料。

SPI.write(buf)

要傳送資料可以寫入於 buf 內。

SPI.write_readinto(write_buf, read_buf)

write_buf 為設立一個buffer可將傳送資料寫入,並且設立一個要讀取傳送後資料返回時放置buffer 為 read_buf,兩個buffer可以同一個物件,重點 write_bufread_buf 大小需要 一樣

Constants

SPI.MSB

將第一位bit為最高有效位

SPI.LSB

將第一位bit為最低有效位

Exmaple

main.py 用於硬體設定

from machine import SPI, Pin
import max7219_led

spi = SPI(0)
led = max7219_led.max7219LED(spi)
led.test()

main.py 用於軟體設定

from machine import SPI, Pin
import max7219_led

cs = Pin(10, Pin.OUT)
spi = SPI(mosi=Pin(11) ,miso=Pin(12), sck=Pin(13))
led = max7219_led.max7219LED(spi, cs)
led.test()

max7219_led.py

DECODEMODE = const(9)
INTENSITY = const(10)
SCANLIMIT = const(11)
SHUTDOWM = const(12)
DISPLAYTEST = const(15)

symbol = (0x60, 0xF0, 0xF0, 0x7F, 0x07, 0x06, 0x0C, 0x00)
sprite = (
(0x30, 0x7c, 0xae, 0x3e, 0x3e, 0xae, 0x7c, 0x30),
(0x18, 0xbe, 0x57, 0x1f, 0x1f, 0x57, 0xbe, 0x18),
(0x30, 0xbc, 0x6e, 0x3e, 0x3e, 0x6e, 0xbc, 0x30),
(0x18, 0x9e, 0x57, 0xbf, 0xbf, 0x57, 0x9e, 0x18))


class max7219LED():
    def __init__(self, spi, cs=None):
        self.spi = spi
        self.cs = cs

    def max7219(self,reg, data):
        if (self.cs == None):
            self.spi.write(bytes([reg,data]))
        else:
            self.cs.value(0)
            self.spi.write(bytes([reg,data]))
            self.cs.value(1)


    def init(self):
        for reg, data in (
            (DISPLAYTEST, 0),
            (SCANLIMIT, 7),
            (INTENSITY, 8),
            (DECODEMODE, 0),
            (SHUTDOWM, 1)):
            self.max7219(reg, data)

    def show(self):
        for i in range(8):
            self.max7219(i+1, symbol[i])

    def clear(self):
        for i in range(8):
            self.max7219(i+1, 0)

    def animate(self):
        import utime
        for i in range(4):
            for j in range(8):
                self.max7219(j+1, sprite[i][j])
            utime.sleep_ms(300)

    def test(self):
        try:
            import gc
            self.init()
            for i in range(500):
                gc.collect()
                self.animate()
        except:
            self.clear()

Clone this wiki locally