STM32系列 USART通信


0 前言

UART:通用異步收發傳輸器,是一種通用串行數據線,用於異步通信,雙向通信,可以實現全雙工傳輸和接收。
USART:通用同步/異步串行收發器,是一個全雙工通用同步/異步串行收發模塊。
USART收發模塊分為三個部分:時鍾發生器、數據發送器和接收器。
時鍾發生器由同步邏輯電路(在同步從模式下由外部時鍾輸入驅動)和波特率發生器組成。發送時鍾引腳XCK僅用於同步發送模式下。
發送器部分由一個單獨的寫入緩沖器(發送UDR)、一個串行移位寄存器、校驗位發生器和用於處理不同幀結構的控制邏輯電路構成。使用吸入緩沖器,實現了連續發送多幀數據無延時的通信。
接收器最主要的是時鍾和數據接收單元。數據接收單元用作異步數據的接收。除了接收單元,接收器還包括校驗位校驗器、控制邏輯、移位寄存器和兩級接收緩沖器(接收UDR)。接收器支持與發送器相同的幀結構,同時支持幀錯誤、數據溢出和校驗錯誤的檢測。
UART和USART的區別:
從名字上看,USART在UART基礎上增加了同步功能,即USART是UART的增加型,使用USART在異步通信時,與UART沒什么區別,但是用在同步通信時,區別就明顯了,同步通信需要時鍾來觸發數據傳輸,也就是說USART相對於UART能提供主動時鍾。

1 簡介

通用同步異步收發器(USART)能夠靈活的與外部設備進行全雙工數據交換,滿足外部設備對工業標准NRZ異步串行數據格式的要求。通過小數波特率發生器提供了多種波特率。支持同步單向通信和半雙工擔心通信;還支持LIN(局域互連網絡)、智能卡協議與IrDA(紅外線數據協會)SIR ENDEC規范,以及調制解調器操作(CTS/RTS)。而且還支持多處理器通信。通過配置多個緩沖區使用DMA可實現高速數據通信。

2 主要特性

  • 全雙工異步通信
  • NRZ標准格式(標記/空格)
  • 可配置為16倍過采樣或8倍過采樣,因而為速度容差與時鍾容差的靈活配置提供了可能
  • 小數波特率發生器系統
     - 通用可編程收發波特率
  • 數據字長度可編程(8位或9位)
  • 停止位可配置
     - 支持1或2個停止位
  • LIN主模式同步停止符號發送功能和LIN從模式停止符號檢測功能
     - 對USART進行LIN硬件配置時可發生13位停止符合和檢測10/11位停止符號
  • 用於同步發送的發送器時鍾輸出
  • IrDA SIR編碼解碼器
     - 正常模式下,支持3/16位持續時間
  • 智能卡仿真功能
     - 智能卡接口支持符合ISO 7816-3標准中定義的異步協議智能卡
     - 智能卡工作模式下,支持0.5或1.5個停止位
  • 單線半雙工通信
  • 使用DMA(直接存儲器訪問)實現可配置的多緩沖區通信
     - 使用DMA在預留的SRAM緩沖區中收/發字節
  • 發送器和接收器具有單獨使能位
  • 傳輸檢測標志:
     - 接收緩沖區已滿
     - 發送緩沖區為空
     - 傳輸結束標志
  • 奇偶校驗控制:
     - 發送奇偶校驗位
     - 檢查接收的數據字節的奇偶性
  • 四個錯誤檢測標志:
     - 溢出錯誤
     - 噪聲檢測
     - 幀錯誤
     - 奇偶檢驗錯誤
  • 十個具有標志位的中斷源:
     - CTS變化
     - LIN停止符號檢測
     - 發送數據寄存器為空
     - 發送完成
     - 接收數據寄存器已滿
     - 接收到線路空閑
     - 溢出錯誤
     - 幀錯誤
     - 噪聲錯誤
     - 奇偶檢驗錯誤
  • 多處理器通信
     - 
  • 從靜模式喚醒(通過線路空閑檢測或地址標記檢測)
  • 兩個接收器喚醒模式:地址位(MSB,第9位),線路空閑

3 功能說明

