我們使用輪詢方式接收計(jì)算機(jī)端發(fā)送過(guò)來(lái)的數(shù)據(jù),但是這種方式需要一直在循環(huán)語(yǔ)句中查詢是否有數(shù)據(jù)發(fā)送過(guò)來(lái),這種方式效率非常低。
為了提高處理器的執(zhí)行效率,我們使用中斷方式接收計(jì)算機(jī)端發(fā)送過(guò)來(lái)的數(shù)據(jù),當(dāng)計(jì)算機(jī)端有數(shù)據(jù)發(fā)送過(guò)來(lái)時(shí),會(huì)觸發(fā)STM32的串口中斷,并執(zhí)行中斷回調(diào)函數(shù)。
在這種方式中,不用反復(fù)去查詢串口是否接收到數(shù)據(jù),所以效率非常高,實(shí)時(shí)性也更好。
HAL庫(kù)的中斷接收函數(shù)和中斷發(fā)送函數(shù)分別為HAL_UART_Receive_IT和HAL_UART_Transmit_IT。下面我們對(duì)常用的中斷方式接收函數(shù)HAL_UART_Receive_IT進(jìn)行重點(diǎn)介紹。
HAL_UART_Receive_IT函數(shù)的原型如下
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
它的三個(gè)參數(shù)分別為串口句柄,接收到的數(shù)據(jù)存儲(chǔ)的目標(biāo)地址和接收多少個(gè)字節(jié)的數(shù)據(jù)。
打開(kāi)函數(shù)HAL_UART_Receive_IT,可以看到它的定義如圖8-24所示。
圖8-24 函數(shù)HAL_UART_Receive_IT內(nèi)容示意圖
可以看到,函數(shù)HAL_UART_Receive_IT并沒(méi)有實(shí)際進(jìn)行數(shù)據(jù)接收,而只是對(duì)串口句柄huart的接收信息進(jìn)行初始化和使能相關(guān)中斷,這些使能中斷的最后一個(gè)即為使能串口接收中斷。
由于函數(shù)HAL_UART_Receive_IT本質(zhì)上是對(duì)串口的中斷進(jìn)行使能,所以和設(shè)置系統(tǒng)時(shí)鐘一起放置于main函數(shù)的系統(tǒng)初始化代碼中,而不是放在while循環(huán)中反復(fù)查詢、執(zhí)行。
為了便于對(duì)比,圖8-25給出了輪詢方式接收函數(shù)的定義。
圖8-25 輪詢方式接收函數(shù)HAL_UART_Receive定義示意圖
由輪詢方式接收函數(shù)的定義可以看到,函數(shù)HAL_UART_Receive是確實(shí)在接收數(shù)據(jù)并保存到參數(shù)pData指向的存儲(chǔ)單元中。這點(diǎn)和中斷方式接收函數(shù)完全不同,讀者千萬(wàn)不要被函數(shù)名迷惑了。
那中斷方式是如何接收數(shù)據(jù)的呢?下面我們來(lái)介紹中斷方式接收數(shù)據(jù)的步驟。
(1)使能接收中斷。
(2)接收到數(shù)據(jù)后觸發(fā)接收數(shù)據(jù)中斷,此時(shí)程序按以下步驟執(zhí)行。
①到中斷向量表中找到USART1的中斷入口,如圖8-26所示。
圖8-26 USART1中斷函數(shù)入口
②執(zhí)行中斷函數(shù)USART1_IRQHandler,在該中斷函數(shù)中調(diào)用HAL庫(kù)的USART1中斷函數(shù),如圖8-27所示。
圖8-27 USART的中斷函數(shù)的內(nèi)容
注意,該函數(shù)需要用戶自己實(shí)現(xiàn),如果用戶使用CubeMX生成工程,則工程會(huì)自動(dòng)在輸出文件stm32f4xx_it.c中生成該函數(shù)。
③執(zhí)行HAL庫(kù)的中斷函數(shù)HAL_UART_IRQHandler。在該函數(shù)中先判斷是否存在接收錯(cuò)誤,如果不存在,則執(zhí)行函數(shù)UART_Receive_IT(),如圖8-28所示。
圖8-28 函數(shù)HAL_UART_IRQHandler定義示意圖
④執(zhí)行接收完成中斷函數(shù)UART_Receive_IT(),如圖8-29所示。
圖8-29 函數(shù)UART_Receive_IT()定義示意圖
由圖可見(jiàn),在該函數(shù)中首先判斷字長(zhǎng)是9位還是8位,如果是8位,則根據(jù)是否使能奇偶校驗(yàn)使用如下語(yǔ)句讀取數(shù)據(jù)(見(jiàn)圖8-29中的①):
if (huart- >Init.Parity == UART_PARITY_NONE) /* 如果沒(méi)有使能奇偶校驗(yàn),數(shù)據(jù)位為8位 */
{
*huart- >pRxBuffPtr++ = (uint8_t)(huart- >Instance- >DR & (uint8_t)0x00FF);
}
else /* 如果使能了奇偶校驗(yàn),數(shù)據(jù)位為7位 */
{
*huart- >pRxBuffPtr++ = (uint8_t)(huart- >Instance- >DR & (uint8_t)0x007F);
}
在上述程序段中,程序首先將接收到的數(shù)據(jù)保存到句柄huart的接收區(qū)緩沖指針pRxBuffPtr指向的存儲(chǔ)單元中,然后指針pRxBuffPtr的值加1,指向下一個(gè)存儲(chǔ)單元。
所以,在中斷方式接收中,數(shù)據(jù)的接收在中斷函數(shù)中完成。
讀到一個(gè)數(shù)據(jù)后,huart的接收計(jì)數(shù)變量RxXferCount的值減1,并判斷減到0了沒(méi)有,如果減到0了,說(shuō)明數(shù)據(jù)已經(jīng)接收完成,關(guān)閉串口中斷,如圖8-30中的②所示,接著執(zhí)行接收完成中斷回調(diào)函數(shù)HAL_UART_RxCpltCallback,如圖8-30中的③所示。
⑤執(zhí)行回調(diào)函數(shù)HAL_UART_RxCpltCallback。由于在步驟④中執(zhí)行函數(shù)UART_Receive_IT時(shí)已經(jīng)關(guān)閉了串口的接收中斷,所以如果要繼續(xù)采用中斷方式接收數(shù)據(jù),則需要在回調(diào)函數(shù)中再次調(diào)用函數(shù)HAL_UART_Receive_IT使能串口中斷。
-
接收機(jī)
+關(guān)注
關(guān)注
8文章
1177瀏覽量
53377 -
STM32
+關(guān)注
關(guān)注
2264文章
10854瀏覽量
354297 -
串口中斷
+關(guān)注
關(guān)注
0文章
64瀏覽量
13846 -
系統(tǒng)時(shí)鐘
+關(guān)注
關(guān)注
1文章
30瀏覽量
9282 -
HAL庫(kù)
+關(guān)注
關(guān)注
1文章
114瀏覽量
6144
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論