小白學習STM32(一)(基於cubemx+MDK)外部中斷

STM32的外部中斷

你好,這裏是月魂離人本小白的博客,本人最近在學習stm32(基於cubemx),寫下這篇博客希望自己能養成做筆記的習慣,同時也是鍛鍊自己寫博客的能力,希望大家不吝賜教,大佬們指出我的問題,hhhhh。本篇博客最後寫到了怎麼用jlink調試stm32以及其中的坑,希望能幫到需要的朋友。大家一起沖沖衝,我們開始吧!

外部中斷EXTI是STM32微處理器實時處理外部事件的一種機制,由於中斷請求主要來自GPIO端口的引腳,所以稱爲外部中斷。
STM32F013微處理器有19個能產生事件/中斷請求的邊沿檢測器,每個輸入線可以獨立地配置成輸入類型(脈衝或掛起)和對應的觸發事件(上升沿、下降沿或雙邊沿觸發),也可以獨立地屏蔽。
EXTI0~EXTI15:GPIO端口引腳。
EXTI16:PVD輸出,可編程電壓監測。
EXTI17:RTC鬧鐘。
EXTI18:USB喚醒。

EXIT0的連接引腳是: PA0~PG0,即每個端口組的0號引腳

NVIC

NVIC全稱Nested vectored interrupt controller,即嵌套向量中斷控制器,用來決定中斷的優先級。
NVIC在 ARM Conrtex-M 內核中,用一個 8 位的寄存器來配置,總共可以配置28=25628=256 2^8=25628=256級中斷,但是 ST 公司在生產 STM32 的時候,發現一個小小的單片機根本用不了這麼多,純屬浪費,所以將該寄存器的低 4 位全部置0,只使用高 4 位來配置,這樣一來 STM32 就只有24=1624=16 2^4=1624=16級中斷啦。
簡化爲16級中斷後,ST發現 STM32 內部這麼豐富的外設,還是不方便配置,乾脆人工給這4位來個分組,劃分出了5個分組:

優先級分組 搶佔優先級佔的位數 子優先級佔的位數
NVIC_PriorityGroup_0 0 bit 4 bit
NVIC_PriorityGroup_1 1 bit 3 bit
NVIC_PriorityGroup_2 2 bit 2 bit
NVIC_PriorityGroup_3 3 bit 1 bit
NVIC_PriorityGroup_4 4 bit 0 bit

再次強調一下,這5種中斷分組規則是人爲的,用哪種規則,之後設置具體的優先級時對應就行,STM32默認使用的規則是 NVIC_PriorityGroup_0 。
STM32 的CPU判斷優先級的方法如下:

先判斷搶佔優先級,數字越小,優先級越高;
若搶佔優先級相同,判斷子優先級,同樣,數字越小,優先級越高


基於STM32CubeMX的外部中斷設計步驟

  1. 在STM32CubeMX中指定引腳,配置中斷初始化參數, 選擇GPIO引腳的功能,設置中斷信號觸發條件,使能NVIC對應的中斷通道。

  2. 重寫該I/O引腳對應的中斷回調函數。


    具體實現步驟

    1. 新建工程

      • 搜索芯片型號
      • 選擇芯片
      • 創建工程
    2. 設置RCC

      • 1點擊RCC
      • 2高速時鐘(HSE)選擇外部晶振
      • 3軟件自動配置管腳
        在這裏插入圖片描述
    3. GPIO初始化

      LED :GPIO_OUTPUT(輸出模式)

      按鍵 :GPIO_EXITx(外部中斷模式)

      • 點擊對應管腳
      • 設置對應模式

      GPIO的各種模式設置

在這裏插入圖片描述

  + GPIO output level   引腳電平設置   高/低
  + GPIO mode   GPIO模式     推輓輸出/開漏輸出
  + GPIO Pull-up/Pull-dowm   上拉下拉電阻      上拉電阻/下拉電阻/無上拉或下拉
  + Maxinum output speed   引腳速度設置   低速/中速/高速
  + User Label    用戶標籤   給引腳設置名稱  如LED0

  ==GPIO_EXIT的六種模式==

在這裏插入圖片描述

  1. 設置NVIC(嵌套向量中斷控制器)

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳在這裏插入圖片描述

    • 1點擊NVIC2 勾選EXIT Line
    • 2 interrupt 和 EXIT Line[15:12] interrupt 使能中斷)
  2. 時鐘源設置
    在這裏插入圖片描述

    • 1選擇外部時鐘HSE 8MHz
    • 2PLL鎖相環倍頻9倍
    • 3系統時鐘來源選擇爲PLL
    • 4設置APB1分頻器爲 /2
  3. 項目文件設置


MDK外部中斷的設置

  • 隨後我們可以在stm32f1xx_it.c中看到我們所配置的中斷服務函數 並且可以看到gpio的初始化分到了gpio.c裏面,並且裏面有一個函數

  • HAL_GPIO_EXTI_IRQHandler();
    void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
    {  /* EXTI line interrupt detected */  
        if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)  
        {
         __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
         HAL_GPIO_EXTI_Callback(GPIO_Pin);  
        }
    }
    
  • 上述代碼中可以看到,在該函數中首先讀取了一下中斷寄存器,確認該中斷是否發生,確認之後又調用了一個函數,並將接收到的參數 GPIO_Pin 繼續傳給該函數

  • HAL_GPIO_EXTI_Callback()

  • 該函數稱爲EXIT中斷的回調函數,用來處理所有發生的EXIT中斷事件

  • 往下看這個回調函數定義的時候使用了__weak修飾符,使用_weak進行了弱定義,所以用戶可以再次定義該函數,並且這個note寫的非常清楚:這個函數不應該被改變,如果需要使用回調函數,請重新在用戶文件中實現該函數。我們需要重新定義這個函數。編輯在gpio.c(或者main.c也可以)

在這裏插入圖片描述

使用JLINK調試STM32

在這裏插入圖片描述

  1. 左邊第一個按鍵時進入調試
  2. 第二個是設置斷點
    在這裏插入圖片描述
    如圖所示,在中斷進入函數設置一個斷點

先選擇JATG模式進行調試,頻率爲5Mhz,後面設置斷點後進入調試,點擊RUN(F5),則會出現如圖所示的BUG
在這裏插入圖片描述
這是因爲在使用cubemx時沒有設置SYS導致的,SYS默認是(No Debug模式)

將其設置爲Serial Wire模式然後生成工程,進入調試後仍發現上述錯誤存在,我在網上查找後發現是在stm32f1xx_hal_msp.c第79行代碼,此代碼的存在禁用了jtag,將其註釋掉

切記註釋後將程序再次燒錄進板子裏(重新編譯就不用我說了吧)

😄

再次RUN,就沒有發現錯誤了,程序直接到了斷點處(這裏我是比較疑惑的。因爲我還沒有按下按鍵,結果直接就到了,小白不知道是什麼情況hhhhh等大佬解釋)
然後後面就是一步步調試
在這裏插入圖片描述

我們再次點擊DEBUG
設置爲SW模式,頻率爲10Mhz

重複上述步驟,發現只有當按下按鍵後程序纔會跑到斷點處,最終我決定在調試時選擇SW模式

在這裏插入圖片描述

重複上述步驟,發現只有當按下按鍵後程序纔會跑到斷點處,最終我決定在調試時選擇SW模式

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章