目錄
SPI協議簡介
極性與相位
SPI框圖
?單字節收發
發送數據流程
接收數據流程
ECSPI控制器
關鍵特性
時鐘源
主機模式
等待狀態
片選控制
單突發傳輸
多突發傳輸
?相位控制
ECSPI Memory Map
ECSPI寄存器
ECSPIx_RXDATA
ECSPIx_TXDATA
?編輯
?ECSPIx_CONREG
ECSPIx_CONFIGREG
ECSPIx_STATREG
ECSPIx_PERIODREG
前言:
增強型可配置串行外設接口ECSPI(Enhanced Configurable Serial Peripheral Interface)是一個全雙工、同步的四線制串行通信模塊,ECSPI 包含一個?64×32 的接收緩沖區(RXFIFO)?和一個?64×32 的發送緩沖區(TXFIFO),64 是 FIFO 深度(可連續存儲 64 個數據單元),32 是位寬(每個單元 32 位,即 4 字節),此時 RXFIFO/TXFIFO 最大可緩存256字節數據;
SPI協議簡介
SPI(Serial Peripheral interface)支持全雙工通信,時鐘頻率可達MHz級別;
SPI通過4個引腳與外部器件相連:
- MISO:主設備輸入/從設備輸出引腳,從模式下發送數據,主模式下接收數據;
- MOSI:主設備輸出/從設備輸入引腳,主模式下發送數據,從模式下接收數據;
- SCK: 串口時鐘,作為主設備的輸出,從設備的輸入,主機負責生成同步時鐘信號;
- NSS: 片選引腳,用來選擇總線上的特定從機(Slave)進行通信;
極性與相位
時鐘極性(CPOL)指串行時鐘SCLK在 空閑狀態(單次數據傳輸完成/無數據傳輸時)的電平;
- 低極性(CPOL=0):SCLK 在空閑時保持?低電平;
- 高極性(CPOL=1):SCLK 在空閑時保持?高電平;
時鐘相位(CPHA)指 數據采樣(讀取)發生于?串行時鐘SCLK的哪個邊沿;
- CPHA=0:數據在 SCLK 的第一個邊沿被采樣,第二個邊沿用于更新數據(主從機更新自身的移位寄存器);
- CPHA=1:數據在 SCLK 的第二個邊沿被采樣,第一個邊沿用于更新數據;
?SPI協議按照極性與相位可組合為四種模式,分別為模式0(Mode 0),模式1(Mode 0),模式2(Mode 2),模式3(Mode 3);
注意:? SPI 是全雙工通信,但是發送數據和采樣數據必然發生在同一個時鐘周期的不同邊沿;
以模式 0 為例,
CPOL=0, CPHA=0
,核心邏輯如下:1. 主機側行為(Master):
- 發送數據(MOSI 輸出):在 SCLK 的?下降沿(第二邊沿)完成移位輸出(數據從主機移位寄存器 → MOSI 總線);
- 采樣數據(MISO 輸入):在 SCLK 的?上升沿(第一邊沿)完成鎖存采樣(數據從 MISO 總線 → 主機移位寄存器);
2. 從機側行為(Slave):
- 發送數據(MISO 輸出):在 SCLK 的?上升沿(第一邊沿)完成移位輸出(數據從從機移位寄存器 → MISO 總線);
- 采樣數據(MOSI 輸入):在 SCLK 的?下降沿(第二邊沿)完成鎖存采樣(數據從 MOSI 總線 → 從機移位寄存器);
SPI框圖
移位寄存器(Shift Register):? 串并轉換器
- 發送側:CPU 寫入的字節并行加載到移位寄存器,然后通過 MOSI 逐位串行發送;
- 接收側:從機通過 MISO 發來的串行位,逐位串行移入到移位寄存器,最終合并為并行字節,供 CPU 讀取;
發送緩沖區(TX Buffer):
- 將發送緩沖區可設計為先進先出隊列(TXFIFO),允許 CPU 提前寫入多個待發送數據,SPI 自動按順序發送,無需 CPU 逐字節判斷發送緩沖區為空;
接收緩沖區(RX Buffer):
- 將接收緩沖區可設計為先進先出隊列(RXFIFO),自動緩存多個接收數據,CPU 可批量讀取,避免因 CPU 響應慢導致數據丟失;
波特率發生器:?
- 可以配置分頻系數,生成指定頻率 SCLK 時鐘;
?單字節收發
假設主機向從機發送?
0x55
(二進制?01010101
),同時接收從機返回的?0xAA
(二進制?10101010
),假定
- CPOL=0,CPHA=0,模式 0,SCK 空閑低電平,上升沿發送 / 采樣數據;
- 數據寬度為8位數據,比特位傳輸順序為MSB(先傳最高有效位);
發送數據流程
路徑:
CPU → TXFIFO → 移位寄存器 → MOSI → 從機
Step 1:CPU 寫入數據到 TXFIFO
CPU 通過地址和數據總線,將待發送的字節?0x55
?寫入?發送緩沖區(TXFIFO),若 TXFIFO 支持多字節,可連續寫入多個數據,SPI 會自動按順序發送;Step 2:移位寄存器加載數據
主控制電路檢測到 TXFIFO 有數據,觸發移位寄存器從 TXFIFO 取出第一個字節?0x55
,并行加載到移位寄存器中(移位寄存器內容:01010101
);Step 3:SCK 時鐘驅動,逐位發送
波特率發生器根據設置的分頻系數生成 SCK 時鐘(假設分頻后頻率為?f_SCK
),在 SCK 的上升沿,移位寄存器將?0x55
?從 最高比特位開始 通過?MOSI 引腳?逐位移出,發送到從機;
- 第 1 個上升沿:發送?
0
(0x55
?的第 7 位,MSB);- 第 2 個上升沿:發送?
1
(0x55
?的第 6 位);- …… 直到 8 個時鐘后,
0x55
?全部發送完成;Step 4:TXE 標志反饋發送緩沖區是否為空
當移位寄存器的 8 位全部發送后,TXFIFO 中若無新數據,狀態寄存器 發送緩沖區空標志位置位,通知 CPU可以寫入下一個字節;
接收數據流程
路徑:
從機 → MISO → 移位寄存器 → RXFIFO → CPU
Step 1:從機數據輸入 MISO
從機通過?MISO 引腳?發送數據?0xAA
(二進制?10101010
),在 SCK 的上升沿,主機的移位寄存器逐位捕獲 MISO 的信號;Step 2:移位寄存器串并轉換
每個 SCK 上升沿,移位寄存器將 MISO 的一位存入,持續 8 個時鐘后,完整的字節?0xAA
?被存入?接收緩沖區(RXFIFO);Step 3:RXNE 標志反饋接收緩沖區非空
當接收字節被轉移到 RXFIFO,狀態寄存器的接收緩沖區非空標志位置位,通知 CPU讀取數據;Step 4:CPU 讀取 RXFIFO
CPU 通過地址和數據總線訪問 RXFIFO,讀出?0xAA
,完成接收;
ECSPI控制器
I.MX6ULL 具有 4 個 ECSPI,每個 ECSPI 支持四個硬件片選信號
關鍵特性
- 全雙工同步串行接口
- 可配置為主機 / 從機模式
- 四路片選(SS)信號,支持多外設連接
- 傳輸續傳功能,允許無限制長度的數據傳輸
- 收發數據均采用?32 位寬、64 項深度?的 FIFO(即每個 FIFO 可存 64 個 32 位數據)
- 片選(SS)和 SPI 時鐘(SCLK)的極性與相位均可配置
- 支持直接內存訪問(DMA)
- 最大工作頻率可達到參考時鐘頻率(即與系統參考時鐘同頻運行)
- 主機模式(Master Mode):設備作為通信發起者和控制者,主動產生?SCLK 時鐘?和?片選信號(SS),驅動數據傳輸;
- 從機模式(Slave Mode):設備作為被動響應者,不產生時鐘,等待主機的 SCLK 和 SS 信號,同步收發數據;
時鐘源
主機作為 SPI 時鐘(SCLK)的主動生成者,從機作為?被動同步者,主機選取通信速度(SCLK 頻率)不能超過從機規格書中標注的最大時鐘頻率,否則傳感器無法正確采樣,導致數據傳輸出錯;
結論:主機的 SCLK 頻率 ≤ 從機支持的最大 SCLK 頻率
?
?①. 復用器用于選擇根時鐘源,由 CSCDR2寄存器 的 ECSPI_CLK_SEL位控制,配置為 0 選擇 pll3_60m 作為 ECSPI 根時鐘源,配置為 1 選擇 osc_clk 作為 ECSPI 時鐘源;假設配置為1;?
?②. ECSPI 時鐘分頻值,由CSCDR2寄存器 的ECSPI_CLK_PODF位控制,分頻值為 (2^ECSPI_CLK_PODF),假設設置為 0,即?1 分頻;
③.? 最終進入 ECSPI模塊時鐘ECSPI_CLK_ROOT=60MHz;
主機模式
等待狀態
若主機(ECSPI)速度遠快于從設備,從設備可能因無法及時處理數據導致錯誤,存在一種解決方案是在?連續的 SPI 突發傳輸之間(突發傳輸:單次片選(SS)有效期間,連續傳輸多個字節 / 位的數據塊)?插入若干個等待狀態(空閑周期),延長傳輸間隔,給從設備足夠時間處理數據;
階段 1:第一個突發傳輸(Burst 1)
- SS 拉低(選中從機)→ SCLK 產生時鐘脈沖 → MOSI/MISO 傳輸數據→ SS 拉高(釋放從機,結束第一個突發);
階段 2:等待狀態(Wait States)
- SS 保持拉高(從機被釋放,不響應 SCLK)→ SCLK 產生空閑時鐘(由寄存器?
ECSPI_PERIODREG
?配置,用于延長間隙時間)→ 此階段無數據傳輸,給從機 / 主機時間處理上一突發的收尾(從機將 RXFIFO 數據寫入內部緩存,主機準備下一突發的 TXFIFO 數據);階段 3:第二個突發傳輸(Burst 2)
- SS 再次拉低(重新選中從機)→ SCLK 恢復時鐘脈沖 → 繼續傳輸新的一組數據 → SS 拉高(結束第二個突發);
實現機制:
- 數量控制:通過?
ECSPI_PERIODREG[SAMPLE PERIOD]
?配置等待狀態的持續周期數(插入 n個時鐘周期的空閑);- 時鐘源選擇:通過?
ECSPI_PERIODREG[CSRC]
?選擇等待狀態的時鐘來源;
片選控制
SPI 片選控制用于決定當前操作是?單突發傳輸?還是?多突發傳輸;
單突發傳輸:?一次片選(SS)持續低電平期間,連續傳輸?多個數據塊,片選(SS)僅拉低一次,直到所有數據傳輸完成后才拉高;
多突發傳輸:將傳輸拆分為?多個獨立的短突發,每次突發對應?獨立的片選周期(SS 拉低→傳輸→拉高),片選(SS)多次拉低 / 拉高,每次突發是獨立的片選有效周期;
ECSPI_CONREG
寄存器BURST_LENGTH
位定義單個突發的最大字節數,ECSPI_CONREG
寄存器SS_CTL位進行模式切換;
- SS_CTL置位(多突發傳輸):適合需獨立片選觸發的外設;
- SS_CTL清零(單突發傳輸):適合需連續數據流的外設;
單突發傳輸
一?突發前:片選拉低,初始化通信
- SS 拉低 → 從機被選中,進入待命狀態;
- SCLK 開始產生時鐘脈沖 → 準備傳輸數據;
二 數據傳輸階段 1:TXFIFO 有數據,連續移位
- TXFIFO 預存數據→ ECSPI 自動從 FIFO 取數據,通過 MOSI 逐位移出;
- SCLK 持續運行 → 每個時鐘邊沿觸發 MOSI/MISO 數據移位(全雙工同步);
三 等待間隙:TXFIFO 空,SCLK 暫停
- 若 TXFIFO 數據耗盡(兩個 8 位數據傳輸完成,新數據未及時填充)→ ECSPI 插入等待軟件寫數據的間隙:
- SCLK 暫停產生 “有效移位時鐘”(可能保持固定電平或低速運行);
- 此間隙給軟件時間填充 TXFIFO(如 CPU 響應中斷,寫入新數據到 TXFIFO);
四 數據傳輸階段 2:TXFIFO 填充后,恢復傳輸
- 軟件向 TXFIFO 寫入新數據 → ECSPI 檢測到 FIFO 非空,恢復 SCLK 時鐘脈沖;
- 繼續傳輸后續數據,直到 BURST LENGTH 定義的長度完成;
五?突發后:片選拉高,結束通信
- 所有數據傳輸完成 → SS 拉高 → 釋放從機,結束本次單突發傳輸;
多突發傳輸
?相位控制
相位控制位(
ECSPI_CONREG[PHA]
)用于控制?發送數據的移位輸出邊沿?和?接收數據的鎖存邊沿;
ECSPI Memory Map
ECSPI寄存器
ECSPIx_RXDATA
只讀寄存器(Read-Only),該寄存器始終顯示FIFO 最前端的未讀數據(即第一個入隊、尚未被讀取的數據),每次成功讀取該寄存器(且 RXFIFO 非空),FIFO 會自動推進即頭部數據被消費,下一個數據上移到 FIFO 頭部,等待下一次讀取;
ECSPIx_TXDATA
只寫寄存器(Write-Only),寫入的數據追加到 FIFO 尾部,該寄存器允許軟件持續寫入數據到 FIFO 尾部(只要 FIFO 未滿),即使 SPI 正在發送數據(
ECSPI_CONREG[XCH]=1
,即XCH 置位,硬件正在發送 TXFIFO 中的數據);
?ECSPIx_CONREG
bit[31:20]: BURST_LENGTH位,定義?單次 SPI 突發(片選(SS)僅拉低一次)傳輸的有效位數,從 LSB 開始,截取連續?
n
?位傳輸,n = BURST_LENGTH + 1,示例如下:
0x00000003
(二進制?0000 0000 0000 0000 0000 0000 0000 0011
):
BURST_LENGTH=0x000
(n=1)→ 傳輸?bit0=1
(LSB);BURST_LENGTH=0x001
(n=2)→ 傳輸?bit0=1
?,?bit1=1?
;典型值映射:
0x000
?→ 1 位(LSB 優先);0x01F
?→ 32 位(完整字傳輸);
bit[19:18]:?CHANNEL_SELECT位,通道選擇位,通道是指同一 ECSPI 模塊內部,通過硬件片選(SS0~SS3)區分的從設備選擇通道;
bit[15:12]:?PRE_DIVIDER位,預分頻,
0000
=1 分頻,0001
=2 分頻,…,1111
=16 分頻;bit[11:8]:?POST_DIVIDER位,后分頻(2 的冪次分頻),
0000
=2?=1 分頻,0001
=21=2 分頻,…,1111
=21? 分頻;ECSPI 采用?兩級分頻器?生成 SPI 時鐘(SCLK),公式:
SCLK頻率 = 參考時鐘 / [(PRE_DIVIDER + 1) × (2^POST_DIVIDER)]
- 假設參考時鐘為 80MHz,需 SCLK=10MHz → 總分頻?
80/10=8
;- 選?
PRE_DIVIDER=0001
(2 分頻),POST_DIVIDER=0010
(4 分頻)→ 總分頻?2×4=8
,符合需求;
bit[7:4]:?CHANNEL_MODE位,ECSPI1 模塊的?通道編號?與?片選引腳(SSn)?是?一一固定對應?,每個通道可獨立配置主 / 從模式;
bit[3]: SMC位,SMC位僅對主機模式通道有效,即?
CHANNEL_MODE=1
,決定:當 TXFIFO 有數據時,ECSPI 如何觸發SPI 突發傳輸,具有兩種觸發邏輯,由?SMC
?位的值決定:模式 1:
SMC = 0
(默認)→?由?XCH
?位顯式控制啟動
- 觸發條件:需軟件主動設置?
XCH
?位(ECSPI_CONREG[XCH] = 1
),才會啟動 SPI 突發傳輸;- 與?
SS_CTL
?協同:XCH
?啟動的是單次突發還是多次突發,由?SS_CTL
(SPI SS Wave Form Select)決定:
- 若?
SS_CTL
?配置為多突發模式:XCH
?置 1 后會持續啟動突發,直到 TXFIFO 空或手動清零?XCH
;- 若?
SS_CTL
?配置為單突發模式:XCH
?置 1 僅啟動一次突發,傳輸完成后自動清零?XCH
;模式 2:
SMC = 1
?→?寫入 TXFIFO 時自動啟動
- 觸發條件:無需軟件干預?
XCH
,只要向 TXFIFO 寫入數據(通過?ECSPI_TXDATA
?寄存器),硬件會立即自動啟動 SPI 突發傳輸;- 特點:數據寫入 TXFIFO 的瞬間,突發自動開始,適合需要實時采集傳感器數據的場景;
bit[2]:XCH位,用于控制?SPI 突發的啟動時機;
0
:空閑(無傳輸);1
:啟動單次 / 多次突發(由?SS_CTL
?定義模式),傳輸中自動保持置 1,完成后清零
bit[0]: EN位,使能 / 禁用 ECSPI 模塊;
- 置?
1
:使能模塊;- 置?
0
:禁用模塊;
ECSPIx_CONFIGREG
bit[23:20]:SCLK_CTL(SCLK 空閑狀態控制位),用于控制每個通道的?SCLK 在空閑期的電平狀態,
SCLK_CTL[3:0]
?分別對應?Channel 3~0;
0
:空閑時 SCLK 保持?低電平;1
:空閑時 SCLK 保持?高電平;
?bit[19:16]:DATA_CTL(數據引腳空閑狀態控制),
DATA_CTL[3:0]
?分別對應?Channel 3~0(每位控制一個通道);
0
:空閑時數據引腳保持?高電平;1
:空閑時數據引腳保持?低電平;
bit[15:12]:SS_POL(片選極性控制),控制每個通道的?片選信號(SSn)的有效電平,
SS_POL[3:0]
?分別對應?Channel 3~0;
0
:SS 有效電平為?低電平(常見模式,SS 拉低選通從機);1
:SS 有效電平為?高電平(特殊場景,SS 拉高選通從機);
bit[11:8]:?SS_CTL(片選波形控制),主機模式(
SMC=0
?時生效):
0
:單突發模式 → 片選保持低電平,僅傳輸一次突發;1
:多突發模式 → 片選在突發間拉高,連續傳輸多次突發(直到 TXFIFO 空)
bit[7:4]:SCLK_POL,控制每個通道的?SCLK 極性(空閑電平),
SCLK_POL[3:0]
?分別對應?Channel 3~0(每位控制一個通道的 SCLK 極性);
0
:SCLK 空閑電平為?高(CPOL=1);1
:SCLK 空閑電平為?低(CPOL=0);
bit[3:0]:?SCLK_PHA(時鐘相位控制,即 CPHA),控制每個通道的?SCLK 相位(數據采樣 / 移位的邊沿),
SCLK_PHA[3:0]
?分別對應?Channel 3~0(每位控制一個通道的 SCLK 相位);
0
:Phase 0 模式 → 采樣在?第一邊沿(由 CPOL 決定上升 / 下降沿);1
:Phase 1 模式 → 采樣在?第二邊沿(由 CPOL 決定上升 / 下降沿);
ECSPIx_STATREG
?bit[7]:(TC),傳輸完成狀態(Transfer Completed),用于指示當前 SPI 突發傳輸是否完成;
0
:傳輸中(數據移位未完成,或新傳輸已啟動);1
:傳輸完成(所有數據已移位輸出 / 輸入,可啟動新傳輸);- 操作:寫 1 清零(
w1c
),軟件需主動清零以準備下一次傳輸;
bit[6]: (RO),接收 FIFO 溢出(RXFIFO Overflow),用于檢測?RXFIFO 溢出錯誤;
0
:無溢出;1
:溢出(數據丟失風險,需軟件處理);- 操作:寫 1 清零(
w1c
),清零后需檢查 RXFIFO 數據,避免遺漏;
bit[5]:?(RF),接收 FIFO 滿(RXFIFO Full),用于指示 RXFIFO 是否已滿(達到 64 字深度);
0
:未滿(可繼續接收數據);1
:已滿(需立即讀取 RXFIFO,否則可能觸發 RO 溢出);- 操作:只讀,由硬件根據 FIFO 狀態自動更新;
bit[3]:?(RR),接收 FIFO 就緒(RXFIFO Ready),指示 RXFIFO 中是否有有效數據(至少 1 個字);
0
:空(無有效數據,讀取 RXDATA 會返回未定義值);1
:就緒(有數據,可安全讀取 RXDATA);- 操作:只讀,由硬件根據 FIFO 狀態自動更新;
bit[2]:?(TF),發送 FIFO 滿(TXFIFO Full),用于指示 TXFIFO 是否已滿(達到 64 字深度);
0
:未滿(可繼續寫入數據);1
:已滿(寫入 TXDATA 會失敗,需等待 FIFO 空);- 操作:只讀,由硬件根據 FIFO 狀態自動更新;
bit[0]:?(TE),發送 FIFO 空(TXFIFO Empty),用于指示 TXFIFO 是否為空(無有效數據);
0
:非空(有數據,可繼續傳輸);1
:空(需寫入數據,否則傳輸會暫停或發送 0);- 操作:只讀,由硬件根據 FIFO 狀態自動更新;
ECSPIx_PERIODREG
bit[21:16]:?CSD_CTL位,主機拉低片選(SS)選中從機后,先等幾個 SCLK 周期,讓從機準備好接收數據,CSD_CTL用于控制片選有效邊沿 → 第一個 SCLK 邊沿?的延遲時鐘數,取值范圍為?
0 - 63
,表示插入?0 - 63
?個?SPI 時鐘周期(SCLK)?的延遲;
bit[15]:CSRC位,用于選擇等待狀態的時鐘來源,決定延遲時間的基準頻率;
0
:SPI 時鐘(SCLK)→ 延遲時間隨 SCLK 頻率動態變化(當SCLK=10MHz 時,1 個等待狀態 = 100ns,當SCLK=1MHz 時 = 1μs);1
:低頻參考時鐘(32.768KHz)→ 延遲時間固定(1 個等待狀態≈30.5μs),不受 SCLK 頻率影響;
bit[14:0]:?SAMPLE_PERIOD,用于控制?連續 SPI 傳輸之間?插入的等待狀態數量,取值范圍為0~32767,僅在?主機模式(
CHANNEL_MODE=1
)且多突發傳輸時生效;