Переодическое прерывание

Необходимые знания: [HW] Kontrollermoodul, [HW] Kasutajaliidese moodul,
[AVR] Katkestused, [AVR] Loendurid/Taimerid, [LIB] Sisend-väljundviigud, [LIB] Viide,
[LIB] Taimerid, [PRT] Tarkvaraline viide

Теория

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

Практика

Следующая программа показывает, как настроить счетчик для создания прерывания. В программе используются два LED-а модуля «Дигитальные входы-выходы», где состояние красного меняется периодически с программной задержкой и состояние зеленого - при создании прерывания. Для мигания LED-а с программной задержкой существует отдельное упражнение и в данном разделе это не разъясняется. Главной задачей является объяснение использования библиотеки счетчика и прерываний.

В начале программы происходит настройка 16-битового счетчика/таймера 1 функцией timer1_init_ctc. С помощью этой функции счетчик устанавливается в режим CTC (на английском языке clear timer on compare match) где максимальным значением не является 216 - 1, а его можно выбирать. В данном случае максимальным значением обозначается значение регистра ICR1. Делителем счетчика является 1024 и значением ICR1 - 14400, в результате чего, в случае тактовой частоты 14,7456 Mhz, периодом счетчика является ровно 1 секунда. Это можно легко вычислить по формуле:

f = 14745600 Hz / 1024 / 14400 = 1

После разрешения прерыванию достигать максимального значения счетчика 1, придется так же разрешить создание прерывания глобально, т.е. по всему микроконтроллеру. Для глобального разрешения прерывания используется функция sei и для запрета cli. Для обозначения раздела программы этих функций и прерываний следует привлечь в программу так же заголовочный файл avr/interrupt.h. Раздел программы прерывания обозначается макрофункцией ISR, где параметром является имя вектора прерывания. При названной настройке вектором прерывания достижения максимального значения счетчика 1 является TIMER1_CAPT_vect.

//
// Пример мигающего LED-а Домашней Лаборатории,
// который мигает из-за прерывания счетчика.
// Для сравнения LED-а мигающего с прерыванием
// параллельно работает и LED, мигающий с программной задержкой.
//
#include <homelab/pin.h>
#include <homelab/delay.h>
#include <homelab/timer.h>
#include <avr/interrupt.h>
 
 
//
// Обозначение выводов LED-ов
//
pin led_red   = PIN(C, 5);
pin led_green = PIN(C, 3);
 
//
// Прерывание
//
ISR(TIMER1_CAPT_vect)
{
	// Изменение состояния зеленого LED-а
	pin_toggle(led_green);
}
 
//
// Основная программа
//
int main(void)
{
	// Настройка выводов LED-ов выходом
	pin_setup_output(led_red);
	pin_setup_output(led_green);
 
	// Настройка таймера в CTC режим	
	timer1_init_ctc(
		TIMER1_PRESCALE_1024,
		TIMER1_CTC_TOP_ICR);
 
	// Максимальное значение таймера 14400,
	// что делает длинной периодa 1s
	// Формула 14,7456Mhz / 1024 = 14400
	timer1_set_input_capture_value(14400);
 
	// Разрешение прерывания при достижении значения
	timer1_input_capture_interrupt_enable(true);
 
	// Разрешение глобального прерывания
	sei();
 
	// Бесконечный цикл
	while (true)
	{
		// Программная пауза 1000 миллисекунд
		sw_delay_ms(1000);
 
		// Изменение состояния красного LED-а
		pin_toggle(led_red);
	}
}

При запуске программы видно, что не зависимо от того, что делает микроконтроллер в основной программе, происходят прерывания и зеленый LED мигает.

Если дать программе поработать несколько минут, выяснится важный аспект, который не был так легко заметен в упражнении программной задержки. Несмотря на то, что задержка мигания красного LED-а 1000 мс, то действительное время, которое расходуется на выполнение каждого цикла, немного дольше. Причина в том, что изменение состояния LED-а, вызов функции задержки и заполнение цикла занимают у процессора время выполнения в несколько тактов. В результате мигание красного LED-а отстает от мигания зеленого LED-а. Именно по этой причине нежелательно создавать часовые счетчики и другие точно скоординированные по времени действия с задержкой, а следует использовать прерывание счетчика.

ru/examples/timer/periodic_interrupt.txt · Last modified: 2020/07/20 09:00 by 127.0.0.1
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0