2016-08-18 33 views
1

我是嵌入式系統的新手。對於我的最終學位項目,我正在開發一個使用帶有STM32F411RE微控制器的STM NUCLEO板的系統。如何在中斷中處理全局變量

另外,我正在使用stmcube32加載初始化代碼。

在這一點上我堅持,但首先讓我解釋一下你痘痘背景:

  • 我有三個中斷程序處理相同的標誌,因爲你可以在源文件stm32f4xx_it中看到的。 ç

    void EXTI15_10_IRQHandler(void) { 
    
        /* USER CODE BEGIN EXTI15_10_IRQn 0 */ 
    
        if (__HAL_GPIO_EXTI_GET_IT(BOTON1_Pin) != RESET) { 
         __HAL_GPIO_EXTI_CLEAR_IT(BOTON1_Pin); 
         boton_Flag = 1; 
        } 
        if (__HAL_GPIO_EXTI_GET_IT(BOTON2_Pin) != RESET) { 
         __HAL_GPIO_EXTI_CLEAR_IT(BOTON2_Pin); 
         boton_Flag = 2; 
        } 
        if (__HAL_GPIO_EXTI_GET_IT(BOTON3_Pin) != RESET) { 
         __HAL_GPIO_EXTI_CLEAR_IT(BOTON3_Pin); 
         boton_Flag = 3; 
        } 
        /* USER CODE END EXTI15_10_IRQn 0 */ 
        //HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10); 
        //HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11); 
        //HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12); 
        /* USER CODE BEGIN EXTI15_10_IRQn 1 */ 
    
        /* USER CODE END EXTI15_10_IRQn 1 */ 
    } 
    
  • 在頭文件stm32f4xx_it.h現宣佈我的全局變量是這樣的:

    extern volatile uint8_t boton_Flag; 
    
  • BOTON_1BOTON_2BOTON_3是分配給引腳,這是通過提高觸發邊緣檢測配置爲中斷的名稱。

  • 在調試過程中,當按下按鈕時,三個中斷都能正常工作,每個按鈕都在正確的時間。

  • 變量boton_Flagmain.c中這樣定義的:

    volatile uint8_t boton_Flag = 0; 
    
  • 裏面的main功能我通過我的全局變量boton_Flag到在ControlPanel控制聲明的函數。 h(我在文件開頭有#include "controlpanel.h"):

    int main(void) { 
    
        /* USER CODE BEGIN 1 */ 
    
        /* USER CODE END 1 */ 
    
        /* MCU Configuration----------------------------------------------------------*/ 
    
        /* Reset of all peripherals, Initializes the Flash interface and the Systick.*/ 
        HAL_Init(); 
    
        /* Configure the system clock */ 
        SystemClock_Config(); 
    
        /* Initialize all configured peripherals */ 
        MX_GPIO_Init(); 
        MX_TIM3_Init(); 
        MX_TIM4_Init(); 
    
        /* Initialize interrupts */ 
        MX_NVIC_Init(); 
    
        /* USER CODE BEGIN 2 */ 
        init_PanelConfig(); 
    
        numeroJugadores(boton_Flag); 
    
        /* USER CODE END 2 */ 
    
        /* Infinite loop */ 
        /* USER CODE BEGIN WHILE */ 
        while (1) { 
         /* USER CODE END WHILE */ 
    
         /* USER CODE BEGIN 3 */ 
    
        } 
        /* USER CODE END 3 */ 
    } 
    
  • 功能numeroJugadores(boton_Flag);執行以下操作:

    uint8_t numeroJugadores(uint8_t boton_Flag) { 
        uint8_t players = 4; 
    
        while (boton_Flag != 2); 
        boton_Flag = 0; 
    
        while (boton_Flag != 2) { 
         if (boton_Flag == 1) 
          boton_Flag = 0; 
         { 
          players++; 
          if ((players > 4) || (players < 1)) { 
           players = 0; 
          } 
         } 
         while (boton_Flag != 1); 
    
         switch(players) { 
          case 1: 
          lcd_clear(); 
          lcd_goto(0, 0); 
          lcd_on(); 
          lcd_puts("Numero de"); 
          lcd_goto(0, 1); 
          lcd_puts("jugadores: 1"); 
          break; 
          case 2: 
          lcd_clear(); 
          lcd_goto(0, 0); 
          lcd_on(); 
          lcd_puts("Numero de"); 
          lcd_goto(0, 1); 
          lcd_puts("jugadores: 2"); 
          break; 
          case 3: 
          lcd_clear(); 
          lcd_goto(0, 0); 
          lcd_on(); 
          lcd_puts("Numero de"); 
          lcd_goto(0, 1); 
          lcd_puts("jugadores: 3"); 
          break; 
          case 4: 
          lcd_clear(); 
          lcd_goto(0, 0); 
          lcd_on(); 
          lcd_puts("Numero de"); 
          lcd_goto(0, 1); 
          lcd_puts("jugadores: 4"); 
          break; 
         } 
        } 
        return players; 
    } 
    

那麼,什麼是我的問題嗎?在調試時,我意識到程序仍停留在上述函數內的第一個語句while (boton_Flag != 2);中。

它應該呆在那裏,直到我按BOTON2將標誌更改爲值2並且這樣程序繼續運行。但是,當我按下按鈕時,儘管程序跳到中斷並更改了值,但當它返回到該函數時,該值再次爲0(其初始化值)。

我的結論可能是錯誤的,那就是我沒有正確地將該變量傳遞給該函數,程序將其解釋爲函數內的局部變量,但我不確定。

我希望儘可能地解釋,如果沒有,請讓我知道。

+0

沒有「嵌入式C」 – Olaf

回答

2

你是對的,你沒有正確傳遞變量。按照你的方式,當函數被調用時,你創建一個局部變量(局部於該函數)併爲其分配全局值boton_flag

有兩種方法可以解決這個問題:
1.只需在函數中使用全局變量即可。如果它已經是全球性的,則不需要將它傳遞給你的函數。
2.通過引用傳遞boton_flag。即numeroJugadores(&boton_Flag);。如果你這樣做,你會得到一個指向boton_flag的指針,這個指針稍微改變了numeroJugadores中的代碼(每次使用它時你都必須提取boton_flag)。

+0

你是對的!這很明顯。我的頭在這個時候被燒燬。 –

+0

@SergioCastillo儘管如此,你應該避免在整個地方使用全局變量,這只是意大利麪條編碼,並會導致錯誤。只要將它讀入一個臨時的局部變量並讓一個簡單的狀態機對該值起作用即可。 – Lundin

+1

@Lundin它必須是全局的,因爲它被用在中斷處理程序中。在我看來,有更多的本地變量是不必要的。變量名應該以'G_'開頭,以表明它是全局的。 – Riley

相關問題