Главная > Статьи > Обработка прерываний от интервального таймера

Обработка прерываний от интервального таймера

        1. В предыдущих разделах мы освоили, как управлять портом и динамически изменять период счёта интервального таймера. Было бы не логично управлять портом по программному таймеру, тем самым, используя впустую время процессора Nios II. Правильнее было бы использовать для этих целей аппаратный таймер, и менять состояния порта PIO в прерывании.

        2. Обозначим задачу: необходимо инициализировать таймер, посылающий запрос на прерывание каждую секунду (для удобства наблюдения за мигающим светодиодом), а в программе обработки прерывания (ISR) состояние PIO изменяется на противоположное. Мы будем использовать систему с процессором Nios II, разработанную ранее.

        3. Проект состоит из трёх программных файлов: counter_main.c, counter.h, counter_functions.c. В качестве bsp проекта используем всё тот же hello_world_bsp.

        4. Рассмотрим файл system.h (рис. 51) проекта. В нём представлены макросы нашей системы SOPC BUILDER. Поскольку ставится задача инициализации таймера, необходимо обратиться в раздел "timer_0 configuration". Макросы, описанные в этом разделе, будут использованы для управления ядром интервального таймера timer_0.


Рис. 51

        5. Все функции описаны в файле counter_functions.c . В файле описаны четыре функции: start_message - функция вывода в терминал посредством JTAG UART приветственного сообщения, handle_timer_0_interrupts - собственно функция обработки прерывания от таймера, timer_init - функция инициализации таймера, timer_set_period - функция задания периодичности появления прерывания. Три функции работы с таймером заключены между директивами #ifdef TIMER_0_BASE, таким образом, они обслуживаются только при наличии соответствующего ядра в системе.

        6. Функция timer_init (рис. 52) имеет три формальных параметра, относящихся к ядру таймера: офсет, идентификатор контроллера прерываний, номер прерывания. Вначале функции формальные параметры присваиваются статическим переменным. Затем запрещаются прерывания от таймера (функция alt_ic_irq_disable()), после чего следует функция регистрации прерывания (alt_ic_isr_register()). Эта функция регистрирует функцию обработки прерываний (ISR), которая в нашем случае называется handle_timer_0_interrupts и разрешает прерывания. Подробнее о функциях alt_ic_isr_register() и alt_ic_irq_disable().


Рис. 52

        7. Функция handle_timer_0_interrupts (рис. 53) выполняет следующие операции: сбрасывает флаг прерывания (бит TO) в регистре STATUS таймера, запрещает прерывания без остановки счета (бит CONT) в регистре CONTROL, меняет состояние вывода PIO на противоположное, запускает таймер (бит START) в регистре CONTROL.


Рис. 53

        8. Функция timer_set_period (рис. 54) выполняет следующие операции: останавливает таймер и запрещает прерывания (бит STOP) в регистре CONTROL, побайтно записывает изменённый период счета таймера, затем запускает таймер (бит START) в регистре CONTROL.


Рис. 54

        9. Поскольку все функции уже описаны в файле counter_functions.c, файл counter_main.c выглядит достаточно лаконично (рис. 55). Как видно, тело основного цикла является пустым. В качестве формальных переменных используются макросы из файла system.h, а при вызове функции timer_set_period частота запроса на прерывание была уменьшена до одного в секунду.


Рис. 55

        10. Скомпилируем и запустим программу, для этого нажимаем на иконку . Во всплывающем окне Run As выбираем Nios II Hardware и кликаем OK. Если появляется окно, предлагающее сохранить изменённые файлы, соглашаемся на сохранение.

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

<<Назад Оглавление

Хостинг от uCoz