środa, 26 lipca 2017

[17] STM32F7 - Przerwania EXTI

Ten post chciałbym poświęcić na opisanie sposobu generacji przerwań zewnętrznych w mikrokontrolerze STM32F7.

[Źródło: http://www.st.com/en/evaluation-tools/32f746gdiscovery.html]


Piny względem przerwań grupowane są w następujący sposób:


  • Przerwanie dla pinu 0;
  • Przerwanie dla pinu 1;
  • Przerwanie dla pinu 2;
  • Przerwanie dla pinu 3;
  • Przerwanie dla pinu 4;
  • Przerwanie dla pinów od 5 do 9 ;
  • Przerwanie dla pinów od 10 do 15;

Można je wyzwolić na trzy sposoby: zboczem opadającym (GPIO_MODE_IT_FALLING), rosnącym (GPIO_MODE_IT_RISING) lub wywołanie na oba zbocza (GPIO_MODE_IT_RISING_FALLING).

Poniżej przejdę przez wszystkie funkcje.

Inicjalizacja:

  1. #define Inter_Pin           GPIO_PIN_8
  2. #define Inter_Port          GPIOA
  3. #define Inter_Pull          GPIO_NOPULL //GPIO_PULLUP //GPIO_PULLDOWN
  4. #define Inter_Pin_Speed     GPIO_SPEED_HIGH //GPIO_SPEED_FREQ_LOW //GPIO_SPEED_FREQ_MEDIUM //GPIO_SPEED_FREQ_VERY_HIGH
  5. #define Inter_Trig_Mode     GPIO_MODE_IT_RISING_FALLING
  6. #define Inter_Port_Clock    __HAL_RCC_GPIOA_CLK_ENABLE()
  7. #define Inter_Irq           EXTI9_5_IRQn
  8. void Init_Ext_INT5TO9_Init(void)
  9. {
  10.     GPIO_InitTypeDef   GPIO_InitStruct;
  11.     Inter_Port_Clock;  
  12.     GPIO_InitStruct.Pin = Inter_Pin;
  13.     GPIO_InitStruct.Mode = Inter_Trig_Mode;
  14.     GPIO_InitStruct.Pull = Inter_Pull;
  15.     GPIO_InitStruct.Speed = Inter_Pin_Speed;
  16.     HAL_GPIO_Init(Inter_Port, &GPIO_InitStruct);
  17.     // NVIC config
  18.     HAL_NVIC_SetPriority(Inter_Irq, 2, 0);
  19.     HAL_NVIC_EnableIRQ(Inter_Irq);
  20. }

Obsługa przerwania:

  1. void EXTI9_5_IRQHandler(void)
  2. {
  3.   if(__HAL_GPIO_EXTI_GET_IT(Inter_Pin) != RESET)
  4.   {
  5.     __HAL_GPIO_EXTI_CLEAR_IT(Inter_Pin);
  6.    
  7.     if(HAL_GPIO_ReadPin(Inter_Port, Inter_Pin)==GPIO_PIN_RESET)
  8.     {
  9.        /* Do stuff for low state on pin */
  10.     }
  11.     else
  12.     {
  13.        /* Do stuff for high state on pin */
  14.     }
  15.     break;
  16.   }
  17. }

Sprawa wygląda tak samo dla każdej obsługi przerwania od pinu. Najpierw zostaje sprawdzony który pin wywołał przerwanie, następnie czyścimy flagę, po to aby żadne następne wywołane przerwanie nie zostało przeoczone. Po tych operacjach można sprawdzić stan pinu i na tej podstawie wykonać operacje.

Dostępne są następujące funkcje obsługujące przerwanie:

  1. void EXTI0_IRQHandler(void);
  2. void EXTI1_IRQHandler(void);
  3. void EXTI2_IRQHandler(void);
  4. void EXTI3_IRQHandler(void);
  5. void EXTI4_IRQHandler(void);
  6. void EXTI9_5_IRQHandler(void);
  7. void EXTI10_15_IRQHandler(void);

Każdy pin o tym samym numerze (np. PA0, PB0) nie może być obsługiwany przez przerwanie 0. Jeden pin należy podłączać pod jedno przerwanie.

Dla funkcji obsługującej wywołane przerwanie należy pamiętać aby odbywała się ona możliwie najszybciej, należy odpuścić sobie opóźnienia, zwłaszcza dłuższe. Trzeba wykonywać tylko operacje, które w danym wywołaniu są niezbędne do wykonania.