單芯片解決方案,開啟全新體驗——W55MH32 高性能以太網(wǎng)單片機
W55MH32是WIZnet重磅推出的高性能以太網(wǎng)單片機,它為用戶帶來前所未有的集成化體驗。這顆芯片將強大的組件集于一身,具體來說,一顆W55MH32內(nèi)置高性能Arm? Cortex-M3核心,其主頻最高可達216MHz;配備1024KB FLASH與96KB SRAM,滿足存儲與數(shù)據(jù)處理需求;集成TOE引擎,包含WIZnet全硬件TCP/IP協(xié)議棧、內(nèi)置MAC以及PHY,擁有獨立的32KB以太網(wǎng)收發(fā)緩存,可供8個獨立硬件socket使用。如此配置,真正實現(xiàn)了All-in-One解決方案,為開發(fā)者提供極大便利。
在封裝規(guī)格上,W55MH32 提供了兩種選擇:QFN68和QFN100。
W55MH32Q采用QFN68封裝版本,尺寸為8x8mm,它擁有36個GPIO、3個ADC、12通道DMA、17個定時器、2個I2C、3個串口、2個SPI接口(其中1個帶I2S接口復(fù)用)、1個CAN以及1個USB2.0。在保持與同系列其他版本一致的核心性能基礎(chǔ)上,僅減少了部分GPIO以及SDIO接口,其他參數(shù)保持一致,性價比優(yōu)勢顯著,尤其適合網(wǎng)關(guān)模組等對空間布局要求較高的場景。緊湊的尺寸和精簡化外設(shè)配置,使其能夠在有限空間內(nèi)實現(xiàn)高效的網(wǎng)絡(luò)連接與數(shù)據(jù)交互,成為物聯(lián)網(wǎng)網(wǎng)關(guān)、邊緣計算節(jié)點等緊湊型設(shè)備的理想選擇。 同系列還有QFN100封裝的W55MH32L版本,該版本擁有更豐富的外設(shè)資源,適用于需要多接口擴展的復(fù)雜工控場景,軟件使用方法一致。更多信息和資料請進入http://www.w5500.com/網(wǎng)站或者私信獲取。
此外,本W(wǎng)55MH32支持硬件加密算法單元,WIZnet還推出TOE+SSL應(yīng)用,涵蓋TCP SSL、HTTP SSL以及MQTT SSL等,為網(wǎng)絡(luò)通信安全再添保障。
為助力開發(fā)者快速上手與深入開發(fā),基于W55MH32Q這顆芯片,WIZnet精心打造了配套開發(fā)板。開發(fā)板集成WIZ-Link芯片,借助一根USB C口數(shù)據(jù)線,就能輕松實現(xiàn)調(diào)試、下載以及串口打印日志等功能。開發(fā)板將所有外設(shè)全部引出,拓展功能也大幅提升,便于開發(fā)者全面評估芯片性能。
若您想獲取芯片和開發(fā)板的更多詳細信息,包括產(chǎn)品特性、技術(shù)參數(shù)以及價格等,歡迎訪問官方網(wǎng)頁:http://www.w5500.com/,我們期待與您共同探索W55MH32的無限可能。

第十七章 SPI
1 SPI簡介
SPI 接口可以配置為支持 SPI 協(xié)議或者支持 I2S 音頻協(xié)議。SPI 接口默認工作在 SPI 方式,可以通過軟件把功能從 SPI 模式切換到 I2S 模式。
串行外設(shè)接口(SPI)允許芯片與外部設(shè)備以半/全雙工、同步、串行方式通信。此接口可以被配置成主模式,并為外部從設(shè)備提供通信時鐘(SCK)。接口還能以多主配置方式工作。
它可用于多種用途,包括使用一條雙向數(shù)據(jù)線的雙線單工同步傳輸,還可使用 CRC 校驗的可靠通信。
I2S 也是一種 3 引腳的同步串行接口通訊協(xié)議。它支持四種音頻標準,包括飛利浦 I2S 標準,MSB和 LSB 對齊標準,以及 PCM 標準。它在半雙工通訊中,可以工作在主和從 2 種模式下。當(dāng)它作為主設(shè)備時,通過接口向外部的從設(shè)備提供時鐘信號。
警告:由于 SPI3/I2S3 的部分引腳與 JTAG 引腳共享(SPI3_NSS/I2S3_WS 與 JTDI,SPI3_SCK/I2S3_CK 與 JTDO),因此這些引腳不受 IO 控制器控制,他們(在每次復(fù)位后)被默認保留為 JTAG 用途。如果用戶想把引腳配置給 SPI3/I2S3,必須(在調(diào)試時)關(guān)閉 JTAG并切換至 SWD 接口,或者(在標準應(yīng)用時)同時關(guān)閉 JTAG 和 SWD 接口。
JTAG/SWD 復(fù)用功能重映射。
2 SPI和I2S主要特征
2.1 SPI特征
?3 線全雙工同步傳輸
?帶或不帶第三根雙向數(shù)據(jù)線的雙線單工同步傳輸
?8 或 16 位傳輸幀格式選擇
?主或從操作
?支持多主模式
?8 個主模式波特率預(yù)分頻系數(shù)(最大為 fPCLK/2)
?從模式頻率(最大為 fPCLK/2)
?主模式和從模式的快速通信
?主模式和從模式下均可以由軟件或硬件進行 NSS 管理:主/從操作模式的動態(tài)改變
?可編程的時鐘極性和相位
?可編程的數(shù)據(jù)順序,MSB 在前或 LSB 在前
?可觸發(fā)中斷的專用發(fā)送和接收標志
?SPI 總線忙狀態(tài)標志
?支持可靠通信的硬件 CRC
······在發(fā)送模式下,CRC 值可以被作為最后一個字節(jié)發(fā)送
······在全雙工模式中對接收到的最后一個字節(jié)自動進行 CRC 校驗
?可觸發(fā)中斷的主模式故障、過載以及 CRC 錯誤標志
?支持 DMA 功能的 1 字節(jié)發(fā)送和接收緩沖器:產(chǎn)生發(fā)送和接受請求
2.2 I2S功能
?單工通信(僅發(fā)送或接收)
?主或者從操作
?8 位線性可編程預(yù)分頻器,獲得精確的音頻采樣頻率(8KHz 到 96kHz)
?數(shù)據(jù)格式可以是 16 位,24 位或者 32 位
?音頻信道固定數(shù)據(jù)包幀為 16 位(16 位數(shù)據(jù)幀)或 32 位(16、24 或 32 位數(shù)據(jù)幀)
?可編程的時鐘極性(穩(wěn)定態(tài))
?從發(fā)送模式下的下溢標志位和主/從接收模式下的溢出標志位
?16 位數(shù)據(jù)寄存器用來發(fā)送和接收,在通道兩端各有一個寄存器
?支持的 I2S 協(xié)議:
·······I2S 飛利浦標準
······MSB 對齊標準(左對齊)
······LSB 對齊標準(右對齊)
?PCM 標準(16 位通道幀上帶長或短幀同步或者 16 位數(shù)據(jù)幀擴展為 32 位通道幀)
?數(shù)據(jù)方向總是 MSB 在先
?發(fā)送和接收都具有 DMA 能力
?主時鐘可以輸出到外部音頻設(shè)備,比率固定為 256xFs(Fs 為音頻采樣頻率)
3 SPI功能描述
3.1 概述
SPI 的方框圖見下圖:

