STM32 LibOpenCM3:SPI (Slave mode)
前言
上次已經介紹了 SPI 作為 Master device 的程式,這次要接著介紹作為 Slave device 的程式寫法,讓 Master 與 Slave 可以互相溝通。
正文
首先一樣以 Nucleo-F446RE 做示範。
首先建立一個 PIO 的專案,選擇 Framework 為「libopencm3」,並在 src/
資料夾中新增並開啓 main.c
與 main.h
檔案。
完整程式
1 |
|
1 |
|
分段說明
設定 SPI
1 |
|
這部分與設定 Master 時的類似。不過要注意的是,Master device 的 CS(NSS)腳不受 AF 控制,但 Slave device 的會,所以 CS 腳也要設為 AF。
SPI 本身的設定如 CPOL 與 CPHA 要與 Master 一致才可以正常通訊,這裡設為 CPOL=0
CPHA=1
。
然後先使用 spi_init_master()
初始化 SPI 的相關設定,再以 spi_set_slave_mode()
設定成 Slave mode。
一樣以 spi_set_full_duplex_mode()
設為全雙工模式。
再來,為了要使用硬體 CS,所以要將 SSM 和 SSOE 都設為 0
。這裡呼叫 spi_disable_software_slave_management()
與 spi_disable_ss_output()
來完成設定。
NSS output disable (SSM=0, SSOE = 0): In slave mode, the NSS pin works as a standard “chip select” input and the slave is selected while NSS line is at low level.
節錄自 RM0390 Rev6 P.854。
之後再啓用 SPI 的中斷功能。
SPI ISR
1 |
|
我們設定啓用 SPI 的「接收資料非空」中斷事件,因此 ISR 就負責讀取 Master 傳送的資料,若先前有 Slave 要傳送的資料也會在 CS 腳被下拉且 Master 發起 SCK 時脈訊號後傳送。
USART ISR
1 |
|
當 USART 收到資料時,會將資料先用 spi_send()
寫入到傳送暫存器中,然後以 spi_rq_set()
將 RQ 腳拉低以請求 Master 進行通訊。
多環境程式(F446RE + F103RB)
由於 STM32F1 的部分函式不同,所以 F103RB 沒辦法直接使用上面的 F446RE 的程式。
由於這次程式較長,所以完整的程式請看 GitHub repo。
成果
我使用兩塊 STM32 Nucleo 板分別當作 Master 與 Slave。將線都接好後就可以讓兩者互相溝通了,記得要共地。
小結
這次接續上次的 SPI Master,寫了 Slave 的操作介紹。其實用法基本上是差不多的,相信不會太難。
會使用 SPI 通常是要連接其它的模組,所以 STM32 通常是當作 Master 的角色,但如果想要自己用 STM32 做一個「模組」的話,就可以用到 SPI Slave 模式了。
參考資料
- libopencm3/libopencm3-examples
- platformio/platform-ststm32
- STM32F446RE datasheet (DS10693)
- STM32F446xx reference manual (RM0390)
- STM32F103RB datasheet (DS5319)
- STM32 Nucleo-64 board user manual (UM1724)
本文的程式也有放在 GitHub 上。
本文同步發表於 iT 邦幫忙-2022 iThome 鐵人賽。
留言可能不會立即顯示。若過了幾天仍未出現,請 Email 聯繫:)