STM32F4學(xué)習(xí)筆記7——USART Part2
硬件流控制
使用 nCTS 輸入和 nRTS 輸出可以控制 2 個(gè)器件間的串行數(shù)據(jù)流。如圖顯示了在這種模式 下如何連接 2 個(gè)器件:
分別向 USART_CR3 寄存器中的 RTSE 位和 CTSE 位寫入 1,可以分別使能 RTS 和 CTS 流 控制。
RTS 流控制
如果使能 RTS 流控制 (RTSE=1),只要 USART 接收器準(zhǔn)備好接收新數(shù)據(jù),便會將 nRTS 變 為有效(連接到低電平)。當(dāng)接收寄存器已滿時(shí),會將 nRTS 變?yōu)闊o效,表明發(fā)送過程會在 當(dāng)前幀結(jié)束后停止。下圖圖顯示了在使能 RTS 流控制的情況下進(jìn)行通信的示例。
CTS 流控制
如果使能 CTS 流控制 (CTSE=1),則發(fā)送器會在發(fā)送下一幀前檢查 nCTS。如果 nCTS 有效 (連接到低電平),則會發(fā)送下一數(shù)據(jù)(假設(shè)數(shù)據(jù)已準(zhǔn)備好發(fā)送,即 TXE=0);否則不會進(jìn) 行發(fā)送。如果在發(fā)送過程中 nCTS 變?yōu)闊o效,則當(dāng)前發(fā)送完成之后,發(fā)送器停止。
當(dāng) CTSE=1 時(shí),只要 nCTS 發(fā)生變化,CTSIF 狀態(tài)位便會由硬件自動(dòng)置 1。這指示接收器是 否已準(zhǔn)備好進(jìn)行通信。如果 USART_CR3 寄存器中的 CTSIE 位置 1,則會產(chǎn)生中斷。下圖 顯示了在使能 CTS 流控制的情況下進(jìn)行通信的示例。
注意:停止幀的特殊行為:當(dāng)使能 CTS 流后,發(fā)送器發(fā)送停止信號時(shí)將不檢查 nCTS 輸入狀態(tài)。
USART中斷
USART 中斷事件被連接到相同的中斷向量(請參見圖 270)。
● 發(fā)送期間:發(fā)送完成、清除以發(fā)送或發(fā)送數(shù)據(jù)寄存器為空中斷。
● 接收期間:空閑線路檢測、上溢錯(cuò)誤、接收數(shù)據(jù)寄存器不為空、奇偶校驗(yàn)錯(cuò)誤、LIN 斷路檢測、噪聲標(biāo)志(僅限多緩沖區(qū)通信)和幀錯(cuò)誤(僅限多緩沖區(qū)通信)
如果相應(yīng)的使能控制位置 1,則這些事件會生成中斷。
USART的配置模式
使用 DMA 進(jìn)行連續(xù)通信
使用 DMA 進(jìn)行發(fā)送
將 USART_CR3 寄存器中的 DMAT 位置 1 可以使能 DMA 模式進(jìn)行發(fā)送。當(dāng) TXE 位置 1 時(shí), 可將數(shù)據(jù)從 SRAM 區(qū)(通過 DMA 配置,參見 DMA 部分)加載到 USART_DR 寄存器。要 映射一個(gè) DMA 通道以進(jìn)行 USART 發(fā)送,請按以下步驟操作(x 表示通道編號):
1.在 DMA 控制寄存器中寫入 USART_DR 寄存器地址,將其配置為傳輸?shù)哪繕?biāo)地址。每次 發(fā)生 TXE 事件后,數(shù)據(jù)都會從存儲器移動(dòng)到此地址。
2. 在 DMA 控制寄存器中寫入存儲器地址,將其配置為傳輸?shù)脑吹刂?。每次發(fā)生 TXE 事件 后,數(shù)據(jù)都會從這個(gè)存儲區(qū)域加載到 USART_DR 寄存器中。
3. 在 DMA 控制寄存器中配置要傳輸?shù)目傋止?jié)數(shù)。
4. 在 DMA 寄存器中配置通道優(yōu)先級
5. 根據(jù)應(yīng)用的需求,在完成一半或全部傳輸后產(chǎn)生 DMA 中斷。
6. 向 SR 寄存器中的 TC 位寫入 0,將其清零。
7. 在 DMA 寄存器中激活該通道。
當(dāng)達(dá)到在 DMA 控制器中設(shè)置的數(shù)據(jù)傳輸量時(shí),DMA 控制器會在 DMA 通道的中斷向量上產(chǎn) 生一個(gè)中斷。
在發(fā)送模式下,DMA 對所有要發(fā)送的數(shù)據(jù)執(zhí)行了寫操作(DMA_ISR 寄存器中的 TCIF 標(biāo)志 置 1)后,可以對 TC 標(biāo)志進(jìn)行監(jiān)視,以確保 USART 通信已完成。在禁止 USART 或進(jìn)入 停止模式前必須執(zhí)行此步驟,以避免損壞最后一次發(fā)送。軟件必須等待直到 TC=1。TC 標(biāo)志 在所有數(shù)據(jù)發(fā)送期間都必須保持清零狀態(tài),然后在最后一幀發(fā)送結(jié)束后由硬件置 1。
使用 DMA 進(jìn)行接收
將 USART_CR3 寄存器中的 DMAR 位置 1 可以使能 DMA 模式進(jìn)行接收。接收數(shù)據(jù)字節(jié) 時(shí),數(shù)據(jù)會從 USART_DR 寄存器加載到 SRAM 區(qū)域中(通過 DMA 配置,參見 DMA 規(guī) 范)。要映射一個(gè) DMA 通道以進(jìn)行 USART 接收,請按以下步驟操作:
1.在 DMA 控制寄存器中寫入 USART_DR 寄存器地址,將其配置為傳輸?shù)脑吹刂?。每次發(fā) 生 RXNE 事件后,數(shù)據(jù)都會從此地址移動(dòng)到存儲器。
2. 在 DMA 控制寄存器中寫入存儲器地址,將其配置為傳輸?shù)哪繕?biāo)地址。每次發(fā)生 RXNE 事 件后,數(shù)據(jù)都會從 USART_DR 寄存器加載到此存儲區(qū)。
3. 在 DMA 控制寄存器中配置要傳輸?shù)目傋止?jié)數(shù)。
4. 在 DMA 控制寄存器中配置通道優(yōu)先級。
5. 根據(jù)應(yīng)用的需求,在完成一半或全部傳輸后產(chǎn)生中斷。
6. 在 DMA 控制寄存器中激活該通道。
當(dāng)達(dá)到在 DMA 控制器中設(shè)置的數(shù)據(jù)傳輸量時(shí),DMA 控制器會在 DMA 通道的中斷向量上產(chǎn) 生一個(gè)中斷。在中斷子程序中,USART_CR3 寄存器中的 DMAR 位應(yīng)由軟件清零。
注意:如果 DMA 用于接收,則不要使能 RXNEIE 位。
多緩沖區(qū)通信中的錯(cuò)誤標(biāo)志和中斷生成
在多緩沖區(qū)通信中,如果事務(wù)中發(fā)生任何錯(cuò)誤,都會在當(dāng)前字節(jié)后放置錯(cuò)誤標(biāo)志。如果中斷使能置 1,則會產(chǎn)生中斷。在單字節(jié)接收過程中,與 RXNE 一同置位的幀錯(cuò)誤、上溢錯(cuò)誤和噪聲標(biāo)志具有單獨(dú)的錯(cuò)誤標(biāo)志中斷使能位(USART_CR3 寄存器中的 EIE 位);如果該位置 1, 則會因其中任何一個(gè)錯(cuò)誤而在當(dāng)前字節(jié)后產(chǎn)生中斷。
STM32F4庫
串口配置流程
使能USART時(shí)鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USARTx, ENABLE);//1和6USART
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USARTx, ENABLE);//2、3、4、5USART
使能GPIO
RCC_AHB1PeriphClockCmd();//IO可以是TX,RX,CTS和SCLK
設(shè)置外設(shè)的復(fù)用功能
1、GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);//將引腳連接到相應(yīng)的復(fù)用功能
2、通過GPIO_InitStruct->GPIO_Mode_AF配置引腳到相應(yīng)復(fù)用功能
3、通過GPIO_PuPd,GPIO_OType和GPIO_Speed選擇IO的上下拉,IO類型和IO速度
4、(異步)通過USART_Init()配置Baud Rate,Word Length,Stop Bit,Parity,硬件數(shù)據(jù)了,模式(發(fā)送接收)。
USART_InitStructure.USART_BaudRate = 115200; /* 波特率 */
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No ;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx " USART_Mode_Tx; USART_Init(USART1,&USART_InitStructure);
5、對于同步模式通過USART_ClockInit()使能時(shí)鐘和polarity,phase和last bit
void USART_StructInit(USART_InitTypeDef* USART_InitStruct);
void USART_ClockInit(USART_TypeDef* USARTx, USART_ClockInitTypeDef* USART_ClockInitStruct);
void USART_ClockStructInit(USART_ClockInitTypeDef* USART_ClockInitStruct);
void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
void USART_SetPrescaler(USART_TypeDef* USARTx, uint8_t USART_Prescaler);
void USART_OverSampling8Cmd(USART_TypeDef* USARTx, FunctionalState NewState);
void USART_OneBitMethodCmd(USART_TypeDef* USARTx, FunctionalState NewState);
6、如果需要使能中斷,那么使能NVIC并通不過函數(shù)USART_ITConfig使能相應(yīng)中斷位
7、當(dāng)使用DMA模式時(shí)
——通過DMA_Init()函數(shù)配置DMA
——通過函數(shù)USART_Cmd()激活需要帶的通道
8、通過USART_Cmd()使能USART
9、當(dāng)使用DMA時(shí),通過DMA_Cmd()使能DMA
10、Multi-Processor,LIN,half-duplex,Smartcard,IrDA詳見M4權(quán)威指南
為了獲得更高的波特率,可以通過函數(shù) USART_OverSampling8Cmd()設(shè)置 8倍的過采樣(默認(rèn)是 16 倍的過采樣),這個(gè)函數(shù) 需要在時(shí)鐘RCC_APBxPeriphClockCmd()之后, USART_Init() 之前調(diào)用。
void USART_DeInit(USART_TypeDef* USARTx)通過復(fù)位時(shí)鐘實(shí)現(xiàn)
數(shù)據(jù)傳輸函數(shù)
通過函數(shù)USART_ReceiveData()來讀取寄存器USART_DR的數(shù)值這個(gè)數(shù)據(jù)來自RDR緩存器;通過函數(shù)USART_SendData()實(shí)現(xiàn)對寄存器USART_DR的寫操作,數(shù)據(jù)將被存儲到TDR緩存器上。
void USART_SendData(USART_TypeDef* USARTx, uint16_t Data)
{
/* Check the parameters */ assert_param(IS_USART_ALL_PERIPH(USARTx)); assert_param(IS_USART_DATA(Data));
/* Transmit Data */
USARTx->DR = (Data & (uint16_t)0x01FF);
}
uint16_t USART_ReceiveData(USART_TypeDef* USARTx)
{
/* Check the parameters */ assert_param(IS_USART_ALL_PERIPH(USARTx));
/*ReceiveData*/
return (uint16_t)(USARTx->DR & (uint16_t)0x01FF);
}
DMA傳輸和管理函數(shù)
函數(shù)USART_DMACmd用于使能DMA的發(fā)送和接收請求
void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState)
{
/* Check the parameters */ assert_param(IS_USART_ALL_PERIPH(USARTx)); assert_param(IS_USART_DMAREQ(USART_DMAReq)); assert_param(IS_FUNCTIONAL_STATE(NewState));
if (NewState != DISABLE)
{
/* Enable the DMA transfer for selected requests by setting the DMAT and/or DMAR bits in the USART CR3 register */
USARTx->CR3 |= USART_DMAReq;
}
else
{
/* Disable the DMA transfer for selected requests by clearing the DMAT and/or DMAR bits in the USART CR3 register */
USARTx->CR3 &= (uint16_t)~USART_DMAReq;
}
}
中斷標(biāo)志管理函數(shù)
查詢模式
(#) USART_FLAG_TXE : to indicate the status of the transmit buffer register
(#) USART_FLAG_RXNE : to indicate the status of the receive buffer register
(#) USART_FLAG_TC : to indicate the status of the transmit operation (#) USART_FLAG_IDLE : to indicate the status of the Idle Line
(#) USART_FLAG_CTS : to indicate the status of the nCTS input
(#) USART_FLAG_LBD : to indicate the status of the LIN break detection (#) USART_FLAG_NE : to indicate if a noise error occur
(#) USART_FLAG_FE : to indicate if a frame error occur
(#) USART_FLAG_PE : to indicate if a parity error occur
(#) USART_FLAG_ORE : to indicate if an Overrun error occur
在查詢模式,建議使用下面兩個(gè)函數(shù):
(+) FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG);
(+) void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG);