Говоря о прерываниях, невозможно не рассказать о так называемых внешних прерываниях. За страшным названием стоит просто прерывание от переключения входной ножки. Да, в PIC была одна или две специальных ножки, умеющих генерировать прерывания — тут же таких ножек вагон. Работает всё точно так же, как и во втором проекте — разве что нужно настроить ножку на вход.
17. Прерывания EXTI
При задании прерывания EXTI нужно задать порт–источник и пин–источник прерывания. Также нужно указать реакцию (прерывание или событие — разница пока не важна, выбираем прерывание), тип перепада (только фронт, только спад или и то и другое) и линию EXTI — просто номер EXTI–прерывания, одного из 5.
void init_EXTI()
{
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
Обработчик прерывания будет тот же, что и во втором проекте. Отличие только в названии обработчика (векторе прерывания) и проверяемых флагах.
int state=0;
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0))
{
EXTI_ClearITPendingBit(EXTI_Line0);
if(state)
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
else
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET);
state = 1 - state;
}
}
18. NVIC — приоритетный контроллер прерываний
Однако так ничего работать не будет. Прерывания EXTI обслуживаются через контроллер прерываний, который называется NVIC — значит, нам нужно его настроить. Здесь тоже всё довольно просто: назначаем источник (прерывание EXTI0), приоритет и состояние (включен/выключен). Инициализируем.
void init_NVIC()
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
Весь код 4 проекта полностью
#include "stm32f10x_conf.h"
void init_GPIO()
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
int state=0;
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0))
{
EXTI_ClearITPendingBit(EXTI_Line0);
if(state)
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
else
GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_RESET);
state = 1 - state;
}
}
void init_EXTI()
{
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
void init_NVIC()
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void main()
{
init_GPIO();
init_EXTI();
init_NVIC();
while(1) ;
}
Скачать архив 4 проекта.
Весь цикл:
1. Порты ввода–вывода
2. Таймер и прерывания
3. Выходы таймера
4. Внешние прерывания и NVIC
5. Ставим FreeRTOS
Свежие комментарии