0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

HAL庫中STM32F7的串口中斷響應(yīng)過程簡析

冬至子 ? 來源:聊點(diǎn)嵌入式 ? 作者:聊點(diǎn)嵌入式 ? 2023-11-06 15:21 ? 次閱讀

中斷是計(jì)算機(jī)系統(tǒng)最重要的組成機(jī)制之一,在ARM架構(gòu)里,通常稱為異常(Exception),在文檔里是這么說的:

An exception can be caused by the execution of an exception generating instruction or triggered as a response to a system behavior such as an interrupt, memory management protection violation, alignment or bus fault, or a debug event.

意思是異常是由某些能夠生成異常的指令(例如:SVC)或者是響應(yīng)外部中斷、內(nèi)存沖突、對(duì)齊或總線錯(cuò)誤、調(diào)試等系統(tǒng)行為導(dǎo)致的。

所以,在ARM架構(gòu)里,中斷指的是外設(shè)產(chǎn)生的需要系統(tǒng)優(yōu)先處理的事件,是異常的一種。異常由NVIC(Nested Vectored Interrupt Controller)模塊統(tǒng)一管理。

關(guān)于中斷和異常的工作原理,在ARM架構(gòu)下的工作方式等這里不做展開,需要復(fù)習(xí)這些知識(shí)點(diǎn)的建議找ARM內(nèi)核架構(gòu)的文檔去看。這里主要以HAL庫中STM32F7的串口中斷響應(yīng)過程為例,來看一下中斷到底是怎么工作的,為什么能夠提高系統(tǒng)運(yùn)行效率。

1. CubeMX配置串口1工作在中斷模式下

還是之前的點(diǎn)燈例程,按下圖配置串口1,重新生成代碼。

圖片

需要說明的是,ARM的中斷優(yōu)先級(jí)分為搶占式優(yōu)先級(jí)和子優(yōu)先級(jí),STM32采用4個(gè)優(yōu)先級(jí)位,也即4個(gè)優(yōu)先級(jí)位都為搶占式優(yōu)先級(jí)(FreeRTOS就是這樣處理的)時(shí),總共有16個(gè)優(yōu)先級(jí)別,數(shù)值越小優(yōu)先級(jí)越高。這里默認(rèn)就行。

2. 生成代碼分析

在生成的工程里Core->Src目錄下,會(huì)多一個(gè)usart.c的源文件,里邊有下面三個(gè)函數(shù),把代碼注釋寫出來:

//串口1初始化函數(shù)
void MX_USART1_UART_Init(void)
{   
    //設(shè)置串口1工作參數(shù):115200bps,1個(gè)起始位,8個(gè)數(shù)據(jù)位,1個(gè)停止位,無校驗(yàn)位
    //調(diào)用HAL的串口初始化函數(shù)HAL_UART_Init(&huart1)
}


//串口的MSP(MCU Support Package)初始化,這是與硬件相關(guān)的初始化,單獨(dú)提出來,方便移植
//這是一個(gè)回調(diào)函數(shù),會(huì)被HAL的串口初始化函數(shù)調(diào)用
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
    //串口1相關(guān)時(shí)鐘使能
    //串口1相關(guān)GPIO初始化
    //設(shè)置NVIC,使能串口1中斷
}


//串口MSP的反初始化,調(diào)用這個(gè)函數(shù)會(huì)使串口失能,相關(guān)的時(shí)鐘、引腳和中斷恢復(fù)到復(fù)位狀態(tài)
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
    //失能串口1時(shí)鐘
    //失能串口1引腳
    //失能串口1中斷
}

在main.c中調(diào)用串口1初始化函數(shù),程序運(yùn)行時(shí)完成串口1的初始化。

另外,在stm32f7xx.c中,增加了下面的函數(shù):

void USART1_IRQHandler(void)
{
  HAL_UART_IRQHandler(&huart1);
}

這是串口1 的中斷服務(wù)程序,通過調(diào)用HAL庫的串口中斷處理程序HAL_UART_IRQHandler完成中斷響應(yīng)。這個(gè)中斷服務(wù)程序完全可以針對(duì)該串口完成的具體功能自己去寫,效率更高。調(diào)用HAL庫完成中斷處理更簡單方便,可移植性更好。

另外要注意的是,調(diào)用HAL庫完成中斷處理的話,還需要自己重寫中斷處理的回調(diào)函數(shù),HAL庫里的回調(diào)函數(shù)是一個(gè)弱函數(shù),本身并沒有實(shí)現(xiàn)任何功能。這也很好理解,每個(gè)應(yīng)用的需求都不同,不可能寫出一個(gè)通用的中斷處理函數(shù)。而且有一個(gè)回調(diào)用的弱函數(shù)在,就算是用戶程序沒有實(shí)現(xiàn),也不會(huì)導(dǎo)致程序出錯(cuò)。

3. 添加代碼實(shí)現(xiàn)功能

假設(shè)要實(shí)現(xiàn)一個(gè)最簡單的情況,串口每接收到一個(gè)字節(jié)的數(shù)據(jù),非n則計(jì)數(shù)器RxCounter加1,否則計(jì)數(shù)器清零。為了方便觀察,我們按下邊這樣實(shí)現(xiàn)。

在main.c中定義兩個(gè)全局變量,并申明usart.c中定義的串口1的句柄,如下:

uint8_t* Uart1RxBuff = 0;
uint8_t RxCounter = 0;


extern UART_HandleTypeDef huart1;

并在main函數(shù)的while循環(huán)前加如下代碼,實(shí)現(xiàn)串口1每接收一個(gè)字節(jié)產(chǎn)生中斷,接收的數(shù)據(jù)存放在Uart1RxBuff中。

if (HAL_UART_Receive_IT(&huart1, Uart1RxBuff, 1) != HAL_OK)
{
    Error_Handler();
}

在usart.c中,聲明main.c中定義的兩個(gè)全局變量:

extern uint8_t* Uart1RxBuff;
extern uint8_t RxCounter;

并重新實(shí)現(xiàn)接收中斷的回調(diào)函數(shù)如下:

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    /*判斷是否是串口1中斷*/
    if(huart- >Instance == USART1)
    {
        /*判斷接收的數(shù)據(jù)是否為n*/
        if(*Uart1RxBuff != 'n')
        {
             RxCounter ++;
        }
        else
        {
             RxCounter = 0;
        }
        /*重新使能串口1接收中斷*/
        HAL_UART_Receive_IT(&huart1, Uart1RxBuff, 1);
     }
}

而HAL庫中的接收回調(diào)弱函數(shù)的代碼如下:

__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);


  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_UART_RxCpltCallback can be implemented in the user file.
   */
}

另外, UNUSED是一個(gè)宏,定義如下:

#define UNUSED(X) (void)X      /* To avoid gcc/g++ warnings */

好了,到此就完成了一個(gè)簡單的串口接收中斷處理的任務(wù)。能夠判斷接收的有效字符數(shù)。

4. 中斷響應(yīng)過程分析

串口1接收到一個(gè)字節(jié)的數(shù)據(jù)后,USART_ISR寄存器的RXNE位置1,如果對(duì)應(yīng)的接收中斷使能的話,則會(huì)向NVIC產(chǎn)生一個(gè)中斷請(qǐng)求,NVIC根據(jù)中斷源(USART1)去中斷向量表相應(yīng)的地址上找到中斷向量(中斷服務(wù)程序的入口地址),執(zhí)行串口1的中斷服務(wù)程序。

圖片

由上圖可以看出,USART1的中斷向量偏移地址為0x000000D4,默認(rèn)是從零地址開始偏移,所以實(shí)際地址也為0x000000D4。中斷向量表這個(gè)地址上存儲(chǔ)的中斷向量是中斷服務(wù)程序USART1_IRQHandler的入口地址??催^之前文章關(guān)于啟動(dòng)代碼的分析就應(yīng)該知道,在啟動(dòng)代碼里定義好了中斷向量表,中斷向量地址是由鏈接器生成符號(hào)地址后裝入中斷向量表的。

那么接下來的調(diào)用過程是這樣的:

圖片

5. 小結(jié)

