STM32的USART1與USART2模塊支持多種功能,包括IrDA紅外、Smart Card(IC卡)等。本文就其串行數(shù)據(jù)通訊功能進(jìn)行講解。
USART功能圖:
一般情況串口都采用異步方式通訊,因此本文只講解異步通訊方式(UART)。異步模式下串口采用Tx、Rx兩線,其數(shù)據(jù)模式如圖:
上圖為數(shù)據(jù)長度為8位(包括1位校驗)的情形。位數(shù)據(jù)的意義:
總線空閑 :空閑時線上為高電平。
起始位 :一位邏輯0信號幀,代表傳輸開始。
數(shù)據(jù)位 :可以為7位或8位數(shù)據(jù)。低位開始傳輸
校驗位: 若啟用,使得邏輯1的位數(shù)應(yīng)為偶數(shù)(偶校驗)或奇數(shù)(奇校驗)。若不啟用,該位由一位數(shù)據(jù)幀替代(多一位數(shù)據(jù))。
停止位: 一位或兩位邏輯1,標(biāo)志一個數(shù)據(jù)字符傳輸完成。
※一般情況下個人推薦①數(shù)據(jù)長度為9位(有效數(shù)據(jù)8位+一位校驗)或②數(shù)據(jù)8位(無校驗);并盡量采用ascii或16進(jìn)制編碼方式。
UART配置結(jié)構(gòu)體LL_USART_InitTypeDef
typedef struct
{
uint32_t BaudRate;/*
配置波特率;通過LL_USART_SetBaudRate()函數(shù)實現(xiàn)
@param BaudRate=115200,9600.etc
*/
uint32_t DataWidth;/*
配置數(shù)據(jù)幀數(shù);通過LL_USART_SetDataWidth()函數(shù)實現(xiàn)
@param DataWidth = LL_USART_DATAWIDTH_8B
LL_USART_DATAWIDTH_9B
*/
uint32_t StopBits;/*
設(shè)置停止位數(shù);通過LL_USART_SetStopBitsLength()實現(xiàn)
@param StopBits = LL_USART_STOPBITS_0_5 0.5stop bit
LL_USART_STOPBITS_1 1 stop bit
LL_USART_STOPBITS_1_5 1.5stop bits
LL_USART_STOPBITS_2 2stop bits
*/
uint32_t Parity;/*
設(shè)置校驗位;通過LL_USART_SetParity()實現(xiàn)
@param Parity = LL_USART_PARITY_NONE
LL_USART_PARITY_EVEN 偶校驗
LL_USART_PARITY_ODD 奇校驗
*/
uint32_t TransferDirection;/*
設(shè)置數(shù)據(jù)收發(fā)模式;通過LL_USART_SetTransferDirection()實現(xiàn)
@param TransferDirection = LL_USART_DIRECTION_NONE 雙向禁用
LL_USART_DIRECTION_RX 單接收
LL_USART_DIRECTION_TX 單發(fā)送
LL_USART_DIRECTION_TX_RX 發(fā)送&接收
*/
uint32_t HardwareFlowControl; /*
用于RS232的其他硬件引腳配置(CTS、RTS);通過LL_USART_SetHWFlowCtrl()實現(xiàn)
@param HardwareFlowControl = LL_USART_HWCONTROL_NONE 無
LL_USART_HWCONTROL_RTS RTS
LL_USART_HWCONTROL_CTS CTS
LL_USART_HWCONTROL_RTS_CTS CTS&RTS
*/
uint32_t OverSampling;/*
設(shè)置過采樣。通過LL_USART_SetOverSampling()實現(xiàn)?!灰? @param OverSampling = LL_USART_OVERSAMPLING_16
LL_USART_OVERSAMPLING_8
*/
} LL_USART_InitTypeDef;
__STATIC_INLINE void LL_USART_Enable(USART_TypeDef *USARTx);/*
啟用USART模塊;生成的初始化代碼中已調(diào)用。
@param USARTx= USART1
USART2 .etc
*/
__STATIC_INLINE void LL_USART_Disable(USART_TypeDef *USARTx);/*
關(guān)閉USART模塊
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabled(USART_TypeDef *USARTx);/*
檢測USART模塊是否已開啟。
@retval = 0 !0
*/
※
ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, LL_USART_InitTypeDef *USART_InitStruct);/*
USART初始化函數(shù); @retval = SUCCESS ERROR
*/
以下函數(shù)與狀態(tài)寄存器有關(guān)(相關(guān)函數(shù)只用于指示狀態(tài),可以不使用):
請在reset時先將使用到的位清零
※但若使能中斷,則中斷處理完全必須清零狀態(tài)位方能產(chǎn)生下一次interrupt
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_PE(USART_TypeDef *USARTx);/*
接收使能時,判斷是否發(fā)生奇偶性校驗錯誤(檢測PE位,當(dāng)錯誤時置位,通過軟件清零)
※當(dāng)CubeMx設(shè)置了奇偶校驗時有效
@retval = 1 發(fā)生過錯誤
*/
__STATIC_INLINE void LL_USART_ClearFlag_PE(USART_TypeDef *USARTx);/*
清零PE位。
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_FE(USART_TypeDef *USARTx);/*
判斷是否發(fā)生幀錯誤(噪聲、斷開符)。(檢測FE位,當(dāng)錯誤時置位,通過軟件清零)
@retval = 1 發(fā)生過錯誤
*/
__STATIC_INLINE void LL_USART_ClearFlag_FE(USART_TypeDef *USARTx);/*
清零FE位
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_NE(USART_TypeDef *USARTx);/*
檢測噪聲錯誤。(檢測NE位,當(dāng)錯誤時置位,通過軟件清零)
*/
__STATIC_INLINE void LL_USART_ClearFlag_NE(USART_TypeDef *USARTx);/*
清零NE位
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ORE(USART_TypeDef *USARTx);/*
檢測過載錯誤。(讀取寄存器中數(shù)據(jù)尚未被讀取時收到新數(shù)據(jù))(ORE位)
*/
__STATIC_INLINE void LL_USART_ClearFlag_ORE(USART_TypeDef *USARTx);/*
清零ORE位
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_IDLE(USART_TypeDef *USARTx);/*
檢測總線空閑;(IDLE位)
*/
__STATIC_INLINE void LL_USART_ClearFlag_IDLE(USART_TypeDef *USARTx);/*
清零IDLE位
*/
以下為使用頻繁的狀態(tài)寄存器相關(guān)函數(shù):
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXNE(USART_TypeDef *USARTx);/*
讀數(shù)據(jù)非空 ;檢測讀取數(shù)據(jù)寄存器RDR狀態(tài)。
※讀取數(shù)據(jù)寄存器RDR 完全 完成一次數(shù)據(jù)接收時,該位被置位。@retval =1
※對讀取數(shù)據(jù)寄存器RDR的讀取操作可以硬件清零 該位。
不推薦軟件清零
*/
__STATIC_INLINE void LL_USART_ClearFlag_RXNE(USART_TypeDef *USARTx);/*慎用*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TC(USART_TypeDef *USARTx);/*
發(fā)送完成 ;讀TC
當(dāng)發(fā)送完一幀,且發(fā)送數(shù)據(jù)寄存器空時@retval = 1
需要通過軟件清零
*/
__STATIC_INLINE void LL_USART_ClearFlag_TC(USART_TypeDef *USARTx);
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXE(USART_TypeDef *USARTx);/*
發(fā)送數(shù)據(jù)寄存器空 ; 檢測發(fā)送數(shù)據(jù)寄存器TDR狀態(tài)
※當(dāng)發(fā)送數(shù)據(jù)寄存器TDR數(shù)據(jù)被送出時,該位被置位。 @retval = 1
※對發(fā)送數(shù)據(jù)寄存器TDR的寫入操作可以硬件清零該位。
不推薦軟件清零
*/
__STATIC_INLINE void LL_USART_ClearFlag_TXE(USART_TypeDef *USARTx);/*慎用*/
相關(guān)寄存器:
串口中斷的使用
關(guān)于中斷源:
IDLE中斷:總線空閑中斷
RXNE中斷:接收緩沖區(qū)非空中斷※常用
TC中斷:發(fā)送完成中斷
TXE中斷:發(fā)送緩沖區(qū)空中斷
PE中斷:校驗失敗中斷※常用
※以上中斷發(fā)生將同時調(diào)用同一中斷函數(shù)void USARTx_IRQHandler(void)。可在函數(shù)內(nèi)判斷具體的中斷源。
配置中斷使能:
__STATIC_INLINE void LL_USART_EnableIT_IDLE(USART_TypeDef USARTx);/
使能總線空閑中斷
*/
__STATIC_INLINE void LL_USART_EnableIT_RXNE(USART_TypeDef USARTx);/
使能RXNE中斷
*/
__STATIC_INLINE void LL_USART_EnableIT_TC(USART_TypeDef USARTx);/
使能TC中斷
*/
__STATIC_INLINE void LL_USART_EnableIT_TXE(USART_TypeDef USARTx);/
使能TXE中斷
*/
__STATIC_INLINE void LL_USART_EnableIT_PE(USART_TypeDef USARTx);/
使能PE中斷
*/
**禁用中斷 **
函數(shù)模板為LL_USART_DisableIT_xxx(USART_TypeDef *USARTx);
中斷程序編寫
使能串口中斷后,中斷調(diào)用函數(shù)為void USART?_IRQHandler(void)
若啟用了多個對應(yīng)的中斷源,則應(yīng)該在中斷函數(shù)中
判斷中斷源,再進(jìn)行對應(yīng)操作。
判斷原理:
初始化時啟用相應(yīng)中斷并軟件清零用到的狀態(tài)位。
當(dāng)觸發(fā)相應(yīng)的事件時,中斷源的狀態(tài)位被置位,其余狀態(tài)位仍處于初始化后0態(tài)。此時跳轉(zhuǎn)執(zhí)行中斷函數(shù)void USART?_IRQHandler(void)
在中斷函數(shù)中進(jìn)行用到的狀態(tài)位的判斷,若狀態(tài)位為1則為中斷源
執(zhí)行完后,將相應(yīng)狀態(tài)位清零以使能下一次中斷
示例程序:以接收中斷為例
在 usart.c中:
void MX_USART1_UART_Init(void)
{
·
·
LL_USART_ClearFlag_RXNE(USART1);//強(qiáng)制清零狀態(tài)位
LL_USART_EnableIT_RXNE(USART1); //使能RXNE中斷
·
}
在it.c中
void USART1_IRQHandler(void)
{
if (LL_USART_IsActiveFlag_RXNE(USART1))//判斷中斷源
{
LL_USART_TransmitData8(USART1, LL_USART_ReceiveData8(USART1));/*讀接收寄存器(8bit)并發(fā)送,
*讀操作自動清零狀態(tài)位*/
//LL_USART_ClearFlag_RXNE(USART1);//強(qiáng)制清零狀態(tài)位,不推薦使用
}
}
評論
查看更多