基于STM32Cube的嵌入式系統(tǒng)應(yīng)用 課件 第8、9章 STM32通用同步異步收發(fā)器、STM32 SPI控制器_第1頁
基于STM32Cube的嵌入式系統(tǒng)應(yīng)用 課件 第8、9章 STM32通用同步異步收發(fā)器、STM32 SPI控制器_第2頁
基于STM32Cube的嵌入式系統(tǒng)應(yīng)用 課件 第8、9章 STM32通用同步異步收發(fā)器、STM32 SPI控制器_第3頁
基于STM32Cube的嵌入式系統(tǒng)應(yīng)用 課件 第8、9章 STM32通用同步異步收發(fā)器、STM32 SPI控制器_第4頁
基于STM32Cube的嵌入式系統(tǒng)應(yīng)用 課件 第8、9章 STM32通用同步異步收發(fā)器、STM32 SPI控制器_第5頁
已閱讀5頁,還剩130頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第8章STM32通用同步/異步收發(fā)器本章講述了STM32通用同步異步收發(fā)器,包括串行通信基礎(chǔ)、STM32的USART工作原理、USART的HAL驅(qū)動程序、采用STM32Cube和HAL庫的USART串行通信應(yīng)用實例。8.1串行通信基礎(chǔ)在串行通信中,參與通信的兩臺或多臺設(shè)備通常共享一條物理通路。發(fā)送者依次逐位發(fā)送一串?dāng)?shù)據(jù)信號,按一定的約定規(guī)則為接收者所接收。由于串行端口通常只是規(guī)定了物理層的接口規(guī)范,所以為確保每次傳送的數(shù)據(jù)報文能準(zhǔn)確到達(dá)目的地,使每一個接收者能夠接收到所有發(fā)向它的數(shù)據(jù),必須在通信連接上采取相應(yīng)的措施。8.1.1串行異步通信數(shù)據(jù)格式無論是RS-232還是RS-485,均可采用通用異步收發(fā)數(shù)據(jù)格式。串行異步收發(fā)(UART)通信的數(shù)據(jù)格式如圖8-1所示。圖8-1串行異步收發(fā)(UART)通信的數(shù)據(jù)格式8.1.2串行同步通信數(shù)據(jù)格式同步通信是由1~2個同步字符和多字節(jié)數(shù)據(jù)位組成,同步字符作為起始位以觸發(fā)同步時鐘開始發(fā)送或接收數(shù)據(jù);多字節(jié)數(shù)據(jù)之間不允許有空隙,每位占用的時間相等;空閑位需發(fā)送同步字符。同步通信傳送的多字節(jié)數(shù)據(jù)由于中間沒有空隙,因而傳輸速度較快,但要求有準(zhǔn)確的時鐘來實現(xiàn)收發(fā)雙方的嚴(yán)格同步,對硬件要求較高,適用于成批數(shù)據(jù)傳送。串行同步收發(fā)通信的數(shù)據(jù)格式如圖8-2所示。圖8-2串行同步收發(fā)通信的數(shù)據(jù)格式通信是嵌入式系統(tǒng)的重要功能之一嵌入式系統(tǒng)中使用的通信接口有很多,如UART、SPI、I2C、USB和CAN等。其中,UART(UniversalAsynchronousReceiver/Transmitter,通用異步收發(fā)器)是最常見、最方便、使用最頻繁的通信接口。在嵌入式系統(tǒng)中,很多微控制器或者外設(shè)模塊都帶有UART接口。例如,STM32F407系列微控制器、6軸運(yùn)動處理組件MPU6050(包括3軸陀螺儀和3軸加速器)、超聲波測距模塊US-100、GPS模塊UBLOX、13.56MHz非接觸式IC卡讀卡模塊RC522等。8.2STM32的USART工作原理它們彼此通過UART相互通信交換數(shù)據(jù),但由于UART通信距離較短,一般僅能支持板級通信,因此,通常在UART的基礎(chǔ)上,經(jīng)過簡單擴(kuò)展或變換,就可以得到實際生活中常用的各種適于較長距離的串行數(shù)據(jù)通信接口,如R-S232、RS-485和IrDA等。出于成本和功能兩方面的考慮,目前大多的半導(dǎo)體廠商選擇在微控制器內(nèi)部集成UART模塊。ST有限公司的STM32F407系列微控制器也不例外,在它內(nèi)部配備了強(qiáng)大的UART模塊USART(UniversalSynchronous/AsynchronousReceiver/Transmitter,通用同步/異步收發(fā)器)。STM32F407的USART模塊不僅具備UART接口的基本功能,而且還支持同步單向通信、LIN(局部互聯(lián)網(wǎng))協(xié)議、智能卡協(xié)議、IrDASIR編碼/解碼規(guī)范、調(diào)制解調(diào)器(CTS/RTS)操作。8.2.1USART介紹通用同步/異步收發(fā)器可以說是嵌入式系統(tǒng)中除了GPIO外最常用的一種外設(shè)。USART常用的原因不在于其性能超強(qiáng),而是因為USART的簡單、通用。USART通信的另一個優(yōu)勢是可以適應(yīng)不同的物理層。例如,使用RS-232或RS-485可以明顯提升USART通信的距離,無線FSK調(diào)制可以降低布線施工的難度。所以USART口在工控領(lǐng)域也有著廣泛的應(yīng)用,是串行接口的工業(yè)標(biāo)準(zhǔn)(IndustryStandard)。SM32F407微控制器的小容量產(chǎn)品有2個USART,中等容量產(chǎn)品有3個USART,大容量產(chǎn)品有3個USART+2個UART(UniversalAsynchronousReceiver/Transmitter)。8.2.2USART的主要特性USART主要特性如下:(1)全雙工的,異步通信。(2)NRZ標(biāo)準(zhǔn)格式。(3)分?jǐn)?shù)波特率發(fā)生器系統(tǒng)。發(fā)送和接收共用的可編程波特率,最高達(dá)10.5Mb/s。(4)可編程數(shù)據(jù)字長度(8位或9位)。(5)可配置的停止位-支持1或2個停止位。(6)LIN主發(fā)送同步斷開符的能力以及LIN從檢測斷開符的能力。當(dāng)USART硬件配置成LIN時,生成13位斷開符;檢測10/11位斷開符。(7)發(fā)送方為同步傳輸提供時鐘。(8)IRDASIR編碼器解碼器。在正常模式下支持3/16位的持續(xù)時間。(9)智能卡模擬功能。智能卡接口支持ISO7816-3標(biāo)準(zhǔn)里定義的異步智能卡協(xié)議;智能卡用到0.5和1.5個停止位。(10)單線半雙工通信。(11)可配置的使用DMA的多緩沖器通信。在SRAM里利用集中式DMA緩沖接收/發(fā)送字節(jié)。(12)單獨(dú)的發(fā)送器和接收器使能位。(13)檢測標(biāo)志。接收緩沖器滿;發(fā)送緩沖器空;傳輸結(jié)束標(biāo)志。(14)校驗控制。發(fā)送校驗位;對接收數(shù)據(jù)進(jìn)行校驗。(15)四個錯誤檢測標(biāo)志。溢出錯誤;噪聲錯誤;幀錯誤;校驗錯誤。(16)10個帶標(biāo)志的中斷源。CTS改變;LIN斷開符檢測;發(fā)送數(shù)據(jù)寄存器空;發(fā)送完成;接收數(shù)據(jù)寄存器滿;檢測到總線為空閑;溢出錯誤;幀錯誤;噪聲錯誤;校驗錯誤。(17)多處理器通信。如果地址不匹配,則進(jìn)入靜默模式。(18)從靜默模式中喚醒。通過空閑總線檢測或地址標(biāo)志檢測。(19)兩種喚醒接收器的方式。地址位(MSB,第9位),總線空閑。8.2.3USART的功能STM32F407微控制器USART接口通過三個引腳與其他設(shè)備連接在一起,其內(nèi)部結(jié)構(gòu)如圖8-3所示。圖8-3USART結(jié)構(gòu)框圖(1)總線在發(fā)送或接收前應(yīng)處于空閑狀態(tài)。(2)一個起始位。(3)一個數(shù)據(jù)字(8或9位),最低有效位在前。(4)0.5,1.5,2個的停止位,由此表明數(shù)據(jù)幀的結(jié)束。(5)使用分?jǐn)?shù)波特率發(fā)生器-12位整數(shù)和4位小數(shù)的表示方法。(6)一個狀態(tài)寄存器(USART_SR)。(7)數(shù)據(jù)寄存器(USART_DR)。(8)一個波特率寄存器(USART_BRR),12位的整數(shù)和4位小數(shù)。(9)一個智能卡模式下的保護(hù)時間寄存器(USART_GTPR)。1.波特率控制波特率控制即圖8-3下部虛線框的部分。通過對USART時鐘的控制,可以控制USART的數(shù)據(jù)傳輸速度。通過改變USART外設(shè)時鐘源的分頻系數(shù)USARTDIV,可以設(shè)置USART的波特率。波特率決定了USART數(shù)據(jù)通信的速率,通過設(shè)置波特率寄存器(USART_BRR)來配置波特率。標(biāo)準(zhǔn)USART的波特率計算公式:波特率=fPCLK/(8x(2-OVER8)xUSARTDIV)式中,fpcLk是USART總線時鐘;OVER8是過采樣設(shè)置;USARTDIV是需要存儲在USART_BRR中的數(shù)據(jù)。一般根據(jù)需要的波特率計算USARTDIV,然后換算成存儲到USART_BRR的數(shù)據(jù)。2.收發(fā)控制收發(fā)控制即圖8-3的中間部分。該部分由若干個控制寄存器組成,如USART控制寄存器(controlregister)CR1、CR2、CR3和USART狀態(tài)寄存器(statusregister)SR等。通過向以上控制寄存器寫入各種參數(shù),控制USART數(shù)據(jù)的發(fā)送和接收。同時,通過讀取狀態(tài)寄存器,可以查詢USART當(dāng)前的狀態(tài)。USART狀態(tài)的查詢和控制可以通過庫函數(shù)來實現(xiàn),因此,無須深入了解這些寄存器的具體細(xì)節(jié)(如各個位代表的意義),而只需學(xué)會使用USART相關(guān)的庫函數(shù)即可。3.數(shù)據(jù)存儲轉(zhuǎn)移數(shù)據(jù)存儲轉(zhuǎn)移即圖8-3上部灰色的部分。它的核心是兩個移位寄存器:發(fā)送移位寄存器和接收移位寄存器。這兩個移位寄存器負(fù)責(zé)收發(fā)數(shù)據(jù)并做并串轉(zhuǎn)換。(1)USART數(shù)據(jù)發(fā)送過程當(dāng)USART發(fā)送數(shù)據(jù)時,內(nèi)核指令或DMA外設(shè)先將數(shù)據(jù)從內(nèi)存(變量)寫入發(fā)送數(shù)據(jù)寄存器TDR。然后,發(fā)送控制器適時地自動把數(shù)據(jù)從TDR加載到發(fā)送移位寄存器,將數(shù)據(jù)一位一位地通過Tx引腳發(fā)送出去。(2)USART數(shù)據(jù)接收過程USART數(shù)據(jù)接收是USART數(shù)據(jù)發(fā)送的逆過程。當(dāng)USART接收數(shù)據(jù)時,數(shù)據(jù)從Rx引腳一位一位地輸入到接收移位寄存器中。然后,接收控制器自動將接收移位寄存器的數(shù)據(jù)轉(zhuǎn)移到接收數(shù)據(jù)寄存器RDR中。最后,內(nèi)核指令或DMA將接收數(shù)據(jù)寄存器RDR的數(shù)據(jù)讀入內(nèi)存(變量)中。8.2.4USART的通信時序字長可以通過編程USART_CR1寄存器中的M位,選擇8或9位,如圖8-4所示。圖8-4中的LBCL,最后一位時鐘脈沖(Lastbitclockpulse),為控制寄存器2(USART_CR2)的位8。在同步模式下,該位用于控制是否在CK引腳上輸出最后發(fā)送的那個數(shù)據(jù)位(最高位)對應(yīng)的時鐘脈沖。0:最后一位數(shù)據(jù)的時鐘脈沖不從CK輸出;1:最后一位數(shù)據(jù)的時鐘脈沖會從CK輸出。(2)UART4和UART5上不存在這一位。

