在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

【GD32 MCU 入門教程】GD32 MCU 常見外設介紹(3)NVIC 介紹

聚沃科技 ? 2024-08-12 10:02 ? 次閱讀

NVIC(Nested vectored interrupt controller,嵌套向量中斷控制器)是Cortex-M處理器的一部分,它是可編程的,且寄存器位于存儲器映射的系統控制空間(SCS)。NVIC與內核相輔相成,共同完成對中斷的響應。本章將介紹中斷的優先級設置、如何定義中斷函數名稱、中斷向量如何偏移。有關NVIC的更多知識,請見《ARM Coretex-M3權威指南》。

3.1.優先級的設置

在Cortex-M中,優先級對于異常來說很關鍵的,它會影響一個異常是否能被響應,以及何時可以響應。優先級的數值越小,則優先級越高。Cortex-M支持中斷嵌套,使得高優先級異常會搶占低優先級異常。有3個系統異常:復位,NMI以及硬fault,它們有固定的優先級,并且它們的優先級號是負數,從而高于所有其它異常。所有其它異常的優先級則都是可編程的,但不能編程為負數。

原則上,Cortex-M支持3 個固定的高優先級和多達256 級的可編程優先級,并且支持128級搶占。但是,絕大多數CM3芯片都會精簡設計,以致實際上支持的優先級數會更少,如8級,16級,32級 等。它們在設計時會裁掉表達優先級的幾個低端有效位,以達到減少優先級數的目的。

舉例來說,如果只使用了4位來表達優先級,則優先級配置寄存器的結構如圖所示。

使用 4bit 表達優先級

輸入圖片說明

GD32Fxxx系列、GD32E50x系列、GD32H7xx系 列、GD32A5x系列、GD32W51x系列和GD32VF103、GD32E10X系列使用了4位來表達優先級。GD32E23x和GD32L23x使用的是M23內核,只使用了2位表達優先級。

說明:GD32Fxxx系列是指:GD32F10x、GD32F1x0、GD32F20x、GD32F30x、GD32F3x0、GD32F40x、GD32F4xx。

用于表達優先級的這4bit,又被分組成搶占優先級和子優先級。如果有多個中斷同時響應,搶占優先級高的就會搶占搶占優先級低的優先得到執行。如果搶占優先級相同,就比較子優先級。如果搶占優先級和子優先級都相同的話,就比較他們的硬件中斷編號,編號越小,優先級越高。

GD32Fxxx系列、GD32E10x系列、GD32E50x系列、GD32H7xx系列、GD32A5x系列、GD32W51X系列和GD32VF103和GD32E10x系列可以設置搶占優先級和子優先級的等級,GD32E23x和GD32L23x系列沒有搶占優先級和子優先級的說法,只可以設置優先級。

下面以GD32F10x舉例說明如何設置優先級位數以及搶占優先級和子優先級的等級。在GD32f10x_misc.c文件中,nvic_priority_group_set函數用于設置多少位用于搶占優先級,多少位用于子優先級;nvic_irq_enable函數用于設置相應中斷的搶占優先級和子優先級的等級。比如現在要設置SPI0的中斷,其搶占優先級和子優先級的位數均為2,搶占優先級的等級為0,子優先級 的等級為1,那么代碼如代碼清單SPI0中斷優先級設置所示。

nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); nvic_irq_enable(SPI0_IRQn,0,1);

有關這兩個函數的原型以及函數參數的說明,請見代碼清單nvic_priority_group_set函數原型、參數nvic_prigroup說明表、代碼清單nvic_irq_enable函數原型、nvic_irq_enable()函數的參數說明表。

代碼清單nvic_priority_group_set 函數原型

void nvic_priority_group_set(uint32_t nvic_prigroup) { /* set the priority group value */ SCB->AIRCR = NVIC_AIRCR_VECTKEY_MASK | nvic_prigroup; }

參數 nvic_prigroup 說明表

輸入圖片說明

代碼清單nvic_irq_enable 函數原型

void nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_pre_priority, uint8_t nvic_irq_sub_priority) { uint32_t temp_priority = 0x00U, temp_pre = 0x00U, temp_sub = 0x00U; /* use the priority group value to get the temp_pre and the temp_sub */ switch ((SCB->AIRCR) & (uint32_t)0x700U) { case NVIC_PRIGROUP_PRE0_SUB4: temp_pre = 0U; temp_sub = 0x4U; break; case NVIC_PRIGROUP_PRE1_SUB3: temp_pre = 1U; temp_sub = 0x3U; break; case NVIC_PRIGROUP_PRE2_SUB2: temp_pre = 2U; temp_sub = 0x2U; break; case NVIC_PRIGROUP_PRE3_SUB1: temp_pre = 3U; temp_sub = 0x1U; break; case NVIC_PRIGROUP_PRE4_SUB0: temp_pre = 4U; temp_sub = 0x0U; break; default: nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2); temp_pre = 2U; temp_sub = 0x2U; break; } /* get the temp_priority to fill the NVIC->IP register */ temp_priority = (uint32_t)nvic_irq_pre_priority << (0x4U - temp_pre); temp_priority |= nvic_irq_sub_priority &(0x0FU >> (0x4U - temp_sub)); temp_priority = temp_priority << 0x04U; NVIC->IP[nvic_irq] = (uint8_t)temp_priority; /* enable the selected IRQ */ NVIC->ISER[nvic_irq >> 0x05U] = (uint32_t)0x01U << (nvic_irq & (uint8_t)0x1FU); }

nvic_irq_enable()函數的參數說明表

輸入圖片說明

參數nvic_irq是一個枚舉變量,它定義了每一個中斷的編號,具體定義在gd32f10x.h文件中,如代碼清單中斷號定義所示。