通常 SPI 通過 4 個引腳與外部器件相連:
?MISO:主設(shè)備輸入/從設(shè)備輸出引腳。該引腳在從模式下發(fā)送數(shù)據(jù),在主模式下接收數(shù)據(jù)。
?MOSI:主設(shè)備輸出/從設(shè)備輸入引腳。該引腳在主模式下發(fā)送數(shù)據(jù),在從模式下接收數(shù)據(jù)。
?SCK:串口時鐘,作為主設(shè)備的輸出,從設(shè)備的輸入
?NSS:從設(shè)備選擇。這是一個可選的引腳,用來選擇主/從設(shè)備。它的功能是用來作為“片選引腳”,讓主設(shè)備可以單獨地與特定從設(shè)備通訊,避免數(shù)據(jù)線上的沖突。從設(shè)備的 NSS 引腳可以由主設(shè)備的一個標準 I/O 引腳來驅(qū)動。一旦被使能(SSOE 位),NSS 引腳也可以作為輸出引腳,并在 SPI 處于主模式時拉低;此時,所有的 SPI 設(shè)備,如果它們的 NSS 引腳連接到主設(shè)備的 NSS 引腳,則會檢測到低電平,如果它們被設(shè)置為 NSS 硬件模式,就會自動進入從設(shè)備狀態(tài)。當(dāng)配置為主設(shè)備、NSS 配置為輸入引腳(MSTR=1,SSOE=0)時,如果 NSS 被拉低,則這個 SPI 設(shè)備進入主模式失敗狀態(tài):即 MSTR 位被自動清除,此設(shè)備進入從模式
下圖是一個單主和單從設(shè)備互連的例子:

單主和單從應(yīng)用
1.這里 NSS 引腳設(shè)置為輸入
MOSI 腳相互連接,MISO 腳相互連接。這樣,數(shù)據(jù)在主和從之間串行地傳輸(MSB 位在前)。
通信總是由主設(shè)備發(fā)起。主設(shè)備通過 MOSI 腳把數(shù)據(jù)發(fā)送給從設(shè)備,從設(shè)備通過 MISO 引腳回傳數(shù)據(jù)。這意味全雙工通信的數(shù)據(jù)輸出和數(shù)據(jù)輸入是用同一個時鐘信號同步的;時鐘信號由主設(shè)備通過 SCK 腳提供。
從選擇(NSS)腳管理
有 2 種 NSS 模式:
?軟件 NSS 模式:可以通過設(shè)置 SPI_CR1 寄存器的 SSM 位來使能這種模式(見圖 212)。在這種模式下 NSS 引腳可以用作它用,而內(nèi)部 NSS 信號電平可以通過寫 SPI_CR1 的 SSI 位來驅(qū)動。
?硬件 NSS 模式,分兩種情況:
·······NSS 輸出被使能:當(dāng) W55MH32 工作為主 SPI,并且 NSS 輸出已經(jīng)通過 SPI_CR2 寄存器的SSOE 位使能,這時 NSS 引腳被拉低,所有 NSS 引腳與這個主 SPI 的 NSS 引腳相連并配置為硬件 NSS 的 SPI 設(shè)備,將自動變成從 SPI 設(shè)備。當(dāng)一個 SPI 設(shè)備需要發(fā)送廣播數(shù)據(jù),它必須拉低 NSS 信號,以通知所有其它的設(shè)備它是主設(shè)備;如果它不能拉低 NSS,這意味著總線上有另外一個主設(shè)備在通信,這時將產(chǎn)生一個硬件失敗錯誤(Hard Fault)。
······NSS 輸出被關(guān)閉:允許操作于多主環(huán)境。

硬件/軟件的從選擇管理
時鐘信號的相位和極性
SPI_CR 寄存器的 CPOL 和 CPHA 位,能夠組合成四種可能的時序關(guān)系。CPOL(時鐘極性)位控制在沒有數(shù)據(jù)傳輸時時鐘的空閑狀態(tài)電平,此位對主模式和從模式下的設(shè)備都有效。如果 CPOL 被清'0',SCK 引腳在空閑狀態(tài)保持低電平;如果 CPOL 被置'1',SCK 引腳在空閑狀態(tài)保持高電平。如果CPHA(時鐘相位)位被置'1',SCK 時鐘的第二個邊沿(CPOL 位為 0 時就是下降沿,CPOL 位為'1'時就是上升沿)進行數(shù)據(jù)位的采樣,數(shù)據(jù)在第二個時鐘邊沿被鎖存。如果 CPHA 位被清'0',SCK 時鐘的第一邊沿(CPOL 位為'0'時就是上升沿,CPOL 位為'1'時就是下降沿)進行數(shù)據(jù)位采樣,數(shù)據(jù)在第一個時鐘邊沿被鎖存。CPOL 時鐘極性和 CPHA 時鐘相位的組合選擇數(shù)據(jù)捕捉的時鐘邊沿。
注意:
在改變 CPOL/CPHA 位之前,必須清除 SPE 位將 SPI 禁止。
主和從必須配置成相同的時序模式。
SCK 的空閑狀態(tài)必須和 SPI_CR1 寄存器指定的極性一致(CPOL 為'1'時,空閑時應(yīng)上拉 SCK 為高電平;CPOL 為'0'時,空閑時應(yīng)下拉 SCK 為低電平)。
數(shù)據(jù)幀格式(8 位或 16 位)由 SPI_CR1 寄存器的 DFF 位選擇,并且決定發(fā)送/接收的數(shù)據(jù)長度。