接口通過三個引腳從外部設備連接到其他設備。任何USART雙向通信均需要至少兩個引腳:接收數據輸入引腳(RX)和發送數據輸出引腳(TX)
RX:就是串行數據輸入引腳。過采樣技術可區分有效輸入數據和噪聲,從而用於恢復數據
TX:如果關閉發送器,該輸出引腳模式由其I/O端口配置決定。如果使能了發送器但沒有待發送的數據,則TX引腳處於高電平。在單線和智能卡模式下,該I/O用於發送和接收數據(USART電平下,隨后在SW_RX上接收數據)
正常USART模式下,通過這些引腳以幀的形式發送和接收串行數據:

  • 發送或接收前保持空閑線路
  • 起始位
  • 數據(字長8位或9位),最低有效位在前
  • 用於指示幀傳輸已完成的0.5個、1個、1.5個、2個停止位
  • 該接口使用小數波特率發生器 - 帶12位尾數和4位小數
  • 狀態寄存器(USART_SR)
  • 數據寄存器(USART_DR)
  • 波特率寄存器(USART_BRR) - 12位尾數和4位小數
  • 智能卡模式下的保存時間寄存器(USART_GTPR)
    在同步模式下連接時需要一下引腳:
    SCLK:發送器時鍾輸出,用於輸出發送器數據時鍾,一遍按照SPI主模式進行同步發送(起始位和結束位上無時鍾脈沖,可通過軟件向最后一位數據位發送時鍾脈沖)。RX上可同步接收並行數據。可用於控制帶移位寄存器的外設(如LCD驅動器)。時鍾相位和極性可通過軟件編程。在智能卡模式下,SCLK可向智能卡提供時鍾
    在硬件流控制模式下需要以下引腳:
    nCTS:“清除以發送”用於在當前傳輸結束時阻止數據發送(高電平時)
    nRTS:“請求以發送”用於指示USART已准備好接收數據(低電平時)

4 使用DMA進行通信

USART能夠使用DMA進行連續通信,接收緩沖區和發送緩沖區的DMA請求時獨立的

  • 使用DMA進行發送
    將USART_CR3寄存器中的DMAT位置1可以使能DMA模式進行發送。當TXE位置1時,可將數據從SRAM區加載到USART_DR寄存器。要映射一個DMA通道以進行USART發送,按以下步驟操作(x表示通道編號):
  1. 在DMA控制寄存器中寫入USART_DR寄存器地址,將其配置為傳輸的目標地址。每次發生TXE事件后,數據都會從存儲器移動到此地址。
  2. 在DMA控制寄存器中寫入存儲器地址,將其配置為傳輸的源地址。每次發生TXE后,數據都會從這個存儲區域加載到USART_DR寄存器中。
  3. 在DMA控制寄存器中配置要傳輸的總字節數。
  4. 在DMA寄存器中配置通道的優先級
  5. 根據應用的需求,在完成一半或全部傳輸后產生DMA中斷
  6. 向SR寄存器中的TC位寫入0,將其清零
  7. 在DMA寄存器中激活該通道
    當達到在DMA控制器中設置的數據傳輸量時,DMA控制器會在DMA通道中的中斷向量生上產生一個中斷。
    在發送模式下,DMA對所有要發送的數據執行了寫操作(DMA_ISR寄存器中的TCIF標志置1)后,可以對TC標志進行監視,以確保USART通信已完成。在禁止USART或進入停止模式前必須執行此步驟,以避免損壞最后一次發送。軟件必須等待直到TC=1。TC標志在所有數據發送期間都必須保持清零狀態,然后在最后一幀發送結束后由硬件置1。

使用DMA進行發送
在這里插入圖片描述

  • 使用DMA進行接收
    將USART_CR3寄存器中的DMAR位置1可以使能DMA模式進行接收。接收數據字節時,數據會從USART_DR寄存器加載到SRAM區域中。要映射一個DMA通道以進行USART接收,按以下步驟操作:

  • 在DMA控制器中寫入USART_DR寄存器地址,將其配置為傳輸的源地址。每次發生RXNE事件后,數據都會以此地址移動到存儲器

  • 在DMA控制寄存器中寫入存儲器地址,將其配置為傳輸的目標地址。每次發生RXNE事件后,數據都會從USART_DR寄存器加載到此存儲區

  • 在DMA控制寄存器中配置要傳輸的總字節數

  • 在DMA控制寄存器中配置通道優先級

  • 根據應用的需求,在完成一半或全部傳輸后產生中斷

  • 在DMA控制寄存器中激活該通道
    當達到在DMA控制器中設置的數據傳輸量時,DMA控制器會在DMA通道的中斷向量上產生一個中斷。在中斷子程序中,USART_CR3寄存器中的DMAR位應有軟件清零。
    如果DMA用於接收,則不要使能RXNEIE位。

  • 使用DMA進行接收

在這里插入圖片描述
在多緩沖區通信中,如果發生任何錯誤,都會在當前字節后放置錯誤標志。如果中斷使能置1,則會產生中斷。在單字節接收過程中,與RXNE一同置位的幀錯誤、上溢錯誤和噪聲標志具有單獨的錯誤標志中斷使能位(USART_CR3寄存器中的EIE位);如果該位置1,則會因其中任何一個錯誤而在當前字節后產生中斷。

5 USART中斷

中斷事件 事件標志 使能控制位
發送數據寄存器為空 TXE TXEIE
CTS標志 CTS CTSIE
發送完成 TC TCIE
准備好讀取接收到的數據 RXNE RXNEIE
檢測到上溢錯誤 ORE RXNEIE
檢測到空閑線路 IDLE IDLEIE
奇偶校驗錯誤 PE PEIE
斷路標志 LBD LBDIE
多緩沖區通信中的噪聲標志、上溢錯誤和幀錯誤 NF或ORE或FE EIE
USART中斷事件被連接到相同的中斷向量
  • 發送期間:發送完成、清楚以發送或發送數據寄存器為空中斷
  • 接收期間:空閑線路檢測、上溢錯誤、接收數據寄存器不為空、奇偶校驗錯誤、LIN斷路檢測、噪聲標志(僅限多緩沖區通信)和幀錯誤(僅限多緩沖區通信)
    如果相應的使能控制位置1,則這些事件會發生中斷

6 代碼實現

USART初始化

 void USART_Init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);         //GPIO時鍾使能
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);        //USART時鍾使能
	GPIO_PinAFConfig(GPIO_DEBUG, GPIO_PinSource9, GPIO_AF_USART1); //GPIO復用
	GPIO_PinAFConfig(GPIO_DEBUG, GPIO_PinSource10, GPIO_AF_USART1);//GPIO復用

	GPIO_InitStructure.GPIO_Pin = GPIO_PIN_TX | GPIO_PIN_RX;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;             //設置為復用推免輸出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIO_DEBUG, &GPIO_InitStructure);

	USART_InitStructure.USART_BaudRate = 115200;                  //設置波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;   //8位數據格式
	USART_InitStructure.USART_StopBits = USART_StopBits_1;        //1個停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;           //無奇偶校驗位
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//收發模式
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //無硬件數據流控制
	USART_Init(USART1, &USART_InitStructure);
	
	USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
	USART_ITConfig(USART1, USART_IT_IDLE, DISABLE);
	USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);   //使能USART接收中斷
	USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);   //使能檢測到空閑線路中斷
	
	USART_Cmd(USART1, ENABLE);  //使能USART   
}

USART發送數據
調用USART_SendData函數進行數據發送

void USART_SendData(USART_TypeDef* USARTx, uint16_t Data);
USARTx:選擇USART或者UART設備
Data:傳輸的數據

USART_SendData()只能一個字節一個字節的發送

USART接收數據
可以通過輪詢,中斷和DMA的發送接收數據

void USART1_IRQHandler(void)
{
	uint32_t temp;
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
	{
		RecvBuf[recvcnt] = USART_ReceiveData(USART1);  //接收數據,放入接收buff
		recvcnt++;
		USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除接收中斷
	}
	if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
	{
	    //清除空閑中斷
		temp = USART1->SR;
		temp = USART1->DR;
		idle_flag = 1;
	}
}
uint16_t USART_ReceiveData(USART_TypeDef* USARTx);
USARTx:選擇USART或者UART設備

STM32的IDLE的中斷在串口無數據接收的情況下,是不會一直產生的,產生的條件是,當清除IDLE標志位后,必須有接收到第一個數據后,才開始觸發,一斷接收的數據斷流,沒有接收到數據,即產生IDLE中斷。IDLE位不會再次被置高直到RXNE位被置起(即又檢測到一次空閑總線)。RXNE接收中斷可以不用開啟,減少進中斷的次數
串口總線空閑檢測這一特性,尤其是對收到的數據是不定長時更有效果
在這里插入圖片描述
如果數據量比較大的時候,我們可以考慮使用DMA進行數據的傳輸


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM