1. При конфигурировании системы Nios II EDS мы заложили в проект системы аппаратный таймер (см. рис. 21 ), выбрали для него период таймаута – 1 миллисекунду, 32-битный размер счётчика и полнофункциональные аппаратные опции (рис. 22). Счётчик может использоваться в качестве системного тактового сигнала (в нашем случае это 1 кГц), в качестве сторожевого таймера (он не предусмотрен в нашем проекте), для генерирования сигнала запроса на прерывание или одиночного импульса для логики снаружи системы SOPC Builder (не предусмотрен в нашем проекте). Для начала мы овладеем навыками управления периодом генерирования запроса на прерывание (одиночного импульса), а также остановкой и запуском таймера. Подробная информация об ядре интервального таймера здесь.

рис. 22
2. Создадим проект, называемый timer_full, с хорошо уже известным нам BSP проектом hello_world_bsp. Если вы вдруг забыли, как создавать проект приложения, обратитесь к первым пунктам в любом из предыдущих разделов.
3. Добавим в проект файлы заголовочный и исходный (timer_full.h и timer_full.c). В заголовочный файл добавим следующий код:
#include "altera_avalon_timer_regs.h"
#include "altera_avalon_timer.h"
#include "system.h"
#include <sys/alt_alarm.h>
#include <stdio.h>
где alt_types.h
- ширина и тип данных,
altera_avalon_timer_regs.h – схема распределения регистров в таймере
altera_avalon_timer.h – подключения функций таймера
system.h – описание нашей системы SOPC Builder
sys/alt_alarm.h – драйвер системного таймера
stdio.h – стандартная библиотека
4. Исходный файл проекта будет иметь следующий код:
static
void timer_reg(alt_u16 periodL,alt_u16 periodH, alt_u8 control)
{
#ifdef TIMER_0_BASE
IOWR_ALTERA_AVALON_TIMER_PERIODL(TIMER_0_BASE, periodL);
IOWR_ALTERA_AVALON_TIMER_PERIODH(TIMER_0_BASE, periodH);
IOWR_ALTERA_AVALON_TIMER_CONTROL(TIMER_0_BASE, control);
#endif
}
static
void timer_status()
{
alt_u16 periodL;
alt_u16 periodH;
alt_u8
control;
#ifdef TIMER_0_BASE
periodL =
IORD_ALTERA_AVALON_TIMER_PERIODL(TIMER_0_BASE );
periodH =
IORD_ALTERA_AVALON_TIMER_PERIODH(TIMER_0_BASE );
control =
IORD_ALTERA_AVALON_TIMER_CONTROL(TIMER_0_BASE );
printf("\n
TIMER PERIOD %02x%02x\n TIMER STATUS %01x", periodH,
periodL, control);
#endif
}
static
void start_message()
{
printf("\n\n**************************\n");
printf("* Timer
start! *\n");
printf("**************************\n");
}
int main(void)
{
alt_u8 i;
alt_u16 ar_periodL[] = {0x55, 0x77,
0xEE};
alt_u16 ar_periodH[] = {0xAA, 0xFC,
0x38};
alt_u8 ar_control[] = {0x7, 0x8, 0x7};
start_message();
printf("\n
ticks per second %04x",(alt_u16)alt_ticks_per_second());
timer_status();
for (i=0; i<3; i++)
{
timer_reg(ar_periodL[i], ar_periodH[i], ar_control[i]);
timer_status();
}
return 0;
}
5. Рассмотрим код программы подробнее.
Функция timer_reg() записывает значения periodL, periodH в регистры периода таймера, определяя период появления сигнала прерывания, и сигнал control в регистр контроля, контролируя поведение таймера.
Функция timer_status() считывает состояние регистров периода и статуса, и выводит их значение в консоль Nios II.
Функция start_message() уже хорошо знакома по предыдущим пунктам.
Задаём массив произвольных значений для регистров periodL, periodH, control.
printf("\n ticks per second %04x",(alt_u16)alt_ticks_per_second()); - выводим значение функции, отображающую количество тактов в секунду, в консоль Nios II.
Далее в теле main мы пишем и читаем значение регистров периода. Переменная control в функции timer_reg() принимает два значения: 0х7 – таймер запущен непрерывно и прерывания разрешены, 0х8 – таймер остановлен.
6.
Скомпилируем и запустим программу, для этого
нажимаем на иконку
.
Во всплывающем окне Run As выбираем Nios II Hardware и кликаем OK (рис. 17).
Если появляется окно, предлагающее сохранить изменённые файлы, соглашаемся на
сохранение.
7. На рис. 23 отображён результат работы программы. Таймер имеет частоту 1000 тактов в секунду (03e8), начальный период таймера – 24 999 (61а7) – на один тактовый цикл меньше, поскольку считается и нулевой цикл, значение в регистре статуса – 7 – таймер запущен. В следующих строках отображаются манипуляции с регистрами, созданные в теле main.

рис. 23
8. Практика управления интервальным таймером закончена.