Электроника и программирование

Мигание светодиодом по таймеру

Обновлено 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 секунду.

Наверх Оглавление Следующая статья