Всем привет!) сегодня продолжаем покорять 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”
3 строчки и две ошибки, хоть и из за невнимателньости.
1.
“3. Разрешаем прерывание
HAL_NVIC_EnableIRQ(EXTI2_IRQn);”
Исправьте на HAL_NVIC_EnableIRQ(EXTI0_IRQn);
2. EXTI_IRQHandler пишется с большой H.
Спасибо
Comments are closed.