數(shù)據(jù)時鐘時序圖
數(shù)據(jù)幀格式
根據(jù) SPI_CR1 寄存器中的 LSBFIRST 位,輸出數(shù)據(jù)位時可以 MSB 在先也可以 LSB 在先。
根據(jù) SPI_CR1 寄存器的 DFF 位,每個數(shù)據(jù)幀可以是 8 位或是 16 位。所選擇的數(shù)據(jù)幀格式對發(fā)送和/或接收都有效。
3.2 配置SPI為從模式
在從模式下,SCK 引腳用于接收從主設(shè)備來的串行時鐘。SPI_CR1 寄存器中 BR[2:0]的設(shè)置不影響數(shù)據(jù)傳輸速率。
注: 建議在主設(shè)備發(fā)送時鐘之前使能 SPI 從設(shè)備,否則可能會發(fā)生意外的數(shù)據(jù)傳輸。在通信時鐘的第一個邊沿到來之前或正在進行的通信結(jié)束之前,從設(shè)備的數(shù)據(jù)寄存器必須就緒。在使能從設(shè)備和主設(shè)備之前,通信時鐘的極性必須處于穩(wěn)定的數(shù)值。
請按照以下步驟配置 SPI 為從模式:
配置步驟
1. 設(shè)置 DFF 位以定義數(shù)據(jù)幀格式為 8 位或 16 位。
2. 選擇 CPOL 和 CPHA 位來定義數(shù)據(jù)傳輸和串行時鐘之間的相位關(guān)系(見圖 213)。為保證正確的數(shù)據(jù)傳輸,從設(shè)備和主設(shè)備的 CPOL 和 CPHA 位必須配置成相同的方式。
3. 幀格式(SPI_CR1 寄存器中的 LSBFIRST 位定義的”MSB 在前”還是”LSB 在前”)必須與主設(shè)備相同。
4. 硬件模式下(參考從選擇(NSS)腳管理部分),在完整的數(shù)據(jù)幀(8 位或 16 位)傳輸過程中,NSS引腳必須為低電平。在 NSS 軟件模式下,設(shè)置 SPI_CR1 寄存器中的 SSM 位并清除 SSI 位。
5. 清除 MSTR 位、設(shè)置 SPE 位(SPI_CR1 寄存器),使相應(yīng)引腳工作于 SPI 模式下。在這個配置中,MOSI 引腳是數(shù)據(jù)輸入,MISO 引腳是數(shù)據(jù)輸出。
數(shù)據(jù)發(fā)送
過程在寫操作中,數(shù)據(jù)字被并行地寫入發(fā)送緩沖器。
當(dāng)從設(shè)備收到時鐘信號,并且在 MOSI 引腳上出現(xiàn)第一個數(shù)據(jù)位時,發(fā)送過程開始(譯注:此時第一個位被發(fā)送出去)。余下的位(對于 8 位數(shù)據(jù)幀格式,還有 7 位;對于 16 位數(shù)據(jù)幀格式,還有 15位)被裝進移位寄存器。當(dāng)發(fā)送緩沖器中的數(shù)據(jù)傳輸?shù)揭莆患拇嫫鲿r,SPI_SP 寄存器的 TXE 標志被設(shè)置,如果設(shè)置了 SPI_CR2 寄存器的 TXEIE 位,將會產(chǎn)生中斷。
數(shù)據(jù)接收過程
對于接收器,當(dāng)數(shù)據(jù)接收完成時:
移位寄存器中的數(shù)據(jù)傳送到接收緩沖器,SPI_SR 寄存器中的 RXNE 標志被設(shè)置。
如果設(shè)置了 SPI_CR2 寄存器中的 RXNEIE 位,則產(chǎn)生中斷。
在最后一個采樣時鐘邊沿后,RXNE 位被置'1',移位寄存器中接收到的數(shù)據(jù)字節(jié)被傳送到接收緩沖器。當(dāng)讀 SPI_DR 寄存器時,SPI 設(shè)備返回這個接收緩沖器的數(shù)值。讀 SPI_DR 寄存器時,RXNE 位被清除。
3.3 配置SPI為主模式
在主配置時,在 SCK 腳產(chǎn)生串行時鐘。
配置步驟
1. 通過 SPI_CR1 寄存器的 BR[2:0]位定義串行時鐘波特率。
2. 選擇 CPOL 和 CPHA 位,定義數(shù)據(jù)傳輸和串行時鐘間的相位關(guān)系(見圖 213)。
3. 設(shè)置 DFF 位來定義 8 位或 16 位數(shù)據(jù)幀格式。
4. 配置 SPI_CR1 寄存器的 LSBFIRST 位定義幀格式。
5. 如果需要 NSS 引腳工作在輸入模式,硬件模式下,在整個數(shù)據(jù)幀傳輸期間應(yīng)把 NSS 腳連接到高電平;在軟件模式下,需設(shè)置 SPI_CR1 寄存器的 SSM 位和 SSI 位。如果 NSS 引腳工作在輸出模式,則只需設(shè)置 SSOE 位。
必須設(shè)置 MSTR 位和 SPE 位(只當(dāng) NSS 腳被連到高電平,這些位才能保持置位)。在這個配置中,MOSI 引腳是數(shù)據(jù)輸出,而 MISO 引腳是數(shù)據(jù)輸入。
數(shù)據(jù)發(fā)送過程
當(dāng)寫入數(shù)據(jù)至發(fā)送緩沖器時,發(fā)送過程開始。
在發(fā)送第一個數(shù)據(jù)位時,數(shù)據(jù)字被并行地(通過內(nèi)部總線)傳入移位寄存器,而后串行地移出到MOSI 腳上;MSB 在先還是 LSB 在先,取決于 SPI_CR1 寄存器中的 LSBFIRST 位的設(shè)置。數(shù)據(jù)從發(fā)送緩沖器傳輸?shù)揭莆患拇嫫鲿r TXE 標志將被置位,如果設(shè)置了 SPI_CR1 寄存器中的 TXEIE位,將產(chǎn)生中斷。
數(shù)據(jù)接收過程
對于接收器來說,當(dāng)數(shù)據(jù)傳輸完成時:
傳送移位寄存器里的數(shù)據(jù)到接收緩沖器,并且 RXNE 標志被置位。
如果設(shè)置了 SPI_CR2 寄存器中的 RXNEIE 位,則產(chǎn)生中斷。
在最后采樣時鐘沿,RXNE 位被設(shè)置,在移位寄存器中接收到的數(shù)據(jù)字被傳送到接收緩沖器。讀SPI_DR 寄存器時,SPI 設(shè)備返回接收緩沖器中的數(shù)據(jù)。讀 SPI_DR 寄存器將清除 RXNE 位。
一旦傳輸開始,如果下一個將發(fā)送的數(shù)據(jù)被放進了發(fā)送緩沖器,就可以維持一個連續(xù)的傳輸流。在試圖寫發(fā)送緩沖器之前,需確認 TXE 標志應(yīng)該為'1'。
注: 在 NSS 硬件模式下,從設(shè)備的 NSS 輸入由 NSS 引腳控制或另一個由軟件驅(qū)動的 GPIO 引腳控制。
3.4 配置SPI為單工通信
SPI 模塊能夠以兩種配置工作于單工方式:
?1 條時鐘線和 1 條雙向數(shù)據(jù)線;
?1 條時鐘線和 1 條數(shù)據(jù)線(只接收或只發(fā)送);
1 條時鐘線和 1 條雙向數(shù)據(jù)線(BIDIMODE=1)
設(shè)置 SPI_CR1 寄存器中的 BIDIMODE 位而啟用此模式。在這個模式下,SCK 引腳作為時鐘,主設(shè)備使用 MOSI 引腳而從設(shè)備使用 MISO 引腳作為數(shù)據(jù)通信。傳輸?shù)姆较蛴?SPI_CR1 寄存器里的 BIDIOE控制,當(dāng)這個位是'1'的時候,數(shù)據(jù)線是輸出,否則是輸入。
1 條時鐘和 1 條單向數(shù)據(jù)線(BIDIMODE=0)
?在這個模式下,SPI 模塊可以或者作為只發(fā)送,或者作為只接收。
?只發(fā)送模式類似于全雙工模式(BIDIMODE=0,RXONLY=0):數(shù)據(jù)在發(fā)送引腳(主模式時是 MOSI、從模式時是 MISO)上傳輸,而接收引腳(主模式時是 MISO、從模式時是 MOSI)可以作為通用的I/O 使用。此時,軟件不必理會接收緩沖器中的數(shù)據(jù)(如果讀出數(shù)據(jù)寄存器,它不包含任何接收數(shù)據(jù))。
?在只接收模式,可以通過設(shè)置 SPI_CR2 寄存器的 RXONLY 位而關(guān)閉 SPI 的輸出功能;此時,發(fā)送引腳(主模式時是 MOSI、從模式時是 MISO)被釋放,可以作為其它功能使用。
配置并使能 SPI 模塊為只接收模式的方式是:
?在主模式時,一旦使能 SPI,通信立即啟動,當(dāng)清除 SPE 位時立即停止當(dāng)前的接收。在此模式下,不必讀取 BSY 標志,在 SPI 通信期間這個標志始終為'1'。
?在從模式時,只要 NSS 被拉低(或在 NSS 軟件模式時,SSI 位為'0')同時 SCK 有時鐘脈沖,SPI就一直在接收。
3.5 數(shù)據(jù)發(fā)送與接收過程
接收與發(fā)送緩沖器
在接收時,接收到的數(shù)據(jù)被存放在一個內(nèi)部的接收緩沖器中;在發(fā)送時,在被發(fā)送之前,數(shù)據(jù)將首先被存放在一個內(nèi)部的發(fā)送緩沖器中。對 SPI_DR 寄存器的讀操作,將返回接收緩沖器的內(nèi)容;寫入 SPI_DR 寄存器的數(shù)據(jù)將被寫入發(fā)送緩沖器中。
主模式下開始傳輸
?全雙工模式(BIDIMODE=0 并且 RXONLY=0)
······當(dāng)寫入數(shù)據(jù)到 SPI_DR 寄存器(發(fā)送緩沖器)后,傳輸開始;
······在傳送第一位數(shù)據(jù)的同時,數(shù)據(jù)被并行地從發(fā)送緩沖器傳送到 8 位的移位寄存器中,然后按順序被串行地移位送到 MOSI 引腳上;
······與此同時,在 MISO 引腳上接收到的數(shù)據(jù),按順序被串行地移位進入 8 位的移位寄存器中,然后被并行地傳送到 SPI_DR 寄存器(接收緩沖器)中。
?單向的只接收模式(BIDIMODE=0 并且 RXONLY=1)
········SPE=1 時,傳輸開始;
······只有接收器被激活,在 MISO 引腳上接收到的數(shù)據(jù),按順序被串行地移位進入 8 位的移位寄存器中,然后被并行地傳送到 SPI_DR 寄存器(接收緩沖器)中。
······雙向模式,發(fā)送時(BIDIMODE=1 并且 BIDIOE=1)
······當(dāng)寫入數(shù)據(jù)到 SPI_DR 寄存器(發(fā)送緩沖器)后,傳輸開始;
·······在傳送第一位數(shù)據(jù)的同時,數(shù)據(jù)被并行地從發(fā)送緩沖器傳送到 8 位的移位寄存器中,然后按順序被串行地移位送到 MOSI 引腳上;
······不接收數(shù)據(jù)。
?雙向模式,接收時(BIDIMODE=1 并且 BIDIOE=0)
······SPE=1 并且 BIDIOE=0 時,傳輸開始;
······在 MOSI 引腳上接收到的數(shù)據(jù),按順序被串行地移位進入 8 位的移位寄存器中,然后被并行地傳送到 SPI_DR 寄存器(接收緩沖器)中。
······不激活發(fā)送器,沒有數(shù)據(jù)被串行地送到 MOSI 引腳上。
從模式下開始傳輸
?全+雙工模式(BIDIMODE=0 并且 RXONLY=0)
······當(dāng)從設(shè)備接收到時鐘信號并且第一個數(shù)據(jù)位出現(xiàn)在它的 MOSI 時,數(shù)據(jù)傳輸開始,隨后的數(shù)據(jù)位依次移動進入移位寄存器;
······與此同時,在傳輸?shù)谝粋€數(shù)據(jù)位時,發(fā)送緩沖器中的數(shù)據(jù)被并行地傳送到 8 位的移位寄存器,隨后被串行地發(fā)送到 MISO 引腳上。軟件必須保證在 SPI 主設(shè)備開始數(shù)據(jù)傳輸之前在發(fā)送寄存器中寫入要發(fā)送的數(shù)據(jù)。
?單向的只接收模式(BIDIMODE=0 并且 RXONLY=1)
·······當(dāng)從設(shè)備接收到時鐘信號并且第一個數(shù)據(jù)位出現(xiàn)在它的 MOSI 時,數(shù)據(jù)傳輸開始,隨后數(shù)據(jù)位依次移動進入移位寄存器;
······不啟動發(fā)送器,沒有數(shù)據(jù)被串行地傳送到 MISO 引腳上。
?雙向模式,發(fā)送時(BIDIMODE=1 并且 BIDIOE=1)
······當(dāng)從設(shè)備接收到時鐘信號并且發(fā)送緩沖器中的第一個數(shù)據(jù)位被傳送到MISO引腳上的時候,數(shù)據(jù)傳輸開始;
······在第一個數(shù)據(jù)位被傳送到 MISO 引腳上的同時,發(fā)送緩沖器中要發(fā)送的數(shù)據(jù)被平行地傳送到 8 位的移位寄存器中,隨后被串行地發(fā)送到 MISO 引腳上。軟件必須保證在 SPI 主設(shè)備開始數(shù)據(jù)傳輸之前在發(fā)送寄存器中寫入要發(fā)送的數(shù)據(jù);
······不接收數(shù)據(jù)。
?雙向模式,接收時(BIDIMODE=1 并且 BIDIOE=0)
······當(dāng)從設(shè)備接收到時鐘信號并且第一個數(shù)據(jù)位出現(xiàn)在它的 MOSI 時,數(shù)據(jù)傳輸開始;
······從 MISO 引腳上接收到的數(shù)據(jù)被串行地傳送到 8 位的移位寄存器中,然后被平行地傳送到SPI_DR 寄存器(接收緩沖器);
······不啟動發(fā)送器,沒有數(shù)據(jù)被串行地傳送到 MISO 引腳上。
處理數(shù)據(jù)的發(fā)送與接收
當(dāng)數(shù)據(jù)從發(fā)送緩沖器傳送到移位寄存器時,設(shè)置 TXE 標志(發(fā)送緩沖器空),它表示內(nèi)部的發(fā)送緩沖器可以接收下一個數(shù)據(jù);如果在 SPI_CR2 寄存器中設(shè)置了 TXEIE 位,則此時會產(chǎn)生一個中斷;寫入 SPI_DR 寄存器即可清除 TXE 位。
注: 在寫入發(fā)送緩沖器之前,軟件必須確認 TXE 標志為'1',否則新的數(shù)據(jù)會覆蓋已經(jīng)在發(fā)送緩沖器中的數(shù)據(jù)。
在采樣時鐘的最后一個邊沿,當(dāng)數(shù)據(jù)被從移位寄存器傳送到接收緩沖器時,設(shè)置 RXNE 標志(接收緩沖器非空);它表示數(shù)據(jù)已經(jīng)就緒,可以從 SPI_DR 寄存器讀出;如果在 SPI_CR2 寄存器中設(shè)置了 RXNEIE 位,則此時會產(chǎn)生一個中斷;讀出 SPI_DR 寄存器即可清除 RXNIE 標志位。
在一些配置中,傳輸最后一個數(shù)據(jù)時,可以使用 BSY 標志等待數(shù)據(jù)傳輸?shù)慕Y(jié)束。
主或從模式下(BIDIMODE=0 并且 RXONLY=0)全雙工發(fā)送和接收過程模式
1. 設(shè)置 SPE 位為'1',使能 SPI 模塊;
2. 在 SPI_DR 寄存器中寫入第一個要發(fā)送的數(shù)據(jù),這個操作會清除 TXE 標志;
3. 等待 TXE=1,然后寫入第二個要發(fā)送的數(shù)據(jù)。等待 RXNE=1,然后讀出 SPI_DR 寄存器并獲得第一個接收到的數(shù)據(jù),讀 SPI_DR 的同時清除了 RXNE 位。重復(fù)這些操作,發(fā)送后續(xù)的數(shù)據(jù)同時接收 n-1 個數(shù)據(jù);
4. 等待 RXNE=1,然后接收最后一個數(shù)據(jù);
5. 等待 TXE=1,在 BSY=0 之后關(guān)閉 SPI 模塊。
也可以在響應(yīng) RXNE 或 TXE 標志的上升沿產(chǎn)生的中斷的處理程序中實現(xiàn)這個過程。

