Старт ARM. Прерывания на STM32F429I-DISCO. HAL

Всем привет!) сегодня продолжаем покорять stm32f4, в данной статье будем юзать stm32f429ZI (его DISCO) и использовать прерывания микроконтроллера. В момент возникновения прерывания необходимо будет зажигать светодиод на борде (их 2). Начнем с начала. Настраиваем(конфигурируем) GPIO в void MX_GPIO_Init(void).

/*Configure GPIO pin : PA0 */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

PA0 – пин для пользовательской кнопки (user button)
Прерывание можно ловить по фронту, по спаду или смешенный, то есть по спаду и фронту.
Режимы прерываний:

#define  GPIO_MODE_IT_RISING                    ((uint32_t)0x10110000)   /*!< External Interrupt Mode with Rising edge trigger detection          */
#define  GPIO_MODE_IT_FALLING                   ((uint32_t)0x10210000)   /*!< External Interrupt Mode with Falling edge trigger detection         */
#define  GPIO_MODE_IT_RISING_FALLING            ((uint32_t)0x10310000)   /*!< External Interrupt Mode with Rising/Falling edge trigger detection  */
 
#define  GPIO_MODE_EVT_RISING                   ((uint32_t)0x10120000)   /*!< External Event Mode with Rising edge trigger detection               */
#define  GPIO_MODE_EVT_FALLING                  ((uint32_t)0x10220000)   /*!< External Event Mode with Falling edge trigger detection              */
#define  GPIO_MODE_EVT_RISING_FALLING           ((uint32_t)0x10320000)   /*!< External Event Mode with Rising/Falling edge trigger detection       */

там же (в той же функции) настраиваем прерывания для реакции по входам микроконтроллера

 /* EXTI interrupt init*/
  /* Sets the priority grouping field */
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
  HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI0_IRQn);
	
/* Sets the priority grouping field */
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
  HAL_NVIC_SetPriority(EXTI1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI1_IRQn);

  /* Sets the priority grouping field */
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
  HAL_NVIC_SetPriority(EXTI2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI2_IRQn);

  /* Sets the priority grouping field */
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
  HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI3_IRQn);
	
/* Sets the priority grouping field */
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
  HAL_NVIC_SetPriority(EXTI4_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI4_IRQn);

/* Sets the priority grouping field */
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
  HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
	
  /* Sets the priority grouping field */
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
  HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);

Наши действия:
1. Выставляем приоритет прерывания для вектора прерывания NVIC (The Nested Vectored Interrupt Controller – вложенный вектор прерывания контроллера). HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);

// NVIC_PRIORITYGROUP_0
// NVIC_PRIORITYGROUP_1
// NVIC_PRIORITYGROUP_2
// NVIC_PRIORITYGROUP_3

2. Выставляем личный приоритет прерывания (главный приоритет) и второстепенный(под) приоритет.
HAL_NVIC_SetPriority(EXTI2_IRQn, 0, 0);
Startup_stm32f429xx.s

EXTI0_IRQn                  = 6,      /*!< EXTI Line0 Interrupt                                              */
EXTI1_IRQn                  = 7,      /*!< EXTI Line1 Interrupt                                              */
EXTI2_IRQn                  = 8,      /*!< EXTI Line2 Interrupt                                              */
EXTI3_IRQn                  = 9,      /*!< EXTI Line3 Interrupt                                              */
EXTI4_IRQn                  = 10,     /*!< EXTI Line4 Interrupt                                              */
EXTI9_5_IRQn                = 23,     /*!< External Line[9:5] Interrupts                                     */
EXTI15_10_IRQn              = 40,     /*!< External Line[15:10] Interrupts                                   */

3. Разрешаем прерывание
HAL_NVIC_EnableIRQ(EXTI2_IRQn);
После того, как мы сделали настройку, можем приступать к написанию задач от прерываний (исполняемая функция). В момент, когда на входе GPIOA0, GPIOB0, GPIOC0 (0 пин), высокий сигнл, микроконтроллер нас забрасывает во void EXTI0_IRQHandler(void), функция размещается в stm32f4xx_t.c, таким образом происходит и для пина 1 -4, то есть для каждого пина индивидуальное прерывание, для группы пинов 5-9 и группу пинов 10-15 дела обстоят не многу по-другому, то есть, для всех пинов одной из групп -прерывание одно, пришел высокий сигнал на 5,6 или 9 функция прерывания одна и та жа, выполняется функция void EXTI9_5_IRQHandler(void), аналогично и для void EXTI10_15_IRQHandler(void).
Небольшой код работы прерывания от нажатия пользовательской кнопки на борде.
stm32f4xx_it.c

static int i = 0;

void EXTI0_IRQHandler(void)
{
	if(i%2 != 1){
		HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_SET);
		i++;
	}
	else{
		HAL_GPIO_WritePin(GPIOG, GPIO_PIN_13, GPIO_PIN_RESET);
		i++;
	}
	if(i >= 10) i = 0;
  HAL_NVIC_ClearPendingIRQ(EXTI0_IRQn);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
}

HAL_NVIC_ClearPendingIRQ(EXTI0_IRQn) – функция сбрасывает бит в регистре прерываний, для EXTI0_IRQn
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0) – функция выхода прерывания с возвратом к тому месту, где прервался исполняемый код при возникновении прерывания.
В следующей части рассмотрим именное привязывание от пинов микроконтроллера, а на сегодня все, всем пока.

2 thoughts on “Старт ARM. Прерывания на STM32F429I-DISCO. HAL

  1. 3 строчки и две ошибки, хоть и из за невнимателньости.

    1.
    “3. Разрешаем прерывание
    HAL_NVIC_EnableIRQ(EXTI2_IRQn);”

    Исправьте на HAL_NVIC_EnableIRQ(EXTI0_IRQn);

    2. EXTI_IRQHandler пишется с большой H.

Comments are closed.