圖8-4USART通信時序8.2.5USART的中斷STM32F407系列微控制器的USART主要有以下各種中斷事件:(1)發(fā)送期間的中斷事件包括發(fā)送完成(TC)、清除發(fā)送(CTS)、發(fā)送數(shù)據(jù)寄存器空(TXE)。(2)接收期間:空閑總線檢測(IDLE)、溢出錯誤(ORE)、接收數(shù)據(jù)寄存器非空(RXNE)、校驗錯誤(PE)、LIN斷開檢測(LBD)、噪聲錯誤(NE,僅在多緩沖器通信)和幀錯誤(FE,僅在多緩沖器通信)。如果設(shè)置了對應(yīng)的使能控制位,這些事件就可以產(chǎn)生各自的中斷,如表8-1所示。中斷事件事件標(biāo)志使能位發(fā)送數(shù)據(jù)寄存器空TXETXEIECTS標(biāo)志CTSCTSIE發(fā)送完成TCTCIE接收數(shù)據(jù)就緒可讀RXNERXNEIE檢測到數(shù)據(jù)溢出OREOREIE檢測到空閑線路IDLEIDLEIE奇偶檢驗錯PEPEIE斷開標(biāo)志LBDLBDIE噪聲標(biāo)志、溢出錯誤和幀錯誤NE或ORT或FEEIE表8-1STM32F407系列微控制器USART的中斷事件及其使能標(biāo)志位8.2.6USART的相關(guān)寄存器現(xiàn)將STM32F407的USART相關(guān)寄存器名稱介紹如下,可以用半字(16位)或字(32位)的方式操作這些外設(shè)寄存器,由于采用庫函數(shù)方式編程,故不做進(jìn)一步的探討。(1)狀態(tài)寄存器(USART_SR)。(2)數(shù)據(jù)寄存器(USART_DR)。(3)波特比率寄存器(USART_BRR)。(4)控制寄存器1(USART_CR1)。(5)控制寄存器2(USART_CR2)。(6)控制寄存器3(USART_CR3)。(7)保護(hù)時間和預(yù)分頻寄存器(USART_GTPR)。8.3.1常用功能函數(shù)串口的驅(qū)動程序頭文件是stm32f4xx_hal_uart.h。串口操作的常用HAL函數(shù)如表8-2所示。8.3USART的HAL驅(qū)動程序分組函數(shù)名功能說明初始化和總體功能

HAL_UART_Init()串口初始化,設(shè)置串口通信參數(shù)HAL_UART_MspInit()串口初始化的MSP弱函數(shù),在HAL_UART_Init()中被調(diào)用。重新實現(xiàn)的這個函數(shù)一般用于串口引腳的GPIO初始化和中斷設(shè)置HAL_UART_GetState()獲取串口當(dāng)前狀態(tài)HAL_UART_GetError()返回串口錯誤代碼HAL_UART_Transmit()阻塞方式發(fā)送一個緩沖區(qū)的數(shù)據(jù),發(fā)送完成或超時后才返回HAL_UART_Receive()阻塞方式將數(shù)據(jù)接收到一個緩沖區(qū),接收完成或超時后才返回阻塞式傳輸HAL_UART_Transmit_IT()以中斷方式(非阻塞式)發(fā)送一個緩沖區(qū)的數(shù)據(jù)HAL_UART_Receive_IT()以中斷方式(非阻塞式)將指定長度的數(shù)據(jù)接收到緩沖區(qū)中斷方式傳輸HAL_UART_Transmit_DMA()以DMA方式發(fā)送一個緩沖區(qū)的數(shù)據(jù)HAL_UART_Receive_DMA()以DMA方式將指定長度的數(shù)據(jù)接收到緩沖區(qū)DMA方式傳輸HAL_UART_Transmit_DMA()以DMA方式發(fā)送一個緩沖區(qū)的數(shù)據(jù)HAL_UART_Receive_DMA()以DMA方式將指定長度的數(shù)據(jù)接收到緩沖區(qū)表8-2串口操作的常用HAL函數(shù)HAL_UART_DMAPause()暫停DMA傳輸過程HAL_UART_DMAResume()繼續(xù)先前暫停的DMA傳輸過程HAL_UART_DMAStop()停止DMA傳輸過程HAL_UART_Abort()終止以中斷方式或DMA方式啟動的傳輸過程,函數(shù)自身以阻塞方式運(yùn)行HAL_UART_AbortTransmit()終止以中斷方式或DMA方式啟動的數(shù)據(jù)發(fā)送過程,函數(shù)自身以阻塞方式運(yùn)行HAL_UART_AbortReceive()終止以中斷方式或DMA方式啟動的數(shù)據(jù)接收過程,函數(shù)自身以阻塞方式運(yùn)行HAL_UART_Abort_IT()終止以中斷方式或DMA方式啟動的傳輸過程,函數(shù)自身以非阻塞方式運(yùn)行HAL_UART_AbortTransmit_IT()終止以中斷方式或DMA方式啟動的數(shù)據(jù)發(fā)送過程,函數(shù)自身以非阻塞方式運(yùn)行HAL_UART_AbortReceive_IT()終止以中斷方式或DMA方式啟動的數(shù)據(jù)接收過程,函數(shù)自身以非阻塞方式運(yùn)行1. 串口初始化函數(shù)HAL_UART_Init()用于串口初始化,主要是設(shè)置串口通信參數(shù)。其原型定義如下:HAL_StatusTypeDef

HAL_UART_Init(UART_HandleTypeDef*huart)2. 阻塞式數(shù)據(jù)傳輸串口數(shù)據(jù)傳輸有兩種模式:阻塞模式和非阻塞模式。(1)阻塞模式(blockingmode)就是輪詢模式,例如,使用函數(shù)HAL_UART_Transmit()發(fā)送一個緩沖區(qū)的數(shù)據(jù)時,這個函數(shù)會一直執(zhí)行,直到數(shù)據(jù)傳輸完成或超時之后,函數(shù)才返回。(2)非阻塞模式(non-blockingmode)是使用中斷或DMA方式進(jìn)行數(shù)據(jù)傳輸,例如,使用函數(shù)HAL_UART_Transmit_IT()啟動一個緩沖區(qū)的數(shù)據(jù)傳輸后,該函數(shù)立刻返回。數(shù)據(jù)傳輸?shù)倪^程引發(fā)各種事件中斷,用戶在相應(yīng)的回調(diào)函數(shù)里進(jìn)行處理。以阻塞模式發(fā)送數(shù)據(jù)的函數(shù)是HAL_UART_Transmit(),其原型定義如下:HAL_StatusTypeDef

HAL_UART_Transmit(UART_HandleTypeDef*huart,uint8_t*pData,uint16_tSize,uint32_tTimeout)3. 非阻塞式數(shù)據(jù)傳輸以中斷或DMA方式啟動的數(shù)據(jù)傳輸是非阻塞式的。我們將在第12章介紹DMA方式,在本章只介紹中斷方式。以中斷方式發(fā)送數(shù)據(jù)的函數(shù)是HAL_UART_Transmit_IT(),其原型定義如下:HAL_StatuaTypeDet

HAL_UART_Transmit_IT(UART_HandleTypeDef*huart,uint8_t*pData,uint16_tSize)8.3.2常用的宏函數(shù)在HAL驅(qū)動程序中,每個外設(shè)都有一些以“_HAL”為前綴的宏函數(shù)。這些宏函數(shù)直接操作寄存器,主要是進(jìn)行啟用或禁用外設(shè)、開啟或禁止事件中斷、判斷和清除中斷標(biāo)志位等操作。串口操作常用的宏函數(shù)如表8-3所示。宏函數(shù)功能描述_HAL_UART_ENABLE(_HANDLE_)啟用某個串口,例如_HAL_UART_ENABLE(&huart1)_HAL_UART_DISABLE(_HANDLE_)禁用某個串口,例如_HAL_UART_DISABLE(&huartl)_HAL_UART_ENABLE_IT(_HANDLE,INTERRUPT)允許某個事件產(chǎn)生硬件中斷,例如_HAL_UART_ENABLE_IT(&huartl,UART_IT_IDLE)_HAL_UART_ENABLE_IT(_HANDLE,INTERRUPT)禁止某個事件產(chǎn)生硬件中斷,例如_HAL_UART_ENABLE_IT(&huartl,UART_IT_IDLE)_HAL_UART_GET_IT_SOURCE(_HANDLE,IT)檢查某個事件是否被允許產(chǎn)生硬件中斷_HAL_UART_GET_FLAG(HANDLE,FLAG_)檢查某個事件的中斷標(biāo)志位是否被置位_HAL_UART_CLEAR_FLAG(HANDLE,FLAG)清除某個事件的中斷標(biāo)志位表8-3串口操作常用的宏函數(shù)這些宏函數(shù)中的參數(shù)_HANDLE_是串口外設(shè)對象指針,參數(shù)_INTERRUPT_和_IT_都是中斷事件類型。一個串口只有一個中斷號,但是中斷事件類型較多,文件stm32f4xx_h(yuǎn)al_uart.h定義了這些中斷事件類型的宏,全部中斷事件類型定義如下:#defineUART_IT_PE((uint32_t)(UART_CR1_REG_INDEX<<28U|USART_CR1_PEIE))#defineUART_IT_TXE((uint32_t)(UART_CR1_REG_INDEX<<28U|USART_CR1_TXEIE))#defineUART_IT_TC((uint32_t)(UART_CR1_REG_INDEX<<28U|USART_CR1_TCIE))#defineUART_IT_RXNE((uint32_t)(UART_CR1_REG_INDEX<<28U|USART_CR1_RXNEIE))#defineUART_IT_IDLE((uint32_t)(UART_CR1_REG_INDEX<<28U|USART_CR1_IDLEIE))#defineUART_IT_LBD((uint32_t)(UART_CR2_REG_INDEX<<28U|USART_CR2_LBDIE))#defineUART_IT_CTS((uint32_t)(UART_CR3_REG_INDEX<<28U|USART_CR3_CTSIE))#defineUART_IT_ERR((uint32_t)(UART_CR3_REG_INDEX<<28U|USART_CR3_EIE))

8.3.3中斷事件與回調(diào)函數(shù)一個串口只有一個中斷號,也就是只有一個ISR,例如,USART1的全局中斷對應(yīng)的ISR是USART1_IRQHandler()。在STM32CubeMX自動生成代碼時,其ISR框架會在文件stm32f4xx_it.c中生成,代碼如下:voidUSART1_IRQHandler(void)//USART1中斷ISR{HAL_UART_IRQHandler(&huart1);//串口中斷通用處理函數(shù)}所有串口的ISR都是調(diào)用HAL_UART_IRQHandler()這個處理函數(shù),這個函數(shù)是中斷處理通用函數(shù)。這個函數(shù)會判斷產(chǎn)生中斷的事件類型、清除事件中斷標(biāo)志位、調(diào)用中斷事件對應(yīng)的回調(diào)函數(shù)。對函數(shù)HAL_UART_IRQHandler()進(jìn)行代碼跟蹤分析,整理出如表8-4所示的串口中斷事件類型與回調(diào)函數(shù)的對應(yīng)關(guān)系。注意,并不是所有中斷事件有對應(yīng)的回調(diào)函數(shù),例如,UART_IT_IDLE中斷事件就沒有對應(yīng)的回調(diào)函數(shù)。中斷事件類型宏定義中斷事件描述對應(yīng)的回調(diào)函數(shù)UARTIT_CTSCTS信號變化中斷無UARTIT_LBDLIN打斷檢測中斷無UART_IT_TXE發(fā)送數(shù)據(jù)寄存器非空中斷無UART_IT_TC傳輸完成中斷,用于發(fā)送完成HAL_UART_TxCpltCallback()UART_ITRXNE接收數(shù)據(jù)寄存器非空中斷HAL_UART_RxCpltCallback()UART_IT_IDLE線路空閑狀態(tài)中斷無UART_IT_PE奇偶校驗錯誤中斷HAL_UART_ErrorCallback()UARTIT_ERR發(fā)生幀錯誤、噪聲錯誤、溢出錯誤的中斷HAL_UART_ErrorCallback()表8-4串口中斷事件類型及其回調(diào)函數(shù)STM32通常具有3個以上的串行通信口(USART),可根據(jù)需要選擇其中一個。在串行通信應(yīng)用的實現(xiàn)中,難點(diǎn)在于正確配置、設(shè)置相應(yīng)的USART。與51單片機(jī)不同的是,除了要設(shè)置串行通信口的波特率、數(shù)據(jù)位數(shù)、停止位和奇偶校驗等參數(shù)外,還要正確配置USART涉及的GPIO和USART口本身的時鐘,即使能相應(yīng)的時鐘。否則,無法正常通信。8.4采用STM32Cube和HAL庫的USART串行通信應(yīng)用實例8.4.1STM32的USART的基本配置流程STM32F4的USART的功能有很多。最基本的功能就是發(fā)送和接收。其功能的實現(xiàn)需要串口工作方式配置、串口發(fā)送和串口接收三部分程序。本節(jié)只介紹基本配置,其他功能和技巧都是在基本配置的基礎(chǔ)上完成的,讀者可參考相關(guān)資料。HAL庫提供的串口相關(guān)操作函數(shù)。(1)串口參數(shù)初始化(波特率/停止位等),并使能串口。串口作為STM32的一個外設(shè),HAL庫為其配置了串口初始化函數(shù)。接下來看看串口初始化函數(shù)HAL_UART_Init相關(guān)知識,定義如下:HAL_StatusTypeDefHAL_UART_Init(UART_HandleTypeDef*huart);(2)使能串口和GPIO口時鐘。要使用串口,所以必須使能串口時鐘和使用到的GPIO口時鐘。例如要使用串口1,所以必須使能串口1時鐘和GPIOA時鐘(串口1使用的是PA9和PA10)。(3)GPIO口初始化設(shè)置(速度,上下拉等)以及復(fù)用映射配置。在HAL庫中GPIO口初始化參數(shù)設(shè)置和復(fù)用映射配置是在函數(shù)HAL_GPIO_Init中一次性完成的。這里只需要注意,要復(fù)用PA9和PA10為串口發(fā)送接收相關(guān)引腳,需要配置GPIO口為復(fù)用,同時復(fù)用映射到串口1。配置源碼如下:GPIO_Initure.Pin=GPIO_PIN_9;//PA9GPIO_Initure.Mode=GPIO_MODE_AF_PP;//復(fù)用推挽輸出GPIO

Initure.Pull=GPIO_PULLUP;//上拉GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速HAL_GPIO_Init(GPIOA,&GPIO_Initure);//初始化PA9GPIO_Initure.Pin=GPIO_PIN_10;//PA10GPIO

Initure.Mode=GPIO_MODE_AF_INPUT;//模式要設(shè)置為復(fù)用輸入模式!HAL_GPIO_Init(GPIOA,&GPIO_Initure);//初始化PA10(4)開啟串口相關(guān)中斷,配置串口中斷優(yōu)先級。HAL庫中定義了一個使能串口中斷的標(biāo)識符__HAL_UART_ENABLE_IT,可以把它當(dāng)一個函數(shù)來使用,具體定義請參考HAL庫文件stm32f4xx_hal_uart.h中該標(biāo)識符定義。例如要使能接收完成中斷,方法如下:HAL_UART_ENABLE_IT(huart,UART_IT_RXNE); //開啟接收完成中斷(5)編寫中斷服務(wù)函數(shù)。串口1中斷服務(wù)函數(shù)為:voidUSART1_IRQHandler(void);當(dāng)發(fā)生中斷的時候,程序就會執(zhí)行中斷服務(wù)函數(shù)。然后在中斷服務(wù)函數(shù)中編寫們相應(yīng)的邏輯代碼即可。(6)串口數(shù)據(jù)接收和發(fā)送。STM32F4的發(fā)送與接收是通過數(shù)據(jù)寄存器USART_DR來實現(xiàn)的,這是一個雙寄存器,包含了TDR和RDR。當(dāng)向該寄存器寫數(shù)據(jù)的時候,串口就會自動發(fā)送,當(dāng)收到數(shù)據(jù)的時候,也是存在該寄存器內(nèi)。HAL庫操作USART_DR寄存器發(fā)送數(shù)據(jù)的函數(shù)是:HAL_StatusTypeDefHAL_UART_Transmit(UART_HandleTypeDef*huart,uint8_t*pData,uint16_tSize,uint32_tTimeout);通過該函數(shù)向串口寄存器USART_DR寫入一個數(shù)據(jù)。HAL庫操作USART_DR寄存器讀取串口接收到的數(shù)據(jù)的函數(shù)是:HAL_StatusTypeDefHAL_UART_Receive(UART_HandleTypeDef*huart,uint8_t*pData,uint16_tSize,uint32_tTimeout);通過該函數(shù)可以讀取串口接收到的數(shù)據(jù)。8.4.2USART串行通信應(yīng)用的硬件設(shè)計為利用USART實現(xiàn)開發(fā)板與計算機(jī)通信,需要用到一個USB轉(zhuǎn)USART的IC電路,選擇CH340G芯片來實現(xiàn)這個功能。CH340G是一個USB總線的轉(zhuǎn)接芯片,實現(xiàn)USB轉(zhuǎn)USART、USB轉(zhuǎn)IrDA紅外或者USB轉(zhuǎn)打印機(jī)接口。使用其USB轉(zhuǎn)USART功能,具體電路設(shè)計如圖8-6所示。將CH340G的TXD引腳與USART1的RX引腳連接CH340G的RXD引腳與USART1的TX引腳連接。CH340G芯片集成在開發(fā)板上,其地線(GND)已與控制器的GND相連。在本實例中,編寫一個程序?qū)崿F(xiàn)STM32通過串口1和上位機(jī)對話,STM32在收到上位機(jī)發(fā)過來的字符串(以回車換行結(jié)束)后,會返回給上位機(jī)。同時每隔一定時間,通過串口1輸出一段信息到電腦。DS0閃爍,提示程序在運(yùn)行。圖8-6USB轉(zhuǎn)串行接口的硬件電路設(shè)計8.4.3 USART串行通信應(yīng)用的軟件設(shè)計STM32F407ZGT6有四個USART和兩個UART,其中USART1和USART6的時鐘來源于APB2總線時鐘,其最大頻率為84MHz,其他四個的時鐘來源于APB1總線時鐘,其最大頻率為42MHz。USART_InitTypeDef結(jié)構(gòu)體成員用于設(shè)置USART工作參數(shù),并由外設(shè)初始化配置函數(shù),比如MX_USART1_UART_Init()調(diào)用,這些設(shè)定參數(shù)將會設(shè)置外設(shè)相應(yīng)的寄存器,達(dá)到配置外設(shè)工作環(huán)境的目的。初始化結(jié)構(gòu)體定義在stm32f4xx_hal_usart.h文件中,初始化庫函數(shù)定義在stm32f4xx_hal_usart.c文件中,編程時可以結(jié)合這兩個文件內(nèi)注釋使用。USART_InitTypeDef結(jié)構(gòu)體如下。typedefstruct{uint32_tBaudRate;//波特率uint32_tWordLength;//字長uint32_tStopBits;//停止位uint32_tParity;//校驗位uint32_tMode;//UART模式uint32_tHwFlowCtl;//硬件流控制uint32_tOverSampling;//過采樣模式}USART_InitTypeDef;1.通過STM32CubeMX新建工程通過STM32CubeMX新建工程的步驟如下:(1)新建文件夾Demo目錄下新建文件夾USART,這是保存新建工程的文件夾。(2)新建STM32CubeMX工程在STM32CubeMX開發(fā)環(huán)境中新建工程。(3)選擇MCU或開發(fā)板CommercialPartNumber和MCUs/MPUsList選擇STM32F407ZGT6,選擇StartProject啟動工程。(4)保存STM32CubeMX工程使用STM32CubeMX菜單File→SaveProject,保存工程。(5)生成報告使用STM32CubeMX菜單File→GenerateReport生成當(dāng)前工程的報告文件。(6)配置MCU時鐘樹STM32CubeMXPinout&Configuration子頁面下,選擇SystemCore→RCC,HighSpeedClock(HSE)根據(jù)開發(fā)板實際情況,選擇Crystal/CeramicResonator(晶體/陶瓷晶振)。(7)配置MCU外設(shè)首先配置USART1,STM32CubeMXPinout&Configuration子頁面下選擇Connectivity→USART1,對USART1進(jìn)行設(shè)置。Mode選擇Asynchronous,HardwareFlowControl(RS232)選擇Disable,ParameterSettings具體配置如圖8-7所示。圖8-7USART1配置頁面NVIC配置頁面如圖8-8所示。圖8-8NVIC配置頁面CodeGeneration頁面Selectforinitsequenceordering欄勾選USART1globalinterrupt。NVICCodeGeneration配置頁面如圖8-9所示。

圖8-9NVICCodeGeneration配置頁面根據(jù)LED和USART1電路,整理出MCU連接的GPIO引腳的輸入/輸出配置,如表8-5所示。。在STM32CubeMX中配置完USART1后,會自動完成相關(guān)GPIO口的配置,不需用戶配置。USARTGPIO配置頁面如圖8-10所示。用戶標(biāo)簽引腳名稱引腳功能GPIO模式上拉或下拉端口速率LED0PF9GPIO_Output推挽輸出上拉高LED1PF10GPIO_Output推挽輸出上拉高-PA9USART1_TX復(fù)用推挽輸出-高-PA10USART1_RX復(fù)用輸入模式-高表8-5MCU引腳的配置圖8-10USARTGPIO配置頁面STM32CubeMXPinout&Configuration子頁面下選擇SystemCore→GPIO,對使用的GPIO口進(jìn)行設(shè)置。LED輸出端口:LED0(PF9)和LED1(PF10),配置完成后的GPIO端口頁面如圖8-11所示。。圖8-11配置完成后的GPIO端口頁面(8)配置工程STM32CubeMXProjectManager子頁面Project欄下Toolchain/IDE選擇MDK-ARM,MinVersion選擇V5,可生成KeilMDK工程;選擇STM32CubeIDE,可生成CubeIDE工程。(9)生成C代碼工程STM32CubeMX主頁面,單擊GENERATECODE按鈕生成C代碼工程。分別生成MDK-ARM和CubeIDE工程。2.通過STM32CubeIDE實現(xiàn)工程通過STM32CubeIDE實現(xiàn)工程的步驟如下:(1)打開工程打開USART\STM32CubeIDE文件夾下的工程文件。(2)編譯STM32CubeMX自動生成的STM32CubeIDE工程在STM32CubeIDE開發(fā)環(huán)境中通過菜單Project→BuildAll或工具欄BuildAll按鈕編譯工程。(3)STM32CubeMX自動生成的STM32CubeIDE工程main.c文件中函數(shù)main()依次調(diào)用了HAL_Init()函數(shù)用于復(fù)位所有外設(shè),初始化Flash接口和Systick定時器。SystemClock_Config()函數(shù)用于配置各種時鐘信號頻率。MX_GPIO_Init()函數(shù)初始化GPIO引腳。(4)新建用戶文件在TIMER\Core\Src下新建led.c,在TIMER\Core\Inc下新建led.h。將led.c添加到工程Application/User/Core文件夾下。(5)編寫用戶代碼led.h和led.c文件實現(xiàn)LED操作的宏定義和LED初始化。usart.c文件MX_USART1_UART_Init()函數(shù)開啟USART1接收中斷。(6)重新編譯工程重新編譯修改后的工程。(7)下載工程連接好仿真下載器,開發(fā)板上電。單擊菜單欄Run→Run或工具欄,首次運(yùn)行時會彈出配置頁面,選擇調(diào)試探頭為ST-LINK,接口為JTAG,其余默認(rèn),單擊OK確認(rèn)。工程下載完成后,連接串口,打開串口調(diào)試助手,在串口調(diào)試助手發(fā)送區(qū)域輸入任意字符,單擊發(fā)送按鈕,馬上在串口調(diào)試助手接收區(qū)即可看到相同的字符。第9章STM32SPI控制器本章講述了STM32SPI控制器,包括STM32的SPI通信原理、STM32F407SPI串行總線的工作原理、SPI的HAL驅(qū)動程序、采用STM32Cube和HAL庫的SPI應(yīng)用實例。9.1STM32的SPI通信原理實際生產(chǎn)生活當(dāng)中,有些系統(tǒng)的功能無法完全通過STM32的片上外設(shè)來實現(xiàn)。例如,16位及以上的A/D轉(zhuǎn)換器、溫/濕度傳感器、大容量EEPROM或Flash、大功率電機(jī)驅(qū)動芯片、無線通信控制芯片等。此時,只能通過擴(kuò)展特定功能的芯片來實現(xiàn)這些功能。另外,有的系統(tǒng)需要兩個或者兩個以上的主控器(STM32或FPGA),而這些主控器之間也需要通過適當(dāng)?shù)男酒g通信方式來實現(xiàn)通信。常見的系統(tǒng)內(nèi)通信方式有并行和串行兩種。并行方式指同一個時刻,在嵌入式處理器和外圍芯片之間傳遞數(shù)據(jù)有多位;串行方式則是指每個時刻傳遞的數(shù)據(jù)只有一位,需要通過多次傳遞才能完成一字節(jié)的傳輸。9.1.1SPI串行總線概述串行外設(shè)接口(SerialPeripheralInterface,SPI)是由美國摩托羅拉(Motorola)公司提出的一種高速全雙工串行同步通信接口,首先出現(xiàn)在M68HC系列處理器中,由于其簡單方便,成本低廉,傳輸速度快,因此被其他半導(dǎo)體廠商廣泛使用,從而成為事實上的標(biāo)準(zhǔn)。SPI與USART相比,其數(shù)據(jù)傳輸速度要快得多,因此它被廣泛地應(yīng)用于微控制器與ADC、LCD等設(shè)備的通信,尤其是高速通信的場合。微控制器還可以通過SPI組成一個小型同步網(wǎng)絡(luò)進(jìn)行高速數(shù)據(jù)交換,完成較復(fù)雜的工作。作為全雙工同步串行通信接口,SPI采用主/從模式(master/slave),支持一個或多個從設(shè)備,能夠?qū)崿F(xiàn)主設(shè)備和從設(shè)備之間的高速數(shù)據(jù)通信。SPI具有硬件簡單、成本低廉、易于使用、傳輸數(shù)據(jù)速度快等優(yōu)點(diǎn),使用于成本敏感或者高速通信的場合。SPI也存在無法檢查糾錯、不具備尋址能力和接收方?jīng)]有應(yīng)答信號等缺點(diǎn),不適合復(fù)雜或者可靠性要求較高的場合。SPI是同步全雙工串行通信接口。SPI在物理層體現(xiàn)為4條信號線,分別是SCK、MOSI、MISO和SS。(1)SCK(SerialClock),即時鐘線,由主設(shè)備產(chǎn)生。不同的設(shè)備支持的時鐘頻率不同。(2)MOSI(MasterOutputSlaveInput),即主設(shè)備數(shù)據(jù)輸出/從設(shè)備數(shù)據(jù)輸入線。(3)MISO(MasterInputSlaveOutput),即主設(shè)備數(shù)據(jù)輸入/從設(shè)備數(shù)據(jù)輸出線。。(4)SS(SlaveSelect),有時候也叫CS(ChipSelect),SPI從設(shè)備選擇信號線,當(dāng)有多個SPI從設(shè)備與SPI主設(shè)備相連(即一主多從)時,SS用來選擇激活指定的從設(shè)備,由SPI主設(shè)備(通常是微控制器)驅(qū)動,低電平有效。當(dāng)只有一個SPI從設(shè)備與SPI主設(shè)備相連(即一主一從)時,SS并不是必需的。因此,SPI也被稱為三線同步通信接口。除了SCK、MOSI、MISO和SS這4條信號線外,SPI接口還包含一個串行移位寄存器,如圖9-1所示。圖9-1SPI接口組成9.1.2SPI串行總線互連方式SPI互連主要有一主一從和一主多從兩種互連方式。1. 一主一從在一主一從的SPI互連方式下,只有一個SPI主設(shè)備和一個SPI從設(shè)備進(jìn)行通信。這種情況下,只需要分別將主設(shè)備的SCK、MOSI、MISO和從設(shè)備的SCK、MOSI、MISO直接相連,并將主設(shè)備的SS置為高電平,從設(shè)備的SS接地(置為低電平,片選有效,選中該從設(shè)備)即可,如圖9-2所示。圖9-2一主一從的SPI互連2. 一主多從在一主多從的SPI互連方式下,一個SPI主設(shè)備可以和多個SPI從設(shè)備相互通信。這種情況下,所有的SPI設(shè)備(包括主設(shè)備和從設(shè)備)共享時鐘線和數(shù)據(jù)線,即SCK、MOSI、MISO這3條線,并在主設(shè)備端使用多個GPIO引腳來選擇不同的SPI從設(shè)備,如圖9-3所示。圖9-3一主多從的SPI互連串行外設(shè)接口(SPI)允許芯片與外部設(shè)備以半/全雙工、同步、串行方式通信。此接口可以被配置成主模式,并為外部從設(shè)備提供通信時鐘(SCK),接口還能以多主的配置方式工作。它可用于多種用途,包括使用一條雙向數(shù)據(jù)線的雙線單工同步傳輸,還可使用CRC校驗的可靠通信。9.2STM32F4SPI串行總線的工作原理9.2.1SPI串行總線的特征STM32F407微控制器的小容量產(chǎn)品有1個SPI接口,中等容量產(chǎn)品有2個SPI,大容量產(chǎn)品則有3個SPI。STM32F407微控制器SPI主要具有以下特征:(1)3線全雙工同步傳輸。(2)帶或不帶第三根雙向數(shù)據(jù)線的雙線單工同步傳輸。(3)8或16位傳輸幀格式選擇。(4)主或從操作。(5)支持多主模式。(6)8個主模式波特率預(yù)分頻系數(shù)(最大為fPCLK/2)。(7)從模式頻率(最大為fPCLK/2)。(8)主模式和從模式的快速通信。(9)主模式和從模式下均可以由軟件或硬件進(jìn)行NSS管理:主/從操作模式的動態(tài)改變。(10)可編程的時鐘極性和相位。(11)可編程的數(shù)據(jù)順序,MSB在前或LSB在前。(12)可觸發(fā)中斷的專用發(fā)送和接收標(biāo)志。(13)SPI總線忙狀態(tài)標(biāo)志。(14)支持可靠通信的硬件CRC。在發(fā)送模式下,CRC值可以被作為最后一個字節(jié)發(fā)送;在全雙工模式下,對接收到的最后一個字節(jié)自動進(jìn)行CRC校驗。(15)可觸發(fā)中斷的主模式故障、過載以及CRC錯誤標(biāo)志。(16)支持DMA功能的1字節(jié)發(fā)送和接收緩沖器,產(chǎn)生發(fā)送和接受請求。9.2.2SPI串行總線的內(nèi)部結(jié)構(gòu)STM32F407微控制器SPI主要由波特率發(fā)生器、收發(fā)控制和數(shù)據(jù)存儲轉(zhuǎn)移三部分組成,內(nèi)部結(jié)構(gòu)如圖9-4所示。波特率發(fā)生器用來產(chǎn)生SPI的SCK時鐘信號,收發(fā)控制主要由控制寄存器組成,數(shù)據(jù)存儲轉(zhuǎn)移主要由移位寄存器、接收緩沖區(qū)和發(fā)送緩沖區(qū)等構(gòu)成。圖9-4STM32F407微控制器SPI內(nèi)部結(jié)構(gòu)圖STM32系列微控制器SPI的功能主要由波特率控制、收發(fā)控制和數(shù)據(jù)存儲轉(zhuǎn)移3部分構(gòu)成。1. 波特率控制波特率發(fā)生器可產(chǎn)生SPI的SCK時鐘信號。波特率預(yù)分頻系數(shù)為2、4、8、16、32、64、128或256。通過設(shè)置波特率控制位(BR)可以控制SCK的輸出頻率,從而控制SPI的傳輸速率。2. 收發(fā)控制收發(fā)控制由若干個控制寄存器組成,如SPI控制寄存器SPI_CR1、SPI_CR2和SPI狀態(tài)寄存器SPI_SR等。3. 數(shù)據(jù)存儲轉(zhuǎn)移數(shù)據(jù)存儲轉(zhuǎn)移如圖9-4的左上部分所示,主要由移位寄存器、接收緩沖區(qū)和發(fā)送緩沖區(qū)等構(gòu)成。9.2.3SPI串行總線時鐘信號的相位和極性SPI_CR寄存器的CPOL和CPHA位,能夠組合成四種可能的時序關(guān)系。CPOL(時鐘極性)位控制在沒有數(shù)據(jù)傳輸時時鐘的空閑狀態(tài)電平,此位對主模式和從模式下的設(shè)備都有效。如果CPOL被清0,SCK引腳在空閑狀態(tài)保持低電平;如果CPOL被置1,SCK引腳在空閑狀態(tài)保持高電平。如圖9-5所示,如果CPHA(時鐘相位)位被清0,數(shù)據(jù)在SCK時鐘的奇數(shù)(第1、3、5個···)跳變沿(CPOL位為0時就是上升沿,CPOL位為1時就是下降沿)進(jìn)行數(shù)據(jù)位的存取,數(shù)據(jù)在SCK時鐘偶數(shù)(第2、4、6個···)跳變沿(CPOL位為0時就是下降沿,CPOL位為1時就是上升沿)準(zhǔn)備就緒。圖9-5CPHA=0時SPI時序圖如圖9-6所示,如果CPHA(時鐘相位)位被置1,數(shù)據(jù)在SCK時鐘的偶數(shù)(第2、4、6個···)跳變沿(CPOL位為0時就是下降沿,CPOL位為1時就是上升沿)進(jìn)行數(shù)據(jù)位的存取,數(shù)據(jù)在SCK時鐘奇數(shù)(第1、3、5個···)跳變沿(CPOL位為0時就是上升沿,CPOL位為1時就是下降沿)準(zhǔn)備就緒。圖9-6CPHA=1時SPI時序圖9.2.4STM32的SPI接口配置1.配置SPI為從模式在從模式下,SCK引腳用于接收從主設(shè)備來的串行時鐘。SPI_CR1寄存器中BR[2:0]的設(shè)置不影響數(shù)據(jù)傳輸速率。SPI從模式的配置步驟如下,(1)設(shè)置DFF位以定義數(shù)據(jù)幀格式為8位或16位。(2)選擇CPOL和CPHA位來定義數(shù)據(jù)傳輸和串行時鐘之間的相位關(guān)系。為保證正確的數(shù)據(jù)傳輸,從設(shè)備和主設(shè)備的CPOL和CPHA位必須配置成相同的方式。(3)幀格式(SPI_CR1寄存器中的LSBFIRST位定義的“最高位在前”還是“最低位在前”)必須與主設(shè)備相同。(4)在NSS引腳管理硬件模式下,在數(shù)據(jù)幀傳輸過程中,NSS引腳必須為低電平。在NSS軟件模式下,設(shè)置SPI_CR1寄存器中的SSM位并清除SSI位。(5)在SPI_CR1寄存器中,清除MSTR位,設(shè)置SPE位,使相應(yīng)引腳工作于SPI模式下。2. 配置SPI為主模式在主模式時,MOSI引腳是數(shù)據(jù)輸出,而MISO引腳是數(shù)據(jù)輸入,在SCK引腳產(chǎn)生串行時鐘。SPI主模式的配置步驟如下:(1)通過SPI_CR1寄存器的BR[2:0]位定義串行時鐘波特率。(2)選擇CPOL和CPHA位,定義數(shù)據(jù)傳輸和串行時鐘間的相位關(guān)系。(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位。(6)必須設(shè)置MSTR位和SPE位(只當(dāng)NSS引腳被連到高電平,這些位才能保持置位)。3. 配置SPI為單工通信SPI模塊能夠以兩種配置工作于單工方式:1條時鐘線和1條雙向數(shù)據(jù)線;1條時鐘線和1條數(shù)據(jù)線(只接收或只發(fā)送)。(1)1條時鐘線和1條雙向單向數(shù)據(jù)線(BIDIMODE=1)通過設(shè)置SPI_CR1寄存器中的BIDIMODE位啟用此模式。在這個模式下,SCK引腳作為時鐘,主設(shè)備使用MOSI引腳而從設(shè)備使用MISO引腳作為數(shù)據(jù)通信。傳輸?shù)姆较蛴蒘PI_CR1寄存器里的BIDIOE控制,當(dāng)這個位是1的時候,數(shù)據(jù)線是輸出,否則是輸入。(2)1條時鐘和1條單向數(shù)據(jù)線(BIDIDIMODE=0)在這個模式下,SPI模塊可以或者作為只發(fā)送,或者作為只接收。9.2.5STM32的SPI接口數(shù)據(jù)發(fā)送與接收過程1.接收與發(fā)送緩沖器接收時,接收到的數(shù)據(jù)被存放在接收緩沖器中;發(fā)送時,在數(shù)據(jù)被發(fā)送之前,首先被存放在發(fā)送緩沖器中。讀SPIDR寄存器將返回接收緩沖器的內(nèi)容;寫入SPI_DR寄存器的數(shù)據(jù)將被寫入發(fā)送緩沖器中。2.主模式下的數(shù)據(jù)傳輸(1)全雙工模式(BIDIMODEE=0并且RXONLY=0)(2)單向的只接收模式(BIDIMODE并且RRXONLY=1)(3)雙向模式,發(fā)送時(BIDIMODE并且BIIDIOE=1)(4)雙向模式,接收時(BIDIMODE=1并且BIDIOE=0)3.從模式下的數(shù)據(jù)傳輸(1)全雙工模式(BIDIMODE并且RXONLY=0)(2)單向的只接收模式(BIDIMODE=0并且RXONLY=1)(3)雙向模式發(fā)送時(BIDIMODE=1并且BIDIOE=1)(4)雙向模式接收時(BIDIMODE=并且BIDIOE=0)4.處理數(shù)據(jù)的發(fā)送與接收當(dāng)數(shù)據(jù)從發(fā)送緩沖器傳送到移位寄存器時,TXE標(biāo)志置位(發(fā)送緩沖器空),表示發(fā)送緩沖器可以接收下一個數(shù)據(jù);如果在SPI_CR2寄存器中設(shè)置了TXEIE位,則此時會產(chǎn)生中斷;寫入數(shù)據(jù)到SPI_DR寄存器即可清除TXE位。9.3.1SPI寄存器操作的宏函數(shù)SPI的驅(qū)動程序頭文件是stm32f4xx_hal_spi.h。SPI寄存器操作的宏函數(shù)如表9-1所示。宏函數(shù)中的參數(shù)_HANDLE是具體某個SPI接口的對象指針,參數(shù)_INTERRUPT是SPI的中斷事件類型,參數(shù)_FLAG_是事件中斷標(biāo)志。9.3SPI的HAL驅(qū)動程序宏函數(shù)功能描述HAL_SPI_DISABLE(_HANDLE_)禁用某個SPI接口HAL_SPI_ENABLE(_HANDLE_)啟用某個SPI接口_HAL_SPI_DISABLE_IT(_HANDLE_,_INTERRUPT_)禁止某個中斷事件源,不允許事件產(chǎn)生硬件中斷_HAL_SPI_ENABLE_IT(HANDLE_,_INTERRUPT_)開啟某個中斷事件源,允許事件產(chǎn)生硬件中斷_HAL_SPI_GET_IT_SOURCE(_HANDLE_,INTERRUPT_)檢查某個中斷事件源是否被允許產(chǎn)生硬件中斷_HAL_SPI_GET_FLAG(_HANDLE_,_FLAG_)獲取某個事件的中斷標(biāo)志,檢查事件是否發(fā)生_HAL_SPI_CLEAR_CRCERRFLAG(_HANDLE_)清除CRC校驗錯誤中斷標(biāo)志_HAL_SPI_CLEAR_FREFLAG(_HANDLE_)清除TI幀格式錯誤中斷標(biāo)志_HAL_SPI_CLEAR_MODFFLAG(_HANDLE_)清除主模式故障中斷標(biāo)志_HAL_SPI_CLEAR_OVRFLAG(_HANDLE_)清除溢出錯誤中斷標(biāo)志表9-1SPI寄存器操作的宏函數(shù)STM32CubeMX自動生成的文件spi.c會定義表示具體SPI接口的外設(shè)對象變量。例如,使用SPI1時,會定義如下的外設(shè)對象變量hspil,宏函數(shù)中的參數(shù)_HANDLE_就可以使用&hspil。SPI_HandleTypeDefhspil;//表示SPI1的外設(shè)對象變量在SPI的HAL驅(qū)動程序中,定義了6個表示事件中斷標(biāo)志位的宏,可作為宏函數(shù)中參數(shù)FLAG_的取值;定義了3個表示中斷事件類型的宏,可作為宏函數(shù)中參數(shù)_INTERRUPT的取值。這些宏定義符號如表9-2所示。中斷事件SPI狀態(tài)寄存器SPI_SR中的斷標(biāo)志位表示事件中斷標(biāo)志位的宏SPI控制寄存器SPI_CR2中的中斷事件使能控制位表示中斷事件使能位的宏(用于表示中斷事件類型)發(fā)送緩沖區(qū)為空TXESPI_FLAG_TXETXEIESPI_IT_TXE接收緩沖區(qū)非空RXNESPI_FLAG_RXNEEXNEIESPI_IT_RXNE主模式故障MODFSPI_FLAG_MODFERRIESPI_IT_ERR溢出錯誤OVRSPI_FLAG_OVRCRC校驗錯誤CRCERRSPI_FLAG_CRCERRTI幀格式錯誤FRESPI_FLAG_FRE表9-2SPI的中斷事件和宏定義9.3.2SPI初始化和阻塞式數(shù)據(jù)傳輸SPI接口初始化、狀態(tài)查詢和阻塞式數(shù)據(jù)傳輸?shù)暮瘮?shù)列表如表9-3所示。函數(shù)名功能描述HAL_SPI_Init()SPI初始化,配置SPI接口參數(shù)HAL_SPI_MspInit()SPI的MSP初始化函數(shù),重新實現(xiàn)時一般用于SPI接口引腳GPIO初始化和中斷設(shè)置HAL_SPI_GetState()返回SPI接口當(dāng)前狀態(tài),返回值是枚舉類型HAL_SPI_StateTypeDefHAL_SPI_GetError()返回SPI接口最后的錯誤碼,錯誤碼有一組宏定義HAL_SPI_Transmit()阻塞式發(fā)送一個緩沖區(qū)的數(shù)據(jù)HAL_SPI_Receive()阻塞式接收指定長度的數(shù)據(jù)保存到緩沖區(qū)HAL_SPI_TransmitReceive()阻塞式同時發(fā)送和接收一定長度的數(shù)據(jù)表9-3SPI初始化和阻塞式數(shù)據(jù)傳輸相關(guān)函數(shù)1. SPI接口初始化函數(shù)HAL_SPI_Init()用于具體某個SPI接口的初始化,其原型定義如下:HAL_StatusTypeDef

HAL_SPI_Init(SPI_HandleTypeDef*hspi)2. 阻塞式數(shù)據(jù)發(fā)送和接收SPI是一種主/從通信方式,通信完全由SPI主機(jī)控制,因為SPI主機(jī)控制了時鐘信號SCK。函數(shù)HAL_SPI_Transmit()用于發(fā)送數(shù)據(jù),其原型定義如下:HAL_StatusTypeDef

HAL_SPI_Transmit(SPI_HandleTypeDef*hspi,uint8_t*pData,uint16_tsize,uint32_tTimeout);

3. 阻塞式同時發(fā)送與接收數(shù)據(jù)雖然SPI通信一般采用應(yīng)答式,MISO和MOSI兩根線不同時傳輸有效數(shù)據(jù)。在原理上,它們是可以在SCK時鐘信號作用下同時傳輸有效數(shù)據(jù)的。函數(shù)HAL_SPI_TransmitReceive()就實現(xiàn)了接收和發(fā)送同時操作的功能,其原型定義如下:HAL_StatusTypeDef

HAL_SPI_TransmitReceive(SPI_HandleTypeDef*hspi,uint8_t*pTxData,uint8_t*pRxData,uint16_tSize,uint32_tTimeout)9.3.3SPI中斷方式數(shù)據(jù)傳輸SPI接口能以中斷方式傳輸數(shù)據(jù),是非阻塞式數(shù)據(jù)傳輸。中斷方式數(shù)據(jù)傳輸?shù)南嚓P(guān)函數(shù)、產(chǎn)生的中斷事件類型、對應(yīng)的回調(diào)函數(shù)等如表9-4所示。中斷事件類型用中斷事件使能控制位的宏定義表示。圖1-3帶操作系統(tǒng)的嵌入式軟件的體系結(jié)構(gòu)構(gòu)函數(shù)名函數(shù)功能產(chǎn)生的中斷事件類型對應(yīng)的回調(diào)函數(shù)HAL_SPI_Transmit_IT()中斷方式發(fā)送一個緩沖區(qū)的數(shù)據(jù)SPI_IT_TXEHAL_SPI_TxCpltCallback()HAL_SPI_Receive_IT()中斷方式接收指定長度的數(shù)據(jù)保存到緩沖區(qū)SPI_IT_RXNEHAL_SPI_RxCpltCallback()HAL_SPI_TransmitReceive_IT()中斷方式發(fā)送和接收一定長度的數(shù)據(jù)SPI_IT_TXE和SPI_IT_RXNEHAL_SPI_TxRxCpltCallback()前3個DMA方式傳輸函數(shù)前3個中斷模式傳輸函數(shù)都可能產(chǎn)生SPI_IT_ERR中斷事件SPI_IT_ERRHAL_SPI_ErrorCallback()HAL_SPI_IRQHandler()SPI中斷ISR里調(diào)用的通用處理函數(shù)——HAL_SPI_Abort()取消非阻塞式數(shù)據(jù)傳輸,本函數(shù)以阻塞模式運(yùn)行——HAL_SPI_Abort_IT()取消非阻塞式數(shù)據(jù)傳輸,本函數(shù)以中斷模式運(yùn)行—HAL_SPI_AbortCpltCallback()表9-4SPI中斷方式數(shù)據(jù)傳輸相關(guān)函數(shù)函數(shù)HAL_SPI_Transmit_IT()用于發(fā)送一個緩沖區(qū)的數(shù)據(jù),發(fā)送完成后,會產(chǎn)生發(fā)送完成中斷事件(SPI_IT_TXE),對應(yīng)的回調(diào)函數(shù)是HAL_SPI_TxCpltCallback()。函數(shù)HAL_SPI_Receive_IT()用于接收指定長度的數(shù)據(jù)保存到緩沖區(qū),接收完成后,會產(chǎn)生接收完成中斷事件(SPI_IT_RXNE),對應(yīng)的回調(diào)函數(shù)是HAL_SPI_RxCpltCallback()。函數(shù)HAL_SPI_TransmitReceive_IT()是發(fā)送和接收同時進(jìn)行,由它啟動的數(shù)據(jù)傳輸會產(chǎn)生SPI_IT_TXE和SPI_IT_RXNE中斷事件,但是有專門的回調(diào)函數(shù)HAL_SPI_TxRxCpltCallback()。上述3個函數(shù)的原型定義如下:HAL_StatusTypeDefHAL_SPI_Transmit_IT(SPI_HandleTypeDef*hspi,uint8_t*pData,uint16_tSize);HAL_StatusTypeDefHAL_SPI_Receive_IT(SPI_HandleTypeDef*hspi,uint8_t*pData,uint16_tSize):HALStatusTypeDefHALSPITransmitReceive_IT(SPI_HandleTypeDef*hapi,uint8_t*pIxData,uint8_t*pRxData,uint16_tSize);9.3.4SPI的DMA方式數(shù)據(jù)傳輸SPI的發(fā)送和接收有各自的DMA請求,能以DMA方式進(jìn)行數(shù)據(jù)發(fā)送和接收。DMA方式傳輸時觸發(fā)DMA流的中斷事件,主要是DMA傳輸完成中斷事件。SPI的DMA方式數(shù)據(jù)傳輸?shù)南嚓P(guān)函數(shù)如表9-5所示。DMA方式功能函數(shù)函數(shù)功能DMA流中斷事件對應(yīng)的回調(diào)函數(shù)HAL_SPI_Transmit_DMA()DMA方式發(fā)送數(shù)據(jù)DMA傳輸完成HAL_SPI_TxCpltCallback()DMA傳輸半完成HAL_SPI_TxHalfCpltCallback()HAL_SPI_Receive_DMA()DMA方式接收數(shù)據(jù)DMA傳輸完成HAL_SPI_TxCpltCallback()DMA傳輸半完成HAL_SPI_TxHalfCpltCallback()HAL_SPI_TransmitReceive_DMA()DMA方式發(fā)送/接收數(shù)據(jù)DMA傳輸完成HAL_SPI_TxRxCpltCallback()DMA傳輸半完成HAL_SPI_TxRxHalfCpltCallback()前3個DMA方式傳輸函數(shù)DMA傳輸錯誤中斷事件DMA傳輸錯誤HAL_SPI_ErrorCallback()HAL_SPI_DMAPause()暫停DMA傳輸——HAL_SPI_DMAResume()繼續(xù)DMA傳輸——HAL_SPI_DMAStop()停止DMA傳輸——表9-5SPI的DMA方式數(shù)據(jù)傳輸?shù)南嚓P(guān)函數(shù)啟動DMA方式發(fā)送和接收數(shù)據(jù)的兩個函數(shù)的原型分別定義如下:HAL_StatusTypeDef

HAL_SPI_Transmit_DMA(SPI_HandleTypeDef*hspi,uint8_t*pData,uint16_tSize);HAL_StatusTypeDef

HAL_SPI_Receive_DMA(SPI_HandleTypeDef*hspi,uint8_t*pData,uint16_tSize);Flash存儲器又稱閃存,它與EEPROM都是掉電后數(shù)據(jù)不丟失的存儲器,但Flash存儲器容量普遍大于EEPROM,現(xiàn)在基本取代了它的地位。我們生活中常用的U盤、SD卡、SSD固態(tài)硬盤以及STM32芯片內(nèi)部用于存儲程序的設(shè)備,都是Flash類型的存儲器。本節(jié)以一種使用SPI通信的串行Flash存儲芯片W25Q128的讀寫為例,講述STM32的SPI使用方法。實例中STM32的SPI外設(shè)采用主模式,通過查詢事件的方式來確保正常通信。9.4采用STM32Cube和HAL庫的SPI應(yīng)用實例9.4.1STM32的SPI配置流程使用STM32的SPI2的主模式,下面講述SPI2部分的設(shè)置步驟。SPI相關(guān)的庫函數(shù)和定義分布在文件stm32f4xx_hal_spi.c以及頭文件stm32f4xx_hal_spi.h中。STM32的主模式配置步驟如下:(1)配置相關(guān)引腳的復(fù)用功能,使能SPI2時鐘。如果要用SPI2,第一步就要使能SPI2的時鐘,SPI2的時鐘通過APB1ENR的第14位來設(shè)置。其次要設(shè)置SPI2的相關(guān)引腳為復(fù)用輸出,這樣才會連接到SPI2上否則這些IO口還是默認(rèn)的狀態(tài),也就是標(biāo)準(zhǔn)輸入輸出口。這里使用的是PB13、PB14、PB15這3個(SCK、MISO、MOSI,CS使用軟件管理方式),所以設(shè)置這三個為復(fù)用功能IO。使能SPI2時鐘的方法為:__HAL_RCC_SPI2_CLK_ENABLE(); //使能SPI2時鐘復(fù)用PB13、PB14和PB15為SPI2引腳通過HAL_GPIO_Init函數(shù)實現(xiàn),代碼如下:GPIO_Initure.Pin=GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;GPIO_Initure.Mode=GPIO_MODE_AF_PP; //復(fù)用推挽輸出GPIO_Initure.Pull=GPIO_PULLUP; //上拉GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH; //快速(2)設(shè)置SPI2工作模式。 這一步全部是通過SPI2_CR1來設(shè)置,設(shè)置SPI2為主機(jī)模式,設(shè)置數(shù)據(jù)格式為8位,然后通過CPOL和CPHA位來設(shè)置SCK時鐘極性及采樣方式。并設(shè)置SPI2的時鐘頻率(最大18Mhz),以及數(shù)據(jù)的格式(MSB在前還是LSB在前)。在HAL庫中初始化SPI的函數(shù)為:HAL_StatusTypeDefHAL_SPI_Init(SPI_HandleTypeDef*hspi);(3)使能SPI2。這一步通過SPI2_CR1的bit6來設(shè)置,以啟動SPI2,在啟動之后,就可以開始SPI通信了。庫函數(shù)使能SPI1的方法為:HAL_SPI_ENABLE(&SPI2_Handler);//使能SPI2(4)SPI傳輸數(shù)據(jù)。通信接口當(dāng)然需要有發(fā)送數(shù)據(jù)和接受數(shù)據(jù)的函數(shù),HAL庫提供的發(fā)送數(shù)據(jù)函數(shù)原型為:HAL_StatusTypeDefHAL_SPI_Transmit(SPI_HandleTypeDef*hspi,uint8_t*pData,uint16_tSize,uint32_tTimeout);這個函數(shù)很好理解,往SPIx數(shù)據(jù)寄存器寫入數(shù)據(jù)Data,從而實現(xiàn)發(fā)送。(5)設(shè)置SPI傳輸速度。SPI初始化結(jié)構(gòu)體SPI_InitTypeDef有一個成員變量是BaudRatePrescaler,該成員變量用來設(shè)置SPI的預(yù)分頻系數(shù),從而決定了SPI的傳輸速度。9.4.2SPI與Flash存儲器接口的硬件設(shè)計W25Q128SPI串行Flash硬件連接圖如圖9-7所示。圖9-7W25Q128SPI串行Flash接口電路圖本開發(fā)板中的Flash芯

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論