2016-08-18 4 views
1

Я новичок в этой встроенной системе. Для моего финального проекта я разрабатываю систему, работающую с Советом STM NUCLEO с микроконтроллером STM32F411RE.Как обрабатывать глобальные переменные в прерываниях

Кроме того, я работаю с stmcube32 для загрузки кода инициализации.

На данный момент я застрял, но сначала позвольте мне объяснить вам LITLE фон:

  • У меня есть три процедуры обработки прерываний обработки тот же флаг, как вы можете видеть в исходном файле 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_1, BOTON_2, BOTON_3 имена, присвоенные контакты, которые сконфигурированы как прерывания путем повышения обнаружения триггера край.

  • При отладке три прерывания отлично работают при нажатии кнопок, каждый в нужное время.

  • переменная boton_Flag определяется в main.c таким образом:

    volatile uint8_t boton_Flag = 0; 
    
  • Внутри функции main я прохожу свою глобальную переменную boton_Flag функции, которая объявлена ​​в Пультом управления. 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, и таким образом программа продолжает работать. Однако, когда я нажимаю кнопку, несмотря на программу JUMPS TO INTERRUPT и CHANGES VALUE, когда она возвращается к функции, значение снова 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

Смежные вопросы