使用LL库开发STM32:UART基础使用
文章目錄
- 目的
- 基礎說明與初始化
- 基礎說明
- 初始化配置
- 數據接收和發送
- 輪詢方式
- 中斷方式
- DMA方式
- 總結
目的
UART(異步串口)是單片機非常常用的一個功能,一般用作設備或模塊間通訊的一種方式。通常所說的232或是485通訊從寫程序的角度來說就是使用UART進行通訊。(這個地方有些人會混淆,串口更多是一種通訊方式、機制,而TTL、232、485更多的是電氣相關特性)
HAL庫使用UART非常簡單,LL庫相對來說會稍微麻煩一點點。HAL庫設計了三套數據首發了模式,你可以選擇其中一套使用,這對新手來說上手可以非常快,但現實情況中這三套模式其實不是那么實用的,你如果想要在此基礎上做些改變就會麻煩。UART中使用LL庫相對來說是個更好的選擇,這篇文章先講下LL庫中使用UART的基本操作。
基礎說明與初始化
基礎說明
STM32系列MCU大多都有多個UART可以使用,每個UART可以設置獨立的參數,和其它設備通訊時通訊的雙方必須有相同的參數。一般會涉及的參數如下:
- BaudRate 波特率,通訊速率,當其他參數默認時,每秒可傳輸字節數約為 BaudRate/10;
- WordLength 數據位,數據位表示每一個數據包含bit數,一般用8bit,即一個數據為一個字節;
- StopBits 停止位,停止位用來表示一個數據傳輸結束;
- Parity 校驗位,校驗位用來校驗傳輸的數據是否正確,一般也比較少用,通訊用的協議一般帶自己的校驗方式;
- HwFlowCtl 流控制,現在比較少用到;
- OverSampling 過采樣,一般默認就行;
初始化配置
使用STM32CubeIDE或STM32CubeMX來初始化UART的話我們一般只要根據需求設置基本參數、中斷、DMA即可,如下圖所示:
使用中如果需要更改相關參數的話可以直接按照軟件生成的初始化程序來,也可以使用LL庫中提供的修改單獨參數的方法:
- LL_USART_SetBaudRate(USART_TypeDef *USARTx, uint32_t PeriphClk, uint32_t OverSampling, uint32_t BaudRate)
設置通訊波特率; - LL_USART_SetDataWidth(USART_TypeDef *USARTx, uint32_t DataWidth)
設置數據位長度; - LL_USART_SetStopBitsLength(USART_TypeDef *USARTx, uint32_t StopBits)
設置停止位長度; - LL_USART_SetParity(USART_TypeDef *USARTx, uint32_t Parity)
設置校驗位; - LL_USART_SetTransferDirection(USART_TypeDef *USARTx, uint32_t TransferDirection)
設置傳輸方向; - LL_USART_SetHWFlowCtrl(USART_TypeDef *USARTx, uint32_t HardwareFlowControl)
設置硬件流控制; - LL_USART_SetOverSampling(USART_TypeDef *USARTx, uint32_t OverSampling)
設置過采樣;
數據接收和發送
HAL庫中UART的數據接收和發送設計了輪詢、中斷、DMA三種方式來使用,這篇文章中將介紹下LL庫中這三種基礎的使用方式。
輪詢方式
如果只是要測試串口收發數據的話,輪詢方式不管是配置還是使用都是最簡單的,先看下面演示:
上面演示中軟件配置中只是使能了USART1,將其設置成異步模式,然后將相關的庫設置為LL庫,其它的都沒改,在生成的程序中在主循環中添加了少量代碼就實現了將收到的數據回傳的功能。其中涉及的方法如下:
- uint32_t LL_USART_IsActiveFlag_RXNE(USART_TypeDef *USARTx)
查詢是否有收到可讀取的數據; - uint8_t LL_USART_ReceiveData8(USART_TypeDef *USARTx)
讀取收到的數據,讀取后會自動清除RXNE標志位; - uint32_t LL_USART_IsActiveFlag_TXE(USART_TypeDef *USARTx)
查詢是否可以向發送數據寄存器寫數據; - void LL_USART_TransmitData8(USART_TypeDef *USARTx, uint8_t Value)
將數據寫入發送數據寄存器,寫入后數據將自動發送;
中斷方式
上面的輪詢方式在實際項目中通常使用率不是那么高,中斷的方式更加常用些,先看下面演示:
上面演示中除了軟件自動生成的代碼手動添加的代碼只有開啟中斷已經中斷回調函數中的操作,新涉及的方法如下:
- void LL_USART_EnableIT_RXNE(USART_TypeDef *USARTx)
使能RXNE中斷; - uint32_t LL_USART_IsEnabledIT_RXNE(USART_TypeDef *USARTx)
查詢是否是RXNE中斷;
上面例子中只用到了接收中斷,發送中斷也有相應的方法使能和查詢。另外可以用 LL_USART_ClearFlag_.... 方法來清除中斷標志。
DMA方式
和中斷方式相比使用DMA方式使用頻率就更高了,先看下面演示:
- 初始化配置
- 測試代碼
- 通訊測試
上面演示中除了軟件自動生成的代碼,我們需要手動添加下面這些內容來啟用相應功能:
- 設置外設地址
void LL_DMA_SetPeriphAddress(DMA_TypeDef* DMAx, uint32_t Stream, uint32_t PeriphAddress)
使用上面方法來設置外設地址,這個演示中指USART的DR寄存器地址,通過下面方法獲取:
uint32_t LL_USART_DMA_GetRegAddr(USART_TypeDef *USARTx) - 設置內存地址
void LL_DMA_SetMemoryAddress(DMA_TypeDef* DMAx, uint32_t Stream, uint32_t MemoryAddress)
使用上面方法來設置內存地址,這個演示中指接收或發的數組數據; - 設置數據長度
void LL_DMA_SetDataLength(DMA_TypeDef* DMAx, uint32_t Stream, uint32_t NbData)
使用上面方法來設置要傳輸的數據長度; - 使能相應的中斷
void LL_DMA_EnableIT_TC(DMA_TypeDef *DMAx, uint32_t Stream)
這個演示中使用了上面方法來開啟DMA傳輸完成中斷; - 使能USART的DMA傳輸
void LL_USART_EnableDMAReq_RX(USART_TypeDef *USARTx)
void LL_USART_EnableDMAReq_TX(USART_TypeDef *USARTx)
使用上面方法分別使能USART通過DMA傳輸數據; - 啟動DMA傳輸
void LL_DMA_EnableStream(DMA_TypeDef *DMAx, uint32_t Stream)
使用上面方法后數據將開始傳輸;
上面演示中在中斷回調函數中我們進行了下面的操作:
- 判斷中斷事件類型
uint32_t LL_DMA_IsActiveFlag_xxx(DMA_TypeDef *DMAx)
使用上面方法來判斷中斷類型; - 清除中斷標志
void LL_DMA_ClearFlag_xxx(DMA_TypeDef *DMAx)
使用上面方法來清除中斷標志; - 停止已完成的DMA傳輸
void LL_DMA_DisableStream(DMA_TypeDef *DMAx, uint32_t Stream)
使用上面方法可以停止DMA傳輸; - 添加所需的功能代碼
上面演示中我在接收完成中斷中啟動了USART DMA發送功能,將收到的數據回發;在發送完成中斷中重新啟動了USART DMA接收功能;
總結
用LL庫來使用UART相比HAL庫也并沒有復雜太多,不過和HAL庫對于各種芯片有著較好兼容性不同的是LL庫對于各種芯片的兼容性不怎么好,比如STM32F4系列的芯片中DMA涉及Stream,而STM32F1系列芯片的DMA并沒有Stream卻有Channel,兩者代碼上無法直接套用。
事實上這篇文章中的各個演示只是介紹了下LL庫中UART的基本使用方法,實際項目中通常不會這么用,更常見的使用方法將在后面的文章中介紹。
總結
以上是生活随笔為你收集整理的使用LL库开发STM32:UART基础使用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 焊接机器人编程及调试方法
- 下一篇: J - 单源最短路