typedef enum IRQn { /* Cortex-M3 processor exceptions numbers */ NonMaskableInt_IRQn = -14, /*!< 2 non maskable interrupt */ MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 memory management interrupt */ BusFault_IRQn = -11, /*!< 5 Cortex-M3 bus fault interrupt */ UsageFault_IRQn = -10, /*!< 6 Cortex-M3 usage fault interrupt */ SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV call interrupt */ DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 debug monitor interrupt */ PendSV_IRQn = -2, /*!< 14 Cortex-M3 pend SV interrupt */ SysTick_IRQn = -1, /*!< 15 Cortex-M3 system tick interrupt */ /* interruput numbers */ WWDGT_IRQn = 0, /*!< window watchDog timer interrupt */ LVD_IRQn = 1, /*!< LVD through EXTI line detect interrupt */ TAMPER_IRQn = 2, /*!< tamper through EXTI line detect */ RTC_IRQn = 3, /*!< RTC through EXTI line interrupt */ FMC_IRQn = 4, /*!< FMC interrupt */ RCU_CTC_IRQn = 5, /*!< RCU and CTC interrupt */ EXTI0_IRQn = 6, /*!< EXTI line 0 interrupts */ EXTI1_IRQn = 7, /*!< EXTI line 1 interrupts */ EXTI2_IRQn = 8, /*!< EXTI line 2 interrupts */ EXTI3_IRQn = 9, /*!< EXTI line 3 interrupts */ EXTI4_IRQn = 10, /*!< EXTI line 4 interrupts */ DMA0_Channel0_IRQn = 11, /*!< DMA0 channel0 interrupt */ DMA0_Channel1_IRQn = 12, /*!< DMA0 channel1 interrupt */ DMA0_Channel2_IRQn = 13, /*!< DMA0 channel2 interrupt */ DMA0_Channel3_IRQn = 14, /*!< DMA0 channel3 interrupt */ DMA0_Channel4_IRQn = 15, /*!< DMA0 channel4 interrupt */ DMA0_Channel5_IRQn = 16, /*!< DMA0 channel5 interrupt */ DMA0_Channel6_IRQn = 17, /*!< DMA0 channel6 interrupt */ ADC0_1_IRQn = 18, /*!< ADC0 and ADC1 interrupt */ #ifdef GD32F10X_MD USBD_HP_CAN0_TX_IRQn = 19, /*!< CAN0 TX interrupts */ USBD_LP_CAN0_RX0_IRQn = 20, /*!< CAN0 RX0 interrupts */ CAN0_RX1_IRQn = 21, /*!< CAN0 RX1 interrupts */ CAN0_EWMC_IRQn = 22, /*!< CAN0 EWMC interrupts */ EXTI5_9_IRQn = 23, /*!< EXTI[9:5] interrupts */ TIMER0_BRK_IRQn = 24, /*!< TIMER0 break interrupts */ TIMER0_UP_IRQn = 25, /*!< TIMER0 update interrupts */ TIMER0_TRG_CMT_IRQn = 26, /*!< TIMER0 trigger and commutation interrupts */ TIMER0_Channel_IRQn = 27, /*!< TIMER0 channel capture compare interrupts */ TIMER1_IRQn = 28, /*!< TIMER1 interrupt */ TIMER2_IRQn = 29, /*!< TIMER2 interrupt */ TIMER3_IRQn = 30, /*!< TIMER3 interrupts */ I2C0_EV_IRQn = 31, /*!< I2C0 event interrupt */ I2C0_ER_IRQn = 32, /*!< I2C0 error interrupt */ I2C1_EV_IRQn = 33, /*!< I2C1 event interrupt */ I2C1_ER_IRQn = 34, /*!< I2C1 error interrupt */ SPI0_IRQn = 35, /*!< SPI0 interrupt */ SPI1_IRQn = 36, /*!< SPI1 interrupt */ USART0_IRQn = 37, /*!< USART0 interrupt */ USART1_IRQn = 38, /*!< USART1 interrupt */ USART2_IRQn = 39, /*!< USART2 interrupt */ EXTI10_15_IRQn = 40, /*!< EXTI[15:10] interrupts */ RTC_Alarm_IRQn = 41, /*!< RTC alarm interrupt */ USBD_WKUP_IRQn = 42, /*!< USBD Wakeup interrupt */ EXMC_IRQn = 48, /*!< EXMC global interrupt */ #endif /* GD32F10X_MD */ } IRQn_Type;

3.2.中斷服務函數的命名

上一小節介紹了如何設置中斷的優先級,那么中斷服務函數如何命名和使用呢? 本小結將介紹這方面的內容。

下面以GD32F103C8T6產品為例,介紹如何命名中斷服務函數名。GD32F103C8T6的flash容量為64KB,屬于中密度產品,其對應的啟動文件為startup_gd32f10x_md.s。在該啟動文件中我們預先為每個中斷都命名了一個中斷服務函數,為的是初始化中斷向量表。實際的中斷服務函數里面的內容需要我們重新編寫,中斷服務函數我們統一寫在gd32f10x_it.c文件里。

需要注意的是,中斷服務函數的函數名必須和啟動文件里面的一樣,如果寫錯了,系統在中斷向量表中就會找不到中斷服務函數的入口,從而導致進不了中斷。為了避免該錯誤,簡單的處理方法是:打開startup_gd32f10x_md.s,找到需要的中斷服務函數名,復制該函數名到gd32f10x_it.c文 件 中 即 可 。 以 SPI0 中 斷 為 例 , 打 開 startup_gd32f10x_md.s , 找 到 SPI0_IRQHandler (SPI0_IRQHandler就是SPI0中斷服務函數的名稱),復制SPI0_IRQHandler到gd32f10x_it.c,修改其如代碼清單SPI0中斷服務函數所示即可。在該函數中就可以添加用戶所需的中斷服務 代碼了。

void SPI0_IRQHandler(void) { }

3.3.中斷向量偏移

當發生了異常并且要響應它時,Cortex-M 需要定位其處理例程的入口地址。這些入口地址存儲在所謂的“異常向量表”中。默認情況下,Cortex-M認為該表位于零地址處,且各向量占用4 節,因此每個表項占用4 字節,如上電后的向量表所示。

輸入圖片說明

因為地址0處應該存儲引導代碼,所以它通常是Flash或者是ROM器件,并且它們的值不得在運行時改變。然而,為了動態重分發中斷,Cortex-M允許向量表重定位,從其它地址處開始定位各異常向量。這些地址對應的區域可以是代碼區,但更多在RAM區。在RAM區就可以修改向量的入口地址了。為了實現這個功能,NVIC中有一個寄存器,稱為“向量表偏移量寄存器”(在地址0xE000_ED08處),通過修改它的值就能定位向量表。但必須注意的是:向量表的起始地址是有要求的:必須先求出系統中共有多少個向量,再把這個數字向上增大到是2 的整次冪,而起始地址必須對齊到后者的邊界上。例如,如果一共有32個中斷,則共有32+16(系統異常)=48個向量,向上增大到2 的整次冪后值為64,因此地址地址必須能被64*4=256 整除,從而合法的起始地址可以是:0x0, 0x100, 0x200等。向量表偏移量寄存器的定義如向量表偏移寄存器(VTOR)表所示。

輸入圖片說明

在gd32f10x_misc.c文件中,nvic_vector_table_set函數就是用來定義中斷向量偏移的,該函數的原型如代碼清單 0-16 nvic_vector_table_set函數原型所示,函數參數說明如參數說明表所示。

代碼清單nvic_vector_table_set 函數原型

void nvic_vector_table_set(uint32_t nvic_vict_tab, uint32_t offset) { SCB->VTOR = nvic_vict_tab | (offset & NVIC_VECTTAB_OFFSET_MASK); }

參數說明表

輸入圖片說明

下面舉例說明如何使用該函數。

在實際使用中,用戶會把FALSH分成BOOT區和APP區。BOOT區只用于代碼升級,實際應用的程序在APP區里運行。假設客戶把FLASH的第0頁(大小為1KB)作為BOOT區,該頁的地址范圍為0x08000000~0x080003FF,第2頁、第3頁作為APP區,地址范圍為0x08000800~0x08000FFF。執行完BOOT區的代碼后,程序會跳轉到0x08000800的地址開始執行APP程序。0x08000800相對于基地址0x08000000的偏移地址為0x800,此時調用nvic_vector_table_set函數的格式如代碼清單調用nvic_vector_table_set函數所示。

nvic_vector_table_set(NVIC_VECTTAB_FLASH, 0x800);

3.4.NVIC 使用注意事項

E23x 系列使用的是 M23 內核,該內核的 NVIC 使用 2bit 定義優先級,并且不分搶占優先級和子優先級。在 gd32e23x_misc.c 文件中,nvic_irq_enable(uint8_t nvic_irq, uint8_t nvic_irq_priority)函數用于設置優先級,該函數的參數說明如圖所示。

輸入圖片說明

教程GD32 MCU方案商聚沃科技原創發布,了解更多GD32 MCU教程,關注聚沃科技官網

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 單片機
    +關注

    關注

    6037

    文章

    44558

    瀏覽量

    635353
  • 嵌入式
    +關注

    關注

    5082

    文章

    19126

    瀏覽量

    305242
  • 開發板
    +關注

    關注

    25

    文章

    5050

    瀏覽量

    97483
  • GD32
    +關注

    關注

    7

    文章

    403

    瀏覽量

    24353
收藏 人收藏

    評論

    相關推薦

    GD32 MCU 入門教程GD32 MCU 常見外設介紹(12)FMC 模塊介紹

    閃存控制器(FMC),提供了片上閃存需要的所有功能。FMC 也提供了頁擦除,整片擦除,以及32 位整字或 16 位半字編程閃存等操作。 GD32 MCU 支持不同類型編程的具體說明如下表 GD32
    的頭像 發表于 08-21 09:56 ?1129次閱讀
    <b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門教程</b>】<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>常見外設</b><b class='flag-5'>介紹</b>(12)FMC 模塊<b class='flag-5'>介紹</b>

    GD32 MCU移植

    gd32是一款國產單片機。該芯片在很多方面和STM32有異曲同工之處。資料不是很多! GD32外設方面、和STM32沒有多大區別。 只是需要注意資源的引腳分配。雖然和STM32使用方式一樣、但是也存在
    發表于 03-23 13:40

    GD32MCU介紹

    其實兆芯的MCU為了兼容ST,外設的寄存器設計與ST保持一致了。比如GD32VF103或者GD32E103系列的USBFS這個外設,基本等同
    發表于 11-01 06:03

    GD32 MCU原理及固件庫開發指南》+讀后感

    。 第2章介紹GD32 MCU快速入門與開發平臺搭建的方法,包括對軟硬件開發平臺、調試工具、GD32 M
    發表于 06-06 21:52

    兆易創新GD32 MCU選型手冊,適用于GD32全系列MCU

    兆易創新GD32MCU選型手冊,適用于GD32全系列MCUGD32MCU選型手冊,適用于GD32全系列MCU
    發表于 10-19 17:26 ?49次下載

    你了解GD32 MCU的命名規則嗎

    下面為大家介紹GD32 MCU的通用命名規則,以GD32F303ZGT6為例,其中,GD32代表GD32
    的頭像 發表于 01-13 09:38 ?3648次閱讀
    你了解<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b>的命名規則嗎

    GD32 MCU的選項字節是什么?

    GD32 MCU的選項字節是什么,有什么功能呢?選項字節被誤篡改如何回復?
    的頭像 發表于 01-17 09:42 ?1387次閱讀
    <b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b>的選項字節是什么?

    不同型號的GD32 MCU如何區分?

    大家是否碰到過以下應用場景:同一套軟件代碼希望跑在不同型號的GD32 MCU中,但有些地方需要根據MCU型號進行調整?或者上位機或其他MCUGD3
    的頭像 發表于 01-27 09:32 ?1003次閱讀
    不同型號的<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b>如何區分?

    GD32 MCU 入門教程】一、GD32 MCU 開發環境搭建(1)使用Keil開發GD32

    GD32系列為通用型MCU,所以開發環境也可以使用通用型的IDE,目前使用較多的是KEIL、IAR、 GCC和Embedded Builder,客戶可以根據個人喜好來選擇相應的開發環境。
    的頭像 發表于 08-08 15:01 ?1202次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門教程</b>】一、<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> 開發環境搭建(1)使用Keil開發<b class='flag-5'>GD32</b>

    GD32 MCU 入門教程】一、GD32 MCU 開發環境搭建(2)使用 IAR 開發 GD32

    GD32系列為通用型MCU,所以開發環境也可以使用通用型的IDE,目前使用較多的是KEIL、IAR、 GCC和Embedded Builder,客戶可以根據個人喜好來選擇相應的開發環境。
    的頭像 發表于 08-08 15:40 ?701次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門教程</b>】一、<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> 開發環境搭建(2)使用 IAR 開發 <b class='flag-5'>GD32</b>

    GD32 MCU 入門教程】一、GD32 MCU 開發環境搭建(3)使用 Embedded Builder 開發 GD32

    GD32系列為通用型MCU,所以開發環境也可以使用通用型的IDE,目前使用較多的是KEIL、IAR、 GCC和Embedded Builder,客戶可以根據個人喜好來選擇相應的開發環境。
    的頭像 發表于 08-08 16:03 ?980次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門教程</b>】一、<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> 開發環境搭建(<b class='flag-5'>3</b>)使用 Embedded Builder 開發 <b class='flag-5'>GD32</b>

    GD32 MCU 入門教程】二、GD32 MCU 燒錄說明(1)ISP 燒錄

    ISP:In System Programing,在系統編程,通過MCU片內的引導程序進行Flash編程。 GD32片內有一個只讀信息塊,用于存放引導裝載程序,引導程序在MCU出廠前就會提前燒錄好
    的頭像 發表于 08-08 16:20 ?952次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門教程</b>】二、<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> 燒錄說明(1)ISP 燒錄

    GD32 MCU 入門教程GD32 MCU 常見外設介紹(14)RTC 模塊介紹

    GD32 MCU內部提供了一個RTC(實時時鐘)模塊,通過RTC可以實現日歷時鐘、鬧鐘等功能。RTC也可以用于深度睡眠或待機模式的低功耗喚醒。不同系列的GD32 MCU在RTC設計和功
    的頭像 發表于 08-23 09:18 ?474次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門教程</b>】<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>常見外設</b><b class='flag-5'>介紹</b>(14)RTC 模塊<b class='flag-5'>介紹</b>

    GD32 MCU 入門教程GD32 MCU FPU 使用方法

    GD32 MCU FPU 使用方法
    的頭像 發表于 08-25 09:24 ?601次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門教程</b>】<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> FPU 使用方法

    GD32 MCU入門教程GD32 MCU GPIO 結構與使用注意事項

    本文是專門為基于GD32 MCU開發的工程設計人員提供,主要介紹了GPIO的功能配置、內部結構以及在不同場景使用時的注意事項,旨在幫助GD32 MC
    的頭像 發表于 09-07 10:34 ?749次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b><b class='flag-5'>入門教程</b>】<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> GPIO 結構與使用注意事項
    主站蜘蛛池模板: 亚洲 欧美 日韩 丝袜 另类| 免费黄色三级网站| 成人宗合网| 国产精品第9页| 你懂的网址免费国产| 午夜在线观看免费视频| 欧美tube最新的69hd| 天堂影院在线| 高清色本在线www| 在线视频免费视频网站| 性欧美黑人xxxx| 成人免费观看一区二区| 日本人善交69xxx| 色人人| 性试验k8经典| 欧美做a欧美| 久久奈| 97精品久久天干天天蜜| 天堂资源在线观看| 在线天堂资源www中文在线| 69xxxxtube日本免费| 人成网站在线观看| 欧美成人午夜毛片免费影院 | 国产欧美亚洲精品第二区首页| 久久久精品免费| 婷婷五月情| 亚洲手机看片| 国产在线播放一区| 国产精品亚洲色图| 免费黄色大片视频| 欧美成人久久| 国产伦精品一区二区三区在线观看| 香蕉色网| 午夜视频福利在线观看| 国产三级在线| 91色视频网站| 国模张文静啪啪私拍337p| 国产免费人成在线视频视频| 69女porenhd| 激情深爱| h国产|