Таймер. Основные характеристики таймеров, страница 3

Тактовая частота периферийных устройств PCLK устанавливается с помощью регистров PCLKSEL0 и PCLKSEL1, и для упрощения настройки микроконтроллера она может быть выбрана равной частоте генератора на кварцевом резонаторе. Для этого должны быть запрограммированысоответствующие регистры (будут использованы в дальнейшем в функции main). Через регистр SCS необходимо разрешить работу генератора на кварцевом резонаторе:

                SCS |= 0x20;      // Разрешить генератор с кварцевым резонатором 12МГц

                while( !(SCS & 0x40) );  //Подождать стабилизации частоты генератора

При этом системная тактовая частота CCLKбудет 12МГц. Затем через регистр PCLKSEL0 необходимо установить делитель частоты для таймера. Для таймера Т0 за это отвечают биты 3:2. Их значение определяется следующим образом:

Биты 3:2

Коэффициент деления

00

PCLK = CCLK/4

01

PCLK = CCLK

10

PCLK = CCLK/2

11

PCLK = CCLK/8

Следовательно, для использования частоты 12МГц без дополнительного деления необходимо выбрать комбинацию 01 и запрограммировать регистр:

PCLKSEL0 = 0x0004; // 0000 0100 - двоичный вид комбинации 01 для разрядов 3:2

В дальнейшем можно настроить таймер на генерацию прерываний с частотой 10Гц. Для этого необходимо разрешить прерывания от таймера и установить коэффициент деления 1200000 поскольку тактовая частота таймера 12000000 (12000000/1200000 = 10). Для инициализации таймера необходимо использовать соответствующую функцию:

void InitTimer0()

{

    T0TCR &= ~0x01;// Запретить таймер

    T0IR   = 0x01; //Конфигурация регистра прерываний

    T0CTCR = 0;//Конфигурация регистра управления

    T0PC   = 0; //Конфигурация регистра предделителя

    T0MR0  = 1200000;//Конфигурация регистра сравнения

                                               //частота PCLK = 12 МГц

                                               //делится на T0MR0 и дает частоту прерываний 10Гц

    T0MCR  = (0x01 | 0x02); //Конфигурация регистра управления режима сравнения

InstallIRQ( TIMER0_INT, (void *)TimerHandler0, 0x03 );

T0TCR |= 0x01;// Разрешить таймер

}

Функция InstallIRQ() использовалась в предыдущей работе и предназначена для инициализации прерываний от различных периферийных устройств. В данном случае необходимо установить функцию прерывания от таймера TimerHandler0:

__irq __nested __arm voidTimerHandler0()

{    

T0IR       = 0x01;

VICADDRESS = 0; //Сброспрерывания

                FIO2PIN = !FIO2PIN; //Инвертироватьсветодиоды

}

В данной функции при каждом вызове (возникновении прерывания 10 раз в секунду) происходит инвертирование состояния светодиодов. Таким образом, светодиоды должны мигать с частотой 5Гц. 

Выполнение определенных действий непосредственно в обработчике прерываний не всегда оптимально. В таком случае можно воспользоваться дополнительной глобальной переменной – флагом события прерывания от таймера:

char T0_event; //Глобальная переменная - флаг события прерывания от таймера

int main (void)

{  

       . . .//Инициализация

       while (1)//Loop forever

       {           

             if( T0_event ) //Если прерывание случилось

             {

                    T0_event = 0; //Сброс флага до следующего прерывания