Мигание светодиодом по таймеру
Обновлено 12.04.2025В статье по первому запуску MIK32 мы запустили мигание светодиодом, задавая интервал в бесконечном цикле. Теперь исправим код в файле main.c так, чтобы светодиод мигал из прерывания по таймеру. Для этого в среде MIK32 IDE на панели Project Explorer скопируем наш проект blinky, и сохраним его под названием blinky_timer_irq. Затем откроем файл main.c, чтобы приступить к редактированию кода:

Копирование проекта
Теперь, опираясь на Техническое описание MIK32 АМУР и примеры, изменяем код следующим образом:
1) Включаем файлы заголовочные файлы, которые нам понадобятся:

Добавление заголовочных файлов
2) Включаем тактирование таймера32_0 и контроллера прерываний:

Включение тактирования таймера32_0 и контроллера прерываний
3) Настраиваем таймер32_0:

Настройка таймера32_0
4) Настраиваем контроллер прерываний и включаем прерывания:


Настройка контроллера прерываний
5) Включаем таймер:

Включение таймера32_0
6) Удаляем переключение светодиода из бесконечного цикла:

Удаление кода из бесконечного цикла
7) И добаляем обработчик прерывания от таймера:

Обработчик прерываний от таймера
Таким образом, у нас получился такой файл main.c:
#include <mik32_memory_map.h> #include <pad_config.h> #include <gpio.h> #include <power_manager.h> #include <wakeup.h> #include <timer32.h> //определения констант для таймера #include <epic.h> //определения констант для контроллера прерываний #include <scr1_csr_encoding.h> //определения констант регистров ядра #include <csr.h> //определения для операций взаимодействия с регистрами ядра /* * Данный пример демонстрирует работу с GPIO и PAD_CONFIG. * В примере настраивается вывод, который подключенный к светодиоду, в режим GPIO. * Светодиод переключается в прерывании от таймера. * */ #define PIN_LED 9 // Светодиод управляется выводом PORT_0_9 #define PIN_BUTTON 10 // Кнопка управляет сигналом на выводе PORT_0_10 void trap_handler() { if (EPIC->STATUS & (1 << EPIC_TIMER32_0_INDEX)) //если прерывание от таймера { GPIO_0->OUTPUT ^= 1 << PIN_LED; // Установка сигнала вывода 9 порта 0 в противоположный уровень TIMER32_0->INT_CLEAR = TIMER32_INT_OVERFLOW_M; //Сброс флага прерывания таймера EPIC->CLEAR = 1 << EPIC_TIMER32_0_INDEX; //Сброс флага прерывания линии таймера } } void EnableInterrupts() { // Разрешение прерываний (установка соответствующих регистров состояния в ядре) set_csr(mstatus, MSTATUS_MIE); set_csr(mie, MIE_MEIE); } void InitClock() { PM->CLK_APB_P_SET |= PM_CLOCK_APB_P_GPIO_0_M; // Включение тактирования GPIO_0 PM->CLK_APB_M_SET |= PM_CLOCK_APB_M_PAD_CONFIG_M // Включение тактирования контроллера выводов | PM_CLOCK_APB_M_PM_M // Включение тактирования блока управления питанием | PM_CLOCK_APB_M_TIMER32_0_M // Включение тактирования таймера32_0 | PM_CLOCK_APB_M_EPIC_M; // Включение тактирования контроллера прерываний } int main() { InitClock(); // Включение тактирования GPIO PAD_CONFIG->PORT_0_CFG &= ~(0b11 << (2 * PIN_LED)); // Установка вывода 9 порта 0 в режим GPIO PAD_CONFIG->PORT_0_CFG &= ~(0b11 << (2 * PIN_BUTTON)); // Установка вывода 10 порта 0 в режим GPIO GPIO_0->DIRECTION_OUT = 1 << PIN_LED; // Установка направления вывода 9 порта 0 на выход GPIO_0->DIRECTION_IN = 1 << PIN_BUTTON; // Установка направления вывода 10 порта 0 на вход //Настраиваем максимальное значение счётчика 32*10^6, //что при такрировании 32 МГц будет соответствовать 1 секунде TIMER32_0->TOP = 32000000u; //Включаем прерывание при переполнении счётчика TIMER32_0->INT_MASK = TIMER32_INT_OVERFLOW_M; EPIC->MASK_EDGE_CLEAR = 0xFFFF; //сброс маски прерываний по фронту EPIC->CLEAR = 0xFFFF; //сброс флагов прерываний EPIC->MASK_EDGE_SET = 1 << EPIC_TIMER32_0_INDEX;//установка маски прерываний по фронту от таймера32_0 EnableInterrupts(); TIMER32_0->ENABLE = TIMER32_ENABLE_TIM_EN_M; //включаем таймер while (1) { } }
На этом заканчиваем редактирование кода, нажимаем Project->Build Proiect. После успешной компилляции прошиваем плату, нажав Upload debug для используемого программатора и Run:

Запуск отладки программы на отладочной плате
Как и раньше, светодиод на отладочной плате будет мигать. Но теперь мигание происходит по таймеру с интервалом ровно в 1 секунду.
Наверх Оглавление Следующая статья