主模式、全雙工模式下(BIDIMODE=0 并且 RXONLY=0)連續(xù)傳輸時,TXE/RXNE/BSY 的變化示意圖
從模式、全雙工模式下(BIDIMODE=0 并且 RXONLY=0)連續(xù)傳輸時,TXE/RXNE/BSY 的變化示意圖
只發(fā)送過程(BIDIMODE=0 并且 RXONLY=0)
在此模式下,傳輸過程可以簡要說明如下,使用 BSY 位等待傳輸?shù)慕Y(jié)束(見下兩圖):
1. 設(shè)置 SPE 位為'1',使能 SPI 模塊;
2. 在 SPI_DR 寄存器中寫入第一個要發(fā)送的數(shù)據(jù),這個操作會清除 TXE 標志;
3. 等待 TXE=1,然后寫入第二個要發(fā)送的數(shù)據(jù)。重復(fù)這個操作,發(fā)送后續(xù)的數(shù)據(jù);
4. 寫入最后一個數(shù)據(jù)到 SPI_DR 寄存器之后,等待 TXE=1;然后等待 BSY=0,這表示最后一個數(shù)據(jù)的傳輸已經(jīng)完成。
也可以在響應(yīng) TXE 標志的上升沿產(chǎn)生的中斷的處理程序中實現(xiàn)這個過程。
注:
對于不連續(xù)的傳輸,在寫入 SPI_DR 寄存器的操作與設(shè)置 BSY 位之間有 2 個 APB 時鐘周期的延遲,因此在只發(fā)送模式下,寫入最后一個數(shù)據(jù)后,最好先等待 TXE=1,然后再等待 BSY=0。
只發(fā)送模式下,在傳輸 2 個數(shù)據(jù)之后,由于不會讀出接收到的數(shù)據(jù),SPI_SR 寄存器中的 OVR位會變?yōu)?1'。軟件不必理會這個 OVR 標志位。

