Прерывания STM32 достаточно, чтобы прочитать эту статью
Прерывания STM32 достаточно, чтобы прочитать эту статью

1. Предисловие

Прерывание STM32:

Прерывание — это механизм, который позволяет возникновению внешних событий или определенных условий прерывать нормальный поток выполнения программы, тем самым выполняя определенную процедуру обслуживания прерывания. Это облегчает возможность реагировать и обрабатывать внешние события в режиме реального времени. Прерывания в микроконтроллерах STM32 бывают двух типов: внутренние прерывания и внешние прерывания.

  • Внутреннее прерывание: вызывается определенным событием внутри микроконтроллера.,Например, переполнение таймера, завершение последовательной связи и т. д.
  • Внешнее прерывание: вызывается внешним устройством или датчиком, например нажатием кнопки, датчиком, обнаруживающим определенное состояние, и т. д. В STM32 контроллер прерываний (NVIC) отвечает за управление и координацию всех запросов на прерывания. Разработчики могут добиться гибкого контроля над прерываниями за счет приоритета прерываний, включая или отключая определенные прерывания.

Почти каждый вывод может быть настроен на прерывание независимо. Подробную информацию можно найти в «Китайском справочном руководстве».

Ссылка: «Справочное руководство STM32F10X-на китайском языке», глава «Прерывания и события». «Руководство Wildfire STM32»

2. NVIC

NVIC — это вложенный векторный контроллер прерываний, который управляет функциями всего чипа, связанными с прерываниями. Он тесно связан с ядром и является периферийным устройством внутри ядра.

2.1 Знакомство с регистрами NVIC

Регистр NVIC включает в себя следующие функции:

  1. Приоритет прерывания: NVIC позволяет устанавливать приоритет для каждого возможного источника прерывания и определяет порядок ответа на прерывания, устанавливая приоритет. Обычно меньшие числа указывают на более высокий приоритет.
  2. Разрешение прерываний: определенные источники прерываний могут быть включены или отключены через регистр NVIC для управления запуском запросов на прерывание.
  3. Регистр смещения таблицы векторов прерываний: используется для указания адреса прерывания. Служить программе (ISR).,когда срабатывает определенное прерывание,Процессор перейдет к соответствующему прерыванию Служить программе, чтобы начать выполнение.
Язык кода:javascript
копировать
typedef struct {
    __IO uint32_t ISER[8];       // Регистр разрешения прерываний
    uint32_t RESERVED0[24];
    __IO uint32_t ICER[8];       // Прерывание очистки регистра
    uint32_t RSERVED1[24];
    __IO uint32_t ISPR[8];       // Регистр ожидания включения прерывания
    uint32_t RESERVED2[24];
    __IO uint32_t ICPR[8];       // Прерывание очистки ожидающего регистра
    uint32_t RESERVED3[24];
    __IO uint32_t IABR[8];       // Прерывание действительного битового регистра
    uint32_t RESERVED4[56];
    __IO uint8_t  IP[240];       // Регистр приоритета прерываний (8 бит wide)
    uint32_t RESERVED5[644];
    __O  uint32_t STIR;          // Регистр прерываний, запускаемых программным обеспечением
}  NVIC_Type;

Обычно используются только три регистра: ISER, ICER и IP.,ISER используется для разрешения прерываний, ICER — для отключения прерываний, а IP — для установки приоритета прерываний.

2.2 Определение приоритета прерывания

Чем меньше значение, тем выше приоритет. В серии F103 используется только 0-4, но в принципе есть 0-255,

4 бита, используемые для выражения приоритета, сгруппированы в приоритет вытеснения и подприоритет.

  1. Если несколько прерываний отвечают одновременно, то прерывание с более высоким приоритетом вытеснит прерывание с более низким приоритетом и будет выполнено первым.
  2. Если приоритеты вытеснения одинаковы, сравните подприоритеты.
  3. Если приоритет вытеснения и подприоритет одинаковы, сравните их номера аппаратных прерываний. Чем меньше число, тем выше приоритет.

2.3 Приоритетная группировка

2.3 Программирование прерываний

Три шага:

  1. Включить внешние прерывания
  2. Инициализируйте структуру NVIC_InitTypeDef.
Язык кода:javascript
копировать
typedef struct {
    uint8_t NVIC_IRQChannel;                    // Источник прерывания
    uint8_t NVIC_IRQChannelPreemptionPriority;  // Приоритет вытеснения
    uint8_t NVIC_IRQChannelSubPriority;         // подприоритет
    FunctionalState NVIC_IRQChannelCmd;         // Включить или отключить прерывания
} NVIC_InitTypeDef;
  1. Пишем функцию обслуживания прерываний, обычно в библиотеке stm32f10x_it.c.

3. Внешний контроллер прерываний/событий (EXTI).

Внешний контроллер прерываний/событий состоит из 20 детекторов фронтов, которые генерируют запросы на события/прерывания. Каждая входная линия может быть независимо настроена на тип входа (импульсный или приостановочный) и соответствующее событие запуска (нарастающий фронт или спадающий фронт, или оба фронта срабатывают). ). Каждая входная линия может быть независимо экранирована. Регистр ожидания содержит строку состояния для запросов на прерывание.

3.1 Функциональная блок-схема EXTI

Косая черта 20 указывает, что внутри контроллера имеется 20 одинаковых сигнальных линий, а EXTI имеет всего 20 линий прерываний/событий.

Красный цвет представляет прерывание, а зеленый — событие.

Целью создания линии прерывания является ввод входного сигнала в NVIC, а затем запуск функции обслуживания прерываний для реализации функции, которая находится на программном уровне. Целью создания линии событий является передача импульсного сигнала другим периферийным устройствам для использования, и это передача сигнала на уровне схемы, то есть на аппаратном уровне.

3.2 Строка событий прерывания

EXTI имеет 20 линий прерываний/событий. Каждый GPIO может быть установлен как входная линия, занимающая от EXTI0 до EXTI15. Есть еще семь строк для определенных периферийных событий, см. таблицу EXTI Interrupt_Event Lines.

4 определенные периферийные линии прерываний/событий запускаются периферийными устройствами. Для конкретного использования обратитесь к конкретным инструкциям по периферийным устройствам в «STM32F10X-Китайское справочное руководство».

EXTI0–EXTI15 используются для GPIO. С помощью программного управления любой GPIO может использоваться в качестве источника входного сигнала EXTI. Из строки таблицы EXTI error_event видно, что EXTI0 можно настроить как PA0, PB0, PC0, PD0, PE0, PF0, PG0, PH0 или PI0 через биты EXTI0[3:0] регистра конфигурации внешнего прерывания AFIO 1 ( AFIO_EXTICR1).

3.3 Структура инициализации EXTI

Язык кода:javascript
копировать
typedef struct {
    uint32_t EXTI_Line;                 // линия прерывания/события
    EXTIMode_TypeDef EXTI_Mode;         // EXTI-режим
    EXTITrigger_TypeDef EXTI_Trigger;   // Тип триггера
    FunctionalState EXTI_LineCmd;       // EXTI включить
} EXTI_InitTypeDef;

  1. EXTI_Line:EXTIлиния прерывания/событиявыбирать,Опционально от EXTI0 до EXTI19,См. таблицу EXTI прерывания_события строки встречи.
  2. EXTI_Mode:EXTI-режимвыбирать,Необязательно — генерировать прерывание (EXTI_Mode_Interrupt) или генерировать событие (EXTI_Mode_Event).
  3. EXTI_Trigger:EXTIсрабатывает по краюсобытие,Дополнительный триггер по нарастающему фронту(EXTI_Trigger_Rising)、 Триггер по заднему фронту ( EXTI_Trigger_Falling) или триггер по нарастающему и спадающему фронту ( EXTI_Trigger_Rising_Falling)。
  4. EXTI_LineCmd: определяет, следует ли включать линию EXTI, при необходимости включать линию EXTI (ENABLE) или отключать ее (DISABLE).

3.4 Ключевое прерывание

  1. Инициализируйте GPIO, используемый для генерации прерываний;
  2. инициализировать EXTI;
  3. КонфигурацияNVIC;
  4. Автор функции обслуживания прерываний;

Определение макроса:

Язык кода:javascript
копировать
//определение контакта
#define KEY1_INT_GPIO_PORT GPIOA
#define KEY1_INT_GPIO_CLK (RCC_APB2Periph_GPIOA\
                                    |RCC_APB2Periph_AFIO)
#define KEY1_INT_GPIO_PIN GPIO_Pin_0
#define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOA
#define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource0
#define KEY1_INT_EXTI_LINE EXTI_Line0
#define KEY1_INT_EXTI_IRQ EXTI0_IRQn

#define KEY1_IRQHandler EXTI0_IRQHandler


#define KEY2_INT_GPIO_PORT GPIOC
#define KEY2_INT_GPIO_CLK (RCC_APB2Periph_GPIOC\
                                    |RCC_APB2Periph_AFIO)
#define KEY2_INT_GPIO_PIN GPIO_Pin_13
#define KEY2_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOC
#define KEY2_INT_EXTI_PINSOURCE GPIO_PinSource13
#define KEY2_INT_EXTI_LINE EXTI_Line13
#define KEY2_INT_EXTI_IRQ EXTI15_10_IRQn

Конфигурация NVIC

Язык кода:javascript
копировать
static void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    /* КонфигурацияNVIC имеет приоритетную группу 1. */
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    /* Конфигурация Источник прерывания:кнопка1 */
    NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
    /* Конфигурация Приоритет вытеснения:1 */
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    /* Конфигурацияподприоритет:1 */
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    /* включить канал прерываний */
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

    /* Конфигурация Источник прерывания:кнопка2,Другие варианты использования, связанные с Конфигурацией выше. */
    NVIC_InitStructure.NVIC_IRQChannel = KEY2_INT_EXTI_IRQ;
    NVIC_Init(&NVIC_InitStructure);
}

Конфигурация прерывания EXIT

Язык кода:javascript
копировать
void EXTI_Key_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    EXTI_InitTypeDef EXTI_InitStructure;

    /*Включаем часы кнопки GPIO порта*/
    RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);

    /* Конфигурация NVIC Прерывать*/
    NVIC_Configuration();

    /*--------------------------KEY1Конфигурация---------------------*/
    /* Выберите GPIO, используемый кнопкой */
    GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN;
    /* Конфигурация – это плавающий ввод. */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStructure);

    /* Выбор источника сигнала EXTI */
    GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, \
                        KEY1_INT_EXTI_PINSOURCE);
    EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;

    /* EXTI — режим прерывания */
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    /* прерывание по нарастающему фронту */
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    /* Включить прерывания */
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    /*--------------------------KEY2Конфигурация------------------*/
    /* Выберите GPIO, используемый кнопкой */
    GPIO_InitStructure.GPIO_Pin = KEY2_INT_GPIO_PIN;
    /* Конфигурация – это плавающий ввод. */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStructure);

    /* Выбор источника сигнала EXTI */
    GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, \
                        KEY2_INT_EXTI_PINSOURCE);
    EXTI_InitStructure.EXTI_Line = KEY2_INT_EXTI_LINE;

    /* EXTI — режим прерывания */
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    /* Прерывание по заднему фронту */
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    /* Включить прерывания */
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);
}

Функция обслуживания прерываний

Язык кода:javascript
копировать
void KEY1_IRQHandler(void)
{
    //Убедимся, что EXTI сгенерирован Обрыв линии
    if (EXTI_GetITStatus(KEY1_INT_EXTI_LINE) != RESET) {
        // LED1 отрицать
        LED1_TOGGLE;
        //Очистим бит флага прерывания
        EXTI_ClearITPendingBit(KEY1_INT_EXTI_LINE);
    }
}

void KEY2_IRQHandler(void)
{
    //Убедимся, что EXTI сгенерирован Обрыв линии
    if (EXTI_GetITStatus(KEY2_INT_EXTI_LINE) != RESET) {
        // LED2 отрицать
        LED2_TOGGLE;
        //Очистим бит флага прерывания
        EXTI_ClearITPendingBit(KEY2_INT_EXTI_LINE);
    }
}

наконец

Если эта статья была для вас полезна, пожалуйста, поддержите блогера трижды!

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose