下面三種方式都親測(cè)可用,實(shí)際使用時(shí)應(yīng)采用第三種方法,更有效率。
方法一:
先說(shuō)重點(diǎn):
1)RXNE,表示一個(gè)字節(jié)產(chǎn)生一次中斷,這里要著重說(shuō)明一下,是一個(gè)字節(jié)。原因是DR寄存器是32位,有效位是8位。比如串口發(fā)送的字符或字符串,其對(duì)應(yīng)的ASICC碼的二進(jìn)制都是8位的,所以不管是發(fā)送“1”,都是8位
2)IDLE,表示DR先有數(shù)據(jù)(可以是一個(gè)字節(jié)的數(shù)據(jù),也可以是N個(gè)字節(jié)的數(shù)據(jù)連續(xù)發(fā)過(guò)來(lái)),然后空閑了一個(gè)字節(jié)的時(shí)間,就會(huì)產(chǎn)生中斷。
如果要讓串口發(fā)送不定長(zhǎng)度的的數(shù)據(jù),則先通過(guò)RXNE,把數(shù)據(jù)一個(gè)字節(jié)一個(gè)字節(jié)地存起來(lái),當(dāng)一串信息發(fā)送完時(shí),因?yàn)橐nD一下,則會(huì)產(chǎn)生IDLE中斷,利用IDLE中斷,表示完成接收數(shù)據(jù),具體方法如下:
先定義一個(gè)數(shù)組和數(shù)組長(zhǎng)度:
uint8_t Rx1_Buff[50]={'0'};
uint8_t rx_buffer_len=0;
方法二:
使用STM32串口中斷實(shí)現(xiàn)非阻塞方式接收不定長(zhǎng)數(shù)據(jù)
一、簡(jiǎn)介
1.1、開發(fā)環(huán)境
STM32CubeIDE V1.9。
1.2、實(shí)現(xiàn)功能
使用STM32的串口1,接收不定長(zhǎng)數(shù)據(jù),并返回接收數(shù)據(jù)
二、步驟解析
2.1、配置串口
打開“Device Configuration Tool”(即STM32CubeMX),配置串口1。
注:一定要在“NVIC Settings”欄,勾選“USART1 global interrupt”打開串口中斷。
2.2、初始化
初始化過(guò)程中,調(diào)用函數(shù)“HAL_UARTEx_ReceiveToIdle_IT”。
HAL庫(kù)中對(duì)該函數(shù)的定義:
HAL_StatusTypeDef HAL_UARTEx_ReceiveToIdle_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)。
huart:定義串口,一般填寫 &huartx(x為串口號(hào),取1、2、3……)。本案例使用串口1,則填寫&huart1;
pData:接收數(shù)據(jù)存放的首地址,一般填寫一維數(shù)組名;
Size:定義接收的字節(jié)長(zhǎng)度,填寫接收數(shù)據(jù)的最大字節(jié)數(shù)。
2.3、回調(diào)函數(shù)
調(diào)用函數(shù)“HAL_UARTEx_ReceiveToIdle_IT”后,當(dāng)接收長(zhǎng)度等于Size,或者串口接收數(shù)據(jù)過(guò)程中產(chǎn)生空閑時(shí),會(huì)執(zhí)行回調(diào)函數(shù)"HAL_UARTEx_RxEventCallback"。
HAL庫(kù)中對(duì)該函數(shù)的定義:
__weak void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
huart:回調(diào)串口號(hào);
Size:實(shí)際接收的字節(jié)長(zhǎng)度。
注:該回調(diào)函數(shù)為空的弱函數(shù),函數(shù)主體需自己重新定義。
三、實(shí)例
從串口1接收不定長(zhǎng)數(shù)據(jù),存放在數(shù)組array[50]中,并返回所接收的數(shù)據(jù)。
3.1、定義
定義一維數(shù)組array:
uint8_t array[50];
3.2、主函數(shù)
在主函數(shù)的初始化過(guò)程,調(diào)用函數(shù)“HAL_UARTEx_ReceiveToIdle_IT”:
void main()
{
HAL_UARTEx_ReceiveToIdle_IT(&huart1, array, 50); //初始化開啟串口接收
while(1);
}
3.3、重新定義回調(diào)函數(shù)
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); //把接收到的數(shù)據(jù)發(fā)送出去
memset(Rx1_Buff,0,strlen((const char*)Rx1_Buff));//清空數(shù)組
HAL_UARTEx_ReceiveToIdle_IT(&huart1, array, 50) ; //重新開啟串口接收
}
}
初始化打開串口接收中斷,當(dāng)串口接收滿50字節(jié),或串口產(chǎn)生空閑時(shí),會(huì)執(zhí)行回調(diào)函數(shù)?;卣{(diào)函數(shù)里判斷串口后正確后,執(zhí)行對(duì)應(yīng)的功能函數(shù),并再次開啟串口接收中斷。
HAL_UARTEx_ReceiveToIdle_IT(),其實(shí)是實(shí)現(xiàn)RXNE和IDLE中斷,和方式一是一樣的原理
以上兩種方式,每一個(gè)字符都會(huì)中斷一次,效率不高,采用DMA接收的方式會(huì)更高一點(diǎn),DMA空閑中斷的方式見這份文檔《STM32F103用hal庫(kù)使用DMA+串口空閑中斷接收數(shù)據(jù)_L》,或下方第三種方式.
方法三:
1.CUBE的設(shè)置就不講了,CUBE設(shè)置完后,就進(jìn)行第二步。
2.生成代碼后,在main函數(shù)中打開串口空閑中斷,單個(gè)字符中斷用于接收用的,因?yàn)槲疫@例程作用是串口1發(fā)送數(shù)據(jù)并把數(shù)據(jù)發(fā)送回來(lái)。
3.在串口中斷中添加如下:
4.DMA發(fā)送完后,要清除數(shù)組Rx1_Buff里的數(shù)據(jù),不然下次接收的數(shù)據(jù)會(huì)重復(fù)覆蓋,有可能覆蓋不全。其實(shí)HAL_UART_Transmit_DMA(), 這個(gè)函數(shù)接收完會(huì)調(diào)用回調(diào)函數(shù)。
HAL_UART_Transmit_DMA() - >
UART_DMATransmitCplt - >
HAL_UART_TxCpltCallback() - >
__weak void HAL_UART_TxCpltCallback()
5.構(gòu)造HAL_UART_TxCpltCallback()函數(shù),不需要添加申明
-
STM32
+關(guān)注
關(guān)注
2293文章
11032瀏覽量
365060 -
中斷
+關(guān)注
關(guān)注
5文章
905瀏覽量
42812 -
串口
+關(guān)注
關(guān)注
15文章
1588瀏覽量
79957 -
字符串
+關(guān)注
關(guān)注
1文章
590瀏覽量
22293
發(fā)布評(píng)論請(qǐng)先 登錄
CW32L083串口中斷+定時(shí)器實(shí)現(xiàn)不定長(zhǎng)數(shù)據(jù)接收

如何使用DMA進(jìn)行USART不定長(zhǎng)度接收

用串口DMA傳輸不定長(zhǎng)度包的方式
STM32單片機(jī)的接收不定長(zhǎng)度字節(jié)數(shù)據(jù)的方法
stm32串口是如何實(shí)現(xiàn)接收不定長(zhǎng)度數(shù)據(jù)的呢
不定長(zhǎng)數(shù)據(jù)接收的原理是什么?怎么實(shí)現(xiàn)串口數(shù)據(jù)的不定長(zhǎng)接收?
STM32 HAL DMA串口接收不定長(zhǎng)度的實(shí)現(xiàn)方法
STM32串口接收不定長(zhǎng)數(shù)據(jù)的實(shí)現(xiàn)方法
HAL庫(kù)下串口接收不定長(zhǎng)數(shù)據(jù)的方法
STM32串口接收不定長(zhǎng)數(shù)據(jù)的幾種方法

stm32 串口接收不定長(zhǎng)度數(shù)據(jù)及黏包處理 + 串口DMA接收

STM32之串口DMA接收不定長(zhǎng)數(shù)據(jù)

STM32CubeMX之串口接收不定長(zhǎng)數(shù)據(jù)

評(píng)論