主設(shè)備只發(fā)送模式(BIDIMODE=0 并且 RXONLY=0)下連續(xù)傳輸時,,TXE/BSY 變化示意圖

從設(shè)備只發(fā)送模式(BIDIMODE=0 并且 RXONLY=0)下連續(xù)傳輸時,TXE/BSY 變化示意圖
雙向發(fā)送過程(BIDIMODE=1 并且 BIDIOE=1)
在此模式下,操作過程類似于只發(fā)送模式,不同的是:在使能 SPI 模塊之前,需要在 SPI_CR2 寄存器中同時設(shè)置 BIDIMODE 和 BIDIOE 位為'1'。
單向只接收模式(BIDIMODE=0 并且 RXONLY=1)在此模式下,傳輸過程可以簡要說明如下(見):
在 SPI_CR2 寄存器中,設(shè)置 RXONLY=1;
設(shè)置 SPE=1,使能 SPI 模塊:
主模式下,立刻產(chǎn)生 SCK 時鐘信號,在關(guān)閉 SPI(SPE=0)之前,不斷地接收串行數(shù)據(jù);
從模式下,當(dāng) SPI 主設(shè)備拉低 NSS 信號并產(chǎn)生 SCK 時鐘時,接收串行數(shù)據(jù)。
等待 RXNE=1,然后讀出 SPI_DR 寄存器以獲得收到的數(shù)據(jù)(同時會清除 RXNE 位)。重復(fù)這個操作接收所有數(shù)據(jù)。也可以在響應(yīng) RXNE 標志的上升沿產(chǎn)生的中斷的處理程序中實現(xiàn)這個過程。
注: 如果在最后一個數(shù)據(jù)傳輸結(jié)束后關(guān)閉 SPI 模塊,請按照第 16.3.8 節(jié)的建議操作

