1. 概述
1.1 功能描述
本範例將使用 S32DS SDK 燒入程式,由 S32K144 EVM master & slaver 進行 SPI
通訊,並使用 DMA 讓 SPI 通訊工作在 10 M baudrate,一次傳送與接收 64 bytes 資料。
1.2 硬體開發工具
S32K144-EVB 評估板
PEmicro Multilink Universal 燒錄器
1.3 軟體開發工具
S32 Design Studio IDE for ARM Architecture , 版本 2018
1.4 參考程式碼
Example codes / S32K144_SPI_DMA
2. SPI 原理(Serial Peripheral interface)
2.1 SPI 腳位功能
2.1.1 SCK 腳位 ( Serial Clock Input)
時鐘訊號 ( SCK ) 由 master 產生並控制,連接到 slaver 來進行同步同時鐘的全雙工資料傳輸。
2.1.2 CS腳位 ( Chip Select )
晶片 ( slaver ) 致能 ( 簡稱CS或SS ) 由 master 控制輸出決定由哪個 chip ( slaver ) 接收訊號, slaver 一般為低電位時對於 master 產生反應,有些 slaver 可改寫為高電位產生反應,應用來說有些 Chip 使用由高轉低的下降緣來觸發,降低錯誤回復率。
2.1.3 Serial data output腳位
串列訊號輸出(例 master output 與 slaver input PIN腳連接)
2.1.4 Serial data input腳位
串列訊號輸入(例 master input 與 slaver output PIN腳連接)
2.2 Master 與 slaver
2.2.1 Master
負責控制 SCK 與 CS ,一般使用為 1 個 master 連接多個 slaver,輸出與讀取資料利用 2 組 shift register 來達到全雙工的功能,同時接收與發送, SCK 為控制register同步位移的時脈訊號。
2.2.2 slaver
正確接收由 master 輸出的訊號並回應,全雙工。
2.3 資料傳輸架構
2.3.1 Multi-CS
Master 有多組 CS_PIN腳輸出,一組 CS 連接一個 slaver,靈活度較高但比 Daisy-Chain 需要更多硬體接腳。
2.3.2 Daisy-Chain
Daisy-Chain slaver 只能在同一個模式下操作,slaver 一定都要有輸出與輸入腳位,slaver 必須都支援 Daisy-Chain,靈活度較低但減少 master 硬體接腳。Daisy-Chain 運作方式為 master 輸出(資料長度x slaver 個數)的資料,第一個Chip 接收完資料後將多餘資料傳給下個chip,等所有資料都傳輸完畢後,利用 CS 訊號上升緣通知 chip 將資料 latch 起來。
2.4 工作模式設定
master 根據想要傳送的 slaver 不同,選擇 slaver 使用的工作模式,否則無法進行溝通,可調整設定分別為 SCLK polarity、Phase 與 CS polarity。
其中 SCLK polarity表示在沒有觸發動作時處於高電位還低電位,Phase 為 first
Bit or second bit 變化, CS polarity 為上升緣或下降緣讀取 ( latch ) 資料。
3. DMA 原理 ( Direct Memory Access )
DMA 可以降低 MCU 大量中斷負載,將資料自動從硬體 buffer ,送到設置 memory 中,直到設置 memory buffer 被填滿,在中斷提醒 MCU 將資料讀出,如此一來 MCU 中斷一次便可讀取到大量資料,而不用每一個 bytes 都要中斷接收一次,大幅降低 MCU 負載,這裡須注意如果 SPI 使用在 polling 方式 work ,baudrate 高,單筆資料量大的情況下,資料會有遺失,需使用 call-back 或者 DMA 方式較佳。
4. 程式流程圖
5. 硬體接線圖
5.1 S32K148_EVB 接線圖
5.2 Block diagram
6. 相關 function 介紹
6.1 DSPI_MasterInit
6.1.1 功能描述
將 S32K144_SPI0 設置為 master
SPI 傳送與接收架構 ( frame )設定
指定 RX與 TX 的緩衝區與傳送速率
SPI ( SCLK polarity、Phase 與 CS polarity )設定
SCLK 是否設置連續
6.1.2 函式原型
LPSPI_DRV_MasterInit ( uint32_t instance , lpspi_state_t * lpspiState , const lpspi_master_config_t * spiConfig )
6.1.3 參數
參數名稱 |
類型 |
描述 |
instance |
dspi_instance_t |
指定 SPI 的 device |
dspi1State |
dspi_state_t |
傳送與接收的 frame 與緩衝區設置 |
dspi1_MasterInitConfig0 |
dspi_master_config_t |
傳送速率、SPI設定、SCLK設定 |
6.1.4 return 值
回傳 STATUS_SUCCESS
6.1.5 範例
LPSPI_DRV_MasterInit ( SEND, &masterState, &Send_MasterConfig0 );
6.2 DSPI_SlaveInit
6.2.1 功能描述
將 S32K144_SPI1 設置為 slaver
SPI 傳送與接收架構 ( frame )設定
指定 RX與 TX 的緩衝區
SPI ( SCLK polarity、Phase 與 CS polarity )設定
6.2.2 函式原型
DSPI_SlaveInit ( dspi_instance_t instance , dspi_state_t * state ,const dspi_slave_config_t * config )
6.2.3 參數
參數名稱 |
類型 |
描述 |
instance |
dspi_instance_t |
指定 SPI 的 device |
state |
dspi_state_t * |
傳送與接收的 frame 與緩衝區設置 |
config |
Const dspi_slave_config_t * |
SPI設定 |
6.2.4 return 值
回傳STATUS_SUCCESS
6.2.5 範例
LPSPI_DRV_SlaveInit ( RECEIVE, &slaveState, &Receive_SlaveConfig0 );
6.3 DMA_Init
6.3.1 功能描述
設置 DMA 通道與 SPI 接收與傳送連接
6.3.2 函式原型
EDMA_DRV_Init ( edma_state_t *edmaState , const edma_user_config_t *userConfig ,edma_chn_state_t * const chnStateArray[] , const edma_channel_config_t * const chnConfigArray[] , uint32_t chnCount )
6.3.3 參數
參數名稱 |
類型 |
描述 |
edmaState |
edma_state_t * |
DMA 所有通道狀態設置 |
userConfig |
const edma_user_config_t |
DMA設置 |
const chnStateArray[] |
edma_chn_state_t * |
將 DMA 通道進行對應功能設置 |
const chnConfigArray[] |
const edma_channel_config_t |
DMA 通道優先權設置 |
chnCount |
uint32_t |
DMA 通道數 |
6.3.4 return 值
STATUS_SUCCESS
STATUS_ERROR
STATUS_BUSY
STATUS_TIMEOUT
STATUS_UNSUPPORTED
6.3.5 範例
EDMA_DRV_Init ( &dmaController1_State , &dmaController1_InitConfig0 ,
edmaChnStateArray , edmaChnConfigArray ,
DMA_CONFIGURED_CHANNELS_COUNT ) ;
6.4 DSPI_MasterTransfer
6.4.1 功能描述
Master傳送資料的陣列
Master接收資料的陣列
Master傳送與接收 Frame 的數量
6.4.2 函式原型
DSPI_MasterTransfer ( INST_DSPI1 , masterTxBuffer4_8b , masterRxBuffer_8b , 2 )
6.4.3 參數
參數名稱 |
類型 |
描述 |
INST_DSPI1 |
dspi_instance_t |
指定 SPI 的 Channel |
masterTxBuffer4_8b |
Uint8_t |
傳送資料的陣列 |
masterRxBuffer_8b |
Uint8_t |
接收資料的陣列 |
2 |
uint16_t |
Frame 的數量 |
6.4.4 return 值
回傳STATUS_SUCCESS
6.4.5 範例
DSPI_MasterTransfer ( INST_DSPI1 , masterTxBuffer_8b , masterRxBuffer_8b , 1 ) ;
DSPI_MasterTransfer ( INST_DSPI1 , masterTxBuffer1_8b , masterRxBuffer_8b , 2 ) ;
6.5 DSPI_SlaveTransfer
6.5.1 功能描述
slaver傳送資料的陣列
slaver接收資料的陣列
slaver傳送與接收 Frame 的數量
6.5.2 函式原型
DSPI_SlaveTransfer ( dspi_instance_t instance , const void * sendBuffer, void * receiveBuffer , uint16_t frames )
6.5.3 參數
參數名稱 |
類型 |
描述 |
instance |
dspi_instance_t |
指定 SPI 的 Channel |
sendBuffer |
const void * |
傳送資料的陣列 |
receiveBuffer |
void * |
接收資料的陣列 |
frames |
uint16_t |
Frame 的數量 |
6.5.4 return 值
回傳STATUS_SUCCESS
6.5.5 範例
DSPI_SlaveTransfer(DSPI1_INSTANCE, slaveTxBuffer_8b, slaveRxBuffer_8b,BUFFER_SIZE );
本範例設置 BUFFER_SIZE = 64
6.6 DSPI_UpdateCS
6.6.1 功能描述
切換 CS channel,用來切換與不同 slaver 溝通
6.6.2 函式原型
DSPI_UpdateCS(dspi_instance_t instance,uint8_t whichPCS);
6.6.3 參數
參數名稱 |
類型 |
描述 |
INST_DSPI1 |
dspi_instance_t |
指定 SPI 的 Channel |
whichPCS |
uint8_t |
更新 CS 通訊通道 |
6.6.4 return 值
回傳STATUS_SUCCESS
6.6.5 範例
DSPI_UpdateCS(DSPI0_INSTANCE,0);
選擇 CS channel 0 與 slaver1 通訊
DSPI_UpdateCS(DSPI0_INSTANCE,1);
選擇 CS channel 1 與 slaver2 通訊
7. 範例程式SDK for ARM ( 基於S32K144 )
7.1 使用 SDK Library DSPI 功能 fuction
點選 Components Library -> Alphabetical -> lpspi
右下方會顯示已加入 function
7.2 DMA 功能系統會自動增加至下方圖示,除非沒有,否則請勿重複添加
...............等等
欲獲得剩餘章節,請在大大通留言,或者聯絡下方信箱
Michael.Gao@wpi-group.com
~~ THANK YOU ~~
評論