基于HAL庫的串口中斷的基本流程就是這樣,但是并沒有深入去查看相關(guān)庫函數(shù)的實(shí)現(xiàn)過程,想全面掌握的話還需要去仔細(xì)閱讀庫函數(shù)源碼。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • FreeRTOS
    +關(guān)注

    關(guān)注

    12

    文章

    483

    瀏覽量

    61915
  • 串口中斷
    +關(guān)注

    關(guān)注

    0

    文章

    64

    瀏覽量

    13845
  • STM32F7
    +關(guān)注

    關(guān)注

    1

    文章

    48

    瀏覽量

    8930
  • 中斷響應(yīng)
    +關(guān)注

    關(guān)注

    0

    文章

    11

    瀏覽量

    2942
  • HAL庫
    +關(guān)注

    關(guān)注

    1

    文章

    114

    瀏覽量

    6144
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    STM32f405 HAL串口中斷接受上溢錯(cuò)誤(ORE)問題

    STM32f405 HAL串口中斷接受上溢錯(cuò)誤(ORE)問題,在哪可以找到官方的修改和訂正解決方案。
    發(fā)表于 12-30 16:46

    STM32 HAL串口中斷通訊【任意長度 不丟幀】精選資料分享

    基于HAL的多串口通信入門,多串口中斷通信,可以發(fā)任意字節(jié)數(shù)據(jù),用的STM32F302CBTx,STM
    發(fā)表于 08-16 06:30

    STM32HAL開發(fā)】CubeMX配置HAL,不進(jìn)串口中斷的問題 精選資料分享

    STM32HAL開發(fā)】串口中斷開發(fā)環(huán)境在main.c添加代碼(1/2)在stm32f4xx_it.c添加代碼(2/2)注意附代碼開發(fā)環(huán)
    發(fā)表于 08-16 07:00

    HAL串口中斷接收

    [STM32系列]一、HAL串口中斷接收1、前言2、回調(diào)函數(shù)3、HAL
    發(fā)表于 08-16 08:13

    STM32F0 HAL串口中斷調(diào)用順序是什么樣的?

    STM32F0 HAL串口中斷調(diào)用順序是什么樣的?
    發(fā)表于 12-08 07:59

    STM32F7的技術(shù)介紹

    2015年 STM32 Roadshow: STM32F7技術(shù)詳解
    的頭像 發(fā)表于 07-02 03:29 ?8510次閱讀

    STM32 串口使用IDLE中斷+DMA接收(HAL庫函數(shù))

    STM32 串口使用IDLE中斷+DMA接收(HAL庫函數(shù))一、開發(fā)環(huán)境單片機(jī)型號(hào):STM32H743IIT6工程配置環(huán)境:
    發(fā)表于 12-02 21:06 ?40次下載
    <b class='flag-5'>STM32</b> <b class='flag-5'>串口</b>使用IDLE<b class='flag-5'>中斷</b>+DMA接收(<b class='flag-5'>HAL</b>庫函數(shù))

    STM32H7 串口 空閑中斷 任意長接收 Hal IDLE

    HAL,在整個(gè)接收過程中,是沒有用到串口的接收空閑中斷,它的處理有三種,分別是輪詢,接收完成中斷
    發(fā)表于 12-04 17:21 ?17次下載
    <b class='flag-5'>STM32H7</b>  <b class='flag-5'>串口</b>  空閑<b class='flag-5'>中斷</b>   任意長接收  <b class='flag-5'>Hal</b><b class='flag-5'>庫</b>  IDLE

    STM32 HAL串口空閑中斷+DMA 實(shí)現(xiàn)串口數(shù)據(jù)的不定長接收

    本文開發(fā)環(huán)境:MCU型號(hào):STM32F051R8T6IDE環(huán)境: MDK 5.25代碼生成工具:STM32CubeMx 5.2.0HAL版本:v1.9.0(
    發(fā)表于 12-06 18:36 ?26次下載
    <b class='flag-5'>STM32</b> <b class='flag-5'>HAL</b><b class='flag-5'>庫</b><b class='flag-5'>中</b><b class='flag-5'>串口</b>空閑<b class='flag-5'>中斷</b>+DMA 實(shí)現(xiàn)<b class='flag-5'>串口</b>數(shù)據(jù)的不定長接收

    STM32 的 USART 串口中斷通訊---輸出 hello windows(實(shí)現(xiàn) STM32 與主機(jī)的通訊)

    文章內(nèi)容:學(xué)習(xí)stm32中斷、DMA通信原理和編程方法。使用stm32tubemx和HAL分別完成以下編程練習(xí):采用
    發(fā)表于 12-06 20:51 ?11次下載
    <b class='flag-5'>STM32</b> 的 USART <b class='flag-5'>串口中斷</b>通訊---輸出 hello windows(實(shí)現(xiàn) <b class='flag-5'>STM32</b> 與主機(jī)的通訊)

    STM32使用CubeMAX配置的串口中斷接收方法

    STM32使用CubeMAX配置的串口中斷接收方法目錄1.定位串口中斷發(fā)生的地方2.處理串口中斷接收的流程是:(1)初始化串口(2)在mai
    發(fā)表于 12-14 18:45 ?28次下載
    <b class='flag-5'>STM32</b>使用CubeMAX配置的<b class='flag-5'>串口中斷</b>接收方法

    STM32f429外部中斷配置解析基于HAL

    STM32f429外部中斷配置解析基于HAL
    發(fā)表于 12-16 16:58 ?9次下載
    <b class='flag-5'>STM32f</b>429外部<b class='flag-5'>中斷</b>配置解析基于<b class='flag-5'>HAL</b><b class='flag-5'>庫</b>

    STM32串口中斷應(yīng)用實(shí)例

    本文將介紹如何使用STM32F4的串口接收中斷,通過串口助手模擬上位機(jī)發(fā)送指令、STM32F4串口中斷
    的頭像 發(fā)表于 04-20 11:45 ?2244次閱讀
    <b class='flag-5'>STM32</b><b class='flag-5'>串口中斷</b>應(yīng)用實(shí)例

    STM32 HAL串口收發(fā)是如何使用的?

    的一種,它提供了一種簡單易用的方法來使用STM32的各種外設(shè)。 本文將詳細(xì)介紹如何使用STM32 HAL來進(jìn)行
    的頭像 發(fā)表于 10-26 17:42 ?1153次閱讀

    stm32f1如何將外部中斷關(guān)掉hal

    Layer)來簡化芯片和外設(shè)的驅(qū)動(dòng)開發(fā)。在STM32F1,外部中斷的關(guān)閉是通過HAL的相
    的頭像 發(fā)表于 12-22 13:52 ?3098次閱讀