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表示通道編號):
- 在DMA控制寄存器中寫入USART_DR寄存器地址,將其配置為傳輸的目標地址。每次發生TXE事件后,數據都會從存儲器移動到此地址。
- 在DMA控制寄存器中寫入存儲器地址,將其配置為傳輸的源地址。每次發生TXE后,數據都會從這個存儲區域加載到USART_DR寄存器中。
- 在DMA控制寄存器中配置要傳輸的總字節數。
- 在DMA寄存器中配置通道的優先級
- 根據應用的需求,在完成一半或全部傳輸后產生DMA中斷
- 向SR寄存器中的TC位寫入0,將其清零
- 在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進行數據的傳輸