只接收模式(BIDIMODE=0 并且 RXONLY=1)下連續(xù)傳輸時,RXNE 變化示意圖
單向接收過程(BIDIMODE=1 并且 BIDIOE=0)
在此模式下,操作過程類似于只接收模式,不同的是:在使能 SPI 模塊之前,需要在 SPI_CR2 寄存器中設(shè)置 BIDIMODE 為'1'并清除 BIDIOE 位為'0'。
連續(xù)和非連續(xù)傳輸
當(dāng)在主模式下發(fā)送數(shù)據(jù)時,如果軟件足夠快,能夠在檢測到每次 TXE 的上升沿(或 TXE 中斷),并立即在正在進行的傳輸結(jié)束之前寫入 SPI_DR 寄存器,則能夠?qū)崿F(xiàn)連續(xù)的通信;此時,在每個數(shù)據(jù)項的傳輸之間的 SPI 時鐘保持連續(xù),同時 BSY 位不會被清除。
如果軟件不夠快,則會導(dǎo)致不連續(xù)的通信;這時,在每個數(shù)據(jù)傳輸之間會被清除(見下圖)。在主模式的只接收模式下(RXONLY=1),通信總是連續(xù)的,而且 BSY 標志始終為'1'。
在從模式下,通信的連續(xù)性由 SPI 主設(shè)備決定。不管怎樣,即使通信是連續(xù)的,BSY 標志會在每個數(shù)據(jù)項之間至少有一個 SPI 時鐘周期為低。

非連續(xù)傳輸發(fā)送(BIDIMODE=0 并且 RXONLY=0)時,TXE/BSY 變化示意圖
4 利用DMA的SPI通信
為了達到最大通信速度,需要及時往 SPI 發(fā)送緩沖器填數(shù)據(jù),同樣接收緩沖器中的數(shù)據(jù)也必須及時讀走以防止溢出。為了方便高速率的數(shù)據(jù)傳輸,SPI 實現(xiàn)了一種采用簡單的請求/應(yīng)答的 DMA 機制。
當(dāng) SPI_CR2 寄存器上的對應(yīng)使能位被設(shè)置時,SPI 模塊可以發(fā)出 DMA 傳輸請求。發(fā)送緩沖器和接收緩沖器亦有各自的 DMA 請求。
發(fā)送時,在每次 TXE 被設(shè)置為'1'時發(fā)出 DMA 請求,DMA 控制器則寫數(shù)據(jù)至 SPI_DR 寄存器,TXE 標志因此而被清除。
接收時,在每次 RXNE 被設(shè)置為'1'時發(fā)出 DMA 請求,DMA 控制器則從 SPI_DR 寄存器讀出數(shù)據(jù),RXNE 標志因此而被清除。當(dāng)只使用 SPI 發(fā)送數(shù)據(jù)時,只需使能 SPI 的發(fā)送 DMA 通道。此時,因為沒有讀取收到的數(shù)據(jù),OVR被置為'1'(譯注:軟件不必理會這個標志)。當(dāng)只使用 SPI 接收數(shù)據(jù)時,只需使能 SPI 的接收 DMA 通道。
在發(fā)送模式下,當(dāng) DMA 已經(jīng)傳輸了所有要發(fā)送的數(shù)據(jù)(DMA_ISR 寄存器的 TCIF 標志變?yōu)?1')后,可以通過監(jiān)視 BSY 標志以確認 SPI 通信結(jié)束,這樣可以避免在關(guān)閉 SPI 或進入停止模式時,破壞最后一個數(shù)據(jù)的傳輸。因此軟件需要先等待 TXE=1,然后等待 BSY=0。
注: 在不連續(xù)的通信中,在寫數(shù)據(jù)到 SPI_DR 的操作與 BSY 位被置為'1'之間,有 2 個 APB 時鐘周期的延遲,因此,在寫完最后一個數(shù)據(jù)后需要先等待 TXE=1 再等待 BSY=0。

使用 DMA 發(fā)送

使用 DMA 接收
5 SPI中斷
SPI 中斷請求
| 中斷事件 | 事件標志 | 使能控制位 |
| 發(fā)送緩沖器空標志 | TXE | TXEIE |
| 接收緩沖器非空標志 | RXNE | RXNEIE |
| 主模式失效事件 | MODF | ERRIE |
| 溢出錯誤 | OVR | ERRIE |
| CRC 錯誤標志 | CRCERR | ERRIE |
6 例程設(shè)計
6.1 SPI_DMA例程
1.UART 模塊:配置 USART1,將printf輸出重定向到該串口,用于輸出系統(tǒng)時鐘信息與測試提示。
2.SPI 模塊:使能 SPI1 和 GPIOA 時鐘,配置相關(guān)引腳。
初始化 SPI1,設(shè)置為雙線全雙工、主模式,數(shù)據(jù)大小為 8 位等參數(shù)。
3.DMA 模塊:使能 DMA1 時鐘,配置 DMA1 通道 2 用于 SPI1 的接收,通道 3 用于 SPI1 的發(fā)送。
分別設(shè)置通道的外設(shè)地址、內(nèi)存地址、數(shù)據(jù)傳輸方向等參數(shù)。
使能 SPI1 的 DMA 收發(fā)請求,但初始時禁用 DMA 通道。
4.主函數(shù)模塊:初始化延時函數(shù)和 UART。
int main(void)
{
RCC_ClocksTypeDef clocks;
uint16_t i;
// 初始化延時和串口
delay_init();
UART_Configuration(115200);
// 打印系統(tǒng)時鐘信息
RCC_GetClocksFreq(&clocks);
printf("nSYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhzn",
(float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000,
(float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000);
printf("SPI DMA Test.n");
// 初始化緩沖區(qū):發(fā)送數(shù)據(jù)為0x01~0xFF,接收緩沖區(qū)清零
for (i = 0; i < SPI_BUFF_SIZE; i++)
{
SPI_TX_BUFF[i] = i + 1;
}
memset(SPI_RX_BUFF, 0, sizeof(SPI_RX_BUFF));
// 初始化SPI和DMA
SPI_Configuration();
DMA_Configuration();
// ================== SPI發(fā)送測試 ==================
printf("Start SPI DMA transmission...n");
GPIO_ResetBits(GPIOA, GPIO_Pin_4); // 拉低片選(CS有效)
printf("Chip select (CS) is pulled low.n");
DMA_Cmd(DMA1_Channel3, ENABLE); // 啟用發(fā)送通道
printf("DMA channel 3 for SPI Tx is enabled.n");
// 等待發(fā)送完成(查詢傳輸完成標志)
while (!DMA_GetFlagStatus(DMA1_FLAG_TC3))
{
printf("DMA transfer in progress...n");
delay_ms(10);
}
printf("DMA transfer completed.n");
// 清除標志并禁用通道
DMA_ClearFlag(DMA1_FLAG_TC3);
printf("DMA transfer complete flag is cleared.n");
DMA_Cmd(DMA1_Channel3, DISABLE);
printf("DMA channel 3 for SPI Tx is disabled.n");
delay_ms(100);
GPIO_SetBits(GPIOA, GPIO_Pin_4); // 拉高片選(CS無效)
printf("Chip select (CS) is pulled high.n");
// 打印發(fā)送數(shù)據(jù)
printf("Data sent via SPI:n");
for (i = 0; i < SPI_BUFF_SIZE; i++)
{
printf("%02X ", SPI_TX_BUFF[i]);
if ((i + 1) % 16 == 0) printf("n");
}
printf("n");
// ================== SPI接收測試(如需自發(fā)自收需硬件環(huán)路) ==================
printf("Start SPI DMA reception...n");
GPIO_ResetBits(GPIOA, GPIO_Pin_4); // 再次拉低片選(僅示例,實際需硬件支持)
printf("Chip select (CS) is pulled low.n");
DMA_Cmd(DMA1_Channel2, ENABLE); // 啟用接收通道
printf("DMA channel 2 for SPI Rx is enabled.n");
// 等待接收完成(假設(shè)發(fā)送后立即接收,需根據(jù)硬件調(diào)整)
while (!DMA_GetFlagStatus(DMA1_FLAG_TC2))
{
printf("DMA Rx transfer in progress...n");
delay_ms(10);
}
printf("DMA Rx transfer completed.n");
DMA_ClearFlag(DMA1_FLAG_TC2);
printf("DMA Rx transfer complete flag is cleared.n");
DMA_Cmd(DMA1_Channel2, DISABLE);
printf("DMA channel 2 for SPI Rx is disabled.n");
GPIO_SetBits(GPIOA, GPIO_Pin_4); // 拉高片選
// 打印接收數(shù)據(jù)(需硬件環(huán)路才能看到有效數(shù)據(jù))
printf("Data received via SPI:n");
for (i = 0; i < SPI_BUFF_SIZE; i++)
{
printf("%02X ", SPI_RX_BUFF[i]);
if ((i + 1) % 16 == 0) printf("n");
}
printf("n");
while (1); // 主循環(huán)保持運行
}
?獲取系統(tǒng)時鐘頻率并輸出。
?填充發(fā)送緩沖區(qū),清空接收緩沖區(qū)。
?配置 SPI 和 DMA。
?拉低片選信號,使能 DMA 發(fā)送通道,等待發(fā)送完成后清除標志位、禁用通道,最后拉高片選信號。
6.2 SPI_MasterSlaveDma例程
該例程是一個基于 W55MH32 的 SPI DMA 通信測試程序,支持主從模式切換,以下是其詳細運行過程:
1. 初始化階段
(1)時鐘配置
// 時鐘配置函數(shù):啟用HSE并配置PLL倍頻
void RCC_ClkConfiguration(void)
{
RCC_DeInit(); // 復(fù)位RCC配置到默認狀態(tài)
// 啟用外部高速時鐘(HSE)
RCC_HSEConfig(RCC_HSE_ON);
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); // 等待HSE穩(wěn)定
// 禁用PLL并配置PLL參數(shù)(HSE×27倍頻,假設(shè)HSE=8MHz,最終SYSCLK=216MHz)
RCC_PLLCmd(DISABLE);
WIZ_RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_27, 1); // HSE作為PLL輸入,倍頻27倍
RCC_PLLCmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); // 等待PLL鎖定
// 設(shè)置系統(tǒng)時鐘源及總線分頻
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // 使用PLL作為系統(tǒng)時鐘
RCC_HCLKConfig(RCC_SYSCLK_Div1); // AHB總線時鐘 = SYSCLK (216MHz)
RCC_PCLK1Config(RCC_HCLK_Div2); // APB1總線時鐘 = HCLK/2 (108MHz)
RCC_PCLK2Config(RCC_HCLK_Div1); // APB2總線時鐘 = HCLK (216MHz)
// 啟用內(nèi)部低速(LSI)和高速(HSI)時鐘(供其他外設(shè)使用)
RCC_LSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET);
RCC_HSICmd(ENABLE);
while (RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET);
}
?調(diào)用RCC_ClkConfiguration():啟用外部高速時鐘(HSE),配置 PLL 為 HSE×27 倍頻(最終 SYSCLK=72MHz)。
······配置 AHB 時鐘(HCLK)=72MHz,APB1(PCLK1)=36MHz,APB2(PCLK2)=72MHz。
·······啟用內(nèi)部低速時鐘(LSI)和高速時鐘(HSI)。
(2)串口初始化
?調(diào)用UART_Configuration(115200):配置 USART1 波特率為 115200,8 位數(shù)據(jù)位,1 位停止位,無校驗。
······初始化 GPIOA 的 Pin9(TX)和 Pin10(RX)為復(fù)用推挽輸出和浮空輸入。
······使能 USART1。
(3)打印時鐘信息
通過RCC_GetClocksFreq()獲取并打印系統(tǒng)各時鐘頻率:
SYSCLK: 72.0Mhz, HCLK: 72.0Mhz, PCLK1: 36.0Mhz, PCLK2: 72.0Mhz, ADCCLK: 36.0Mhz
2. 數(shù)據(jù)準備階段
初始化發(fā)送緩沖區(qū):
for (i = 0; i < SPI_BUFF_SIZE; i++) {
SPI_TX_BUFF[i] = i + 1; // 填充數(shù)據(jù)0x01~0xFF
}
清空接收緩沖區(qū):
memset(SPI_RX_BUFF, 0, sizeof(SPI_RX_BUFF));
3. SPI 與 DMA 配置
(1)模式選擇
?通過條件編譯選擇主模式(SPI_MASTER)或從模式(SPI_SLAVE)。當(dāng)前代碼默認為主模式。
(2)GPIO 與時鐘使能
?主模式(SPI3):使能 SPI3、GPIOA、GPIOB、DMA2 時鐘。
······配置 GPIOB 的 Pin3(MOSI)、Pin4(MISO)、Pin5(SCK)為復(fù)用推挽輸出。
······配置 GPIOA 的 Pin15 為片選(CS)輸出,初始拉高。
(3)DMA 配置
?接收通道(DMA2_Channel1):外設(shè)地址為SPI3->DR,內(nèi)存地址為SPI_RX_BUFF。
······方向為外設(shè)到內(nèi)存,數(shù)據(jù)寬度為 8 位,循環(huán)模式關(guān)閉。
······使能 DMA 傳輸完成中斷。
?發(fā)送通道(DMA2_Channel2):外設(shè)地址為SPI3->DR,內(nèi)存地址為SPI_TX_BUFF。
······方向為內(nèi)存到外設(shè),其他參數(shù)與接收通道一致。
(4)SPI 初始化
?主模式配置:全雙工模式,8 位數(shù)據(jù),CPOL = 低,CPHA = 第一邊沿(模式 0)。
······波特率預(yù)分頻為 8(SPI 時鐘 = 72MHz/8=9MHz)。
······使能 SPI3。
4. 數(shù)據(jù)傳輸階段
(1)觸發(fā) DMA 傳輸
void SpiDmaTrans(unsigned char *sendBuffer, unsigned char *reciveBuffer, unsigned int len)
{
// 主模式下拉低片選信號(假設(shè)PA15為片選引腳)
#ifdef SPI_MASTER
GPIO_ResetBits(GPIOA, GPIO_Pin_15); // 拉低片選,選中從設(shè)備
#endif
// 禁用舊的DMA請求和通道(確保配置干凈)
SPI_I2S_DMACmd(UseSpi, SPI_I2S_DMAReq_Tx, DISABLE);
SPI_I2S_DMACmd(UseSpi, SPI_I2S_DMAReq_Rx, DISABLE);
DMA_Cmd(UseTxChannel, DISABLE);
DMA_Cmd(UseRxChannel, DISABLE);
// 配置DMA緩沖區(qū)地址
UseTxChannel->CMAR = (uint32_t)sendBuffer; // 發(fā)送緩沖區(qū)地址
UseRxChannel->CMAR = (uint32_t)reciveBuffer; // 接收緩沖區(qū)地址
// 設(shè)置傳輸數(shù)據(jù)長度(256字節(jié))
UseTxChannel->CNDTR = len;
UseRxChannel->CNDTR = len;
// 重置傳輸完成標志
SpiTransFinish = 0;
// 啟用DMA通道和SPI的DMA請求
DMA_Cmd(UseRxChannel, ENABLE); // 先啟用接收通道(確保同步)
DMA_Cmd(UseTxChannel, ENABLE);
SPI_I2S_DMACmd(UseSpi, SPI_I2S_DMAReq_Rx, ENABLE); // 使能SPI接收DMA請求
SPI_I2S_DMACmd(UseSpi, SPI_I2S_DMAReq_Tx, ENABLE); // 使能SPI發(fā)送DMA請求
}
?調(diào)用SpiDmaTrans():拉低片選信號(GPIOA Pin15)。
······配置 DMA 緩沖區(qū)地址和數(shù)據(jù)長度(256 字節(jié))。
······啟用 DMA 通道和 SPI 的 DMA 請求。
(2)中斷處理
?傳輸完成中斷(UseSpiTransFinishHanlder):清除 DMA 完成標志,禁用 DMA 通道。
······拉高片選信號(主模式)。
······設(shè)置SpiTransFinish標志,通知主循環(huán)傳輸完成。
5. 數(shù)據(jù)驗證與循環(huán)
?主循環(huán)邏輯:等待 DMA 傳輸完成(SpiTransFinish標志)。
·······比較發(fā)送與接收數(shù)據(jù):若不一致,打印錯誤信息并進入死循環(huán)。
--若一致,打印>>success并延時 10ms 后重試。
7 下載驗證
7.1 SPI_DMA例程
程序啟動
通過串口輸出系統(tǒng)時鐘頻率信息,可確認時鐘配置是否正確。
顯示測試提示信息,表明開始進行 SPI 的 DMA 數(shù)據(jù)傳輸測試。
SPI 數(shù)據(jù)發(fā)送
拉低片選信號(GPIOA 的引腳 4),選中 SPI 從設(shè)備,準備傳輸數(shù)據(jù)。
使能 DMA 發(fā)送通道,開始通過 SPI1 將發(fā)送緩沖區(qū)的數(shù)據(jù)傳輸?shù)綇脑O(shè)備。
等待 DMA 傳輸完成,此過程中硬件上 SPI 總線會有相應(yīng)信號傳輸。
傳輸完成后,清除 DMA 傳輸完成標志,禁用 DMA 發(fā)送通道。
拉高片選信號,結(jié)束本次數(shù)據(jù)傳輸。

7.2 SPI_MasterSlaveDma例程

WIZnet 是一家無晶圓廠半導(dǎo)體公司,成立于 1998 年。產(chǎn)品包括互聯(lián)網(wǎng)處理器 iMCU?,它采用 TOE(TCP/IP 卸載引擎)技術(shù),基于獨特的專利全硬連線 TCP/IP。iMCU? 面向各種應(yīng)用中的嵌入式互聯(lián)網(wǎng)設(shè)備。
WIZnet 在全球擁有 70 多家分銷商,在香港、韓國、美國設(shè)有辦事處,提供技術(shù)支持和產(chǎn)品營銷。
香港辦事處管理的區(qū)域包括:澳大利亞、印度、土耳其、亞洲(韓國和日本除外)。
審核編輯 黃宇
-
crc
+關(guān)注
關(guān)注
0文章
205瀏覽量
30611 -
SPI
+關(guān)注
關(guān)注
17文章
1863瀏覽量
99676 -
I2S
+關(guān)注
關(guān)注
1文章
80瀏覽量
43855
發(fā)布評論請先 登錄
第十七章 SPI——讀寫串行FLASH
文檔更新 | 迅為RK3568驅(qū)動指南-第十七篇(串口)
全國互聯(lián)電網(wǎng)調(diào)度管理規(guī)程(試行)
太陽能充放電控制————求解
火力發(fā)電廠水汽分析方法 第十七部分:聯(lián)氨的測定(直接法)DL
第十七講 譯碼器
模擬電路網(wǎng)絡(luò)課件 第十七節(jié):結(jié)型場效應(yīng)管
第十七屆中國電子電路行業(yè)排行榜頒獎會議正式召開
【正點原子FPGA連載】第三十七章雙路高速AD實驗 -摘自【正點原子】新起點之FPGA開發(fā)指南_V2.1
"STM32H7學(xué)習(xí)繼續(xù)(STM32H7系列5)第十七章比較實用,以后寫程序的時候會用到"
云英谷科技VTOS6205斬獲第十七屆“中國芯”優(yōu)秀技術(shù)創(chuàng)新產(chǎn)品獎

第十七章 SPI
評論