下面三種方式都親測可用,實際使用時應采用第三種方法,更有效率。
方法一:
先說重點:
1)RXNE,表示一個字節產生一次中斷,這里要著重說明一下,是一個字節。原因是DR寄存器是32位,有效位是8位。比如串口發送的字符或字符串,其對應的ASICC碼的二進制都是8位的,所以不管是發送“1”,都是8位
2)IDLE,表示DR先有數據(可以是一個字節的數據,也可以是N個字節的數據連續發過來),然后空閑了一個字節的時間,就會產生中斷。
如果要讓串口發送不定長度的的數據,則先通過RXNE,把數據一個字節一個字節地存起來,當一串信息發送完時,因為要停頓一下,則會產生IDLE中斷,利用IDLE中斷,表示完成接收數據,具體方法如下:
先定義一個數組和數組長度:
uint8_t Rx1_Buff[50]={'0'};
uint8_t rx_buffer_len=0;
方法二:
使用STM32串口中斷實現非阻塞方式接收不定長數據
一、簡介
1.1、開發環境
STM32CubeIDE V1.9。
1.2、實現功能
使用STM32的串口1,接收不定長數據,并返回接收數據
二、步驟解析
2.1、配置串口
打開“Device Configuration Tool”(即STM32CubeMX),配置串口1。
注:一定要在“NVIC Settings”欄,勾選“USART1 global interrupt”打開串口中斷。
2.2、初始化
初始化過程中,調用函數“HAL_UARTEx_ReceiveToIdle_IT”。
HAL庫中對該函數的定義:
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)。
huart:定義串口,一般填寫 &huartx(x為串口號,取1、2、3……)。本案例使用串口1,則填寫&huart1;
pData:接收數據存放的首地址,一般填寫一維數組名;
Size:定義接收的字節長度,填寫接收數據的最大字節數。
2.3、回調函數
調用函數“HAL_UARTEx_ReceiveToIdle_IT”后,當接收長度等于Size,或者串口接收數據過程中產生空閑時,會執行回調函數"HAL_UARTEx_RxEventCallback"。
HAL庫中對該函數的定義:
__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
huart:回調串口號;
Size:實際接收的字節長度。
注:該回調函數為空的弱函數,函數主體需自己重新定義。
三、實例
從串口1接收不定長數據,存放在數組array[50]中,并返回所接收的數據。
3.1、定義
定義一維數組array:
uint8_t array[50];
3.2、主函數
在主函數的初始化過程,調用函數“HAL_UARTEx_ReceiveToIdle_IT”:
void main()
{
HAL_UARTEx_ReceiveToIdle_IT(&huart1, array, 50); //初始化開啟串口接收
while(1);
}
3.3、重新定義回調函數
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if(huart==&huart1) //判定:串口1接收
{
HAL_UART_Transmit(&huart1,Rx1_Buff,strlen((constchar*)Rx1_Buff),0x000A); //把接收到的數據發送出去
memset(Rx1_Buff,0,strlen((const char*)Rx1_Buff));//清空數組
HAL_UARTEx_ReceiveToIdle_IT(&huart1, array, 50) ; //重新開啟串口接收
}
}
初始化打開串口接收中斷,當串口接收滿50字節,或串口產生空閑時,會執行回調函數。回調函數里判斷串口后正確后,執行對應的功能函數,并再次開啟串口接收中斷。
HAL_UARTEx_ReceiveToIdle_IT(),其實是實現RXNE和IDLE中斷,和方式一是一樣的原理
以上兩種方式,每一個字符都會中斷一次,效率不高,采用DMA接收的方式會更高一點,DMA空閑中斷的方式見這份文檔《STM32F103用hal庫使用DMA+串口空閑中斷接收數據_L》,或下方第三種方式.
方法三:
1.CUBE的設置就不講了,CUBE設置完后,就進行第二步。
2.生成代碼后,在main函數中打開串口空閑中斷,單個字符中斷用于接收用的,因為我這例程作用是串口1發送數據并把數據發送回來。
3.在串口中斷中添加如下:
4.DMA發送完后,要清除數組Rx1_Buff里的數據,不然下次接收的數據會重復覆蓋,有可能覆蓋不全。其實HAL_UART_Transmit_DMA(), 這個函數接收完會調用回調函數。
HAL_UART_Transmit_DMA() - >
UART_DMATransmitCplt - >
HAL_UART_TxCpltCallback() - >
__weak void HAL_UART_TxCpltCallback()
5.構造HAL_UART_TxCpltCallback()函數,不需要添加申明
-
STM32
+關注
關注
2282文章
10986瀏覽量
361085 -
中斷
+關注
關注
5文章
902瀏覽量
42339 -
串口
+關注
關注
14文章
1580瀏覽量
78293 -
字符串
+關注
關注
1文章
589瀏覽量
20933
發布評論請先 登錄
相關推薦
用串口DMA傳輸不定長度包的方式
STM32單片機的接收不定長度字節數據的方法
stm32 串口接收不定長度數據及黏包處理 + 串口DMA接收

評論