пятница, 10 мая 2013 г.

Асинхронный режим работы таймера/счетчика T2 в C

Асинхронный режим работы - режим, в котором тактироване таймера/счетчика осуществляется от внешнего тактового генератора и никак не зависит от внутреннего. Это может использоваться для работы таймера/счетчика в качестве счетчика реального времени. Попробуем создать часы реального времени на основе микроконтроллера ATmega328 и дисплея 1602.

Дополнительный материал:
Для работы таймера/счетчика T2 в асинхронном режиме, тактирование микроконтроллера должно осуществляться от внутреннего генератора, а к выводам TOSC1 (9 ножка) и TOSC2 (10 ножка) подключается кварцевый резонатор 32 кГц.
Рисунок 1 - Схема подключения
На рисунке 1 изображена одна из возможных схем подключения компонентов. Дисплей можно  подключить и к другим выводам. Также можно использовать четырехразрядный семисегментный светодиодный индикатор, выбор за Вами. В коде программы я опущу ту часть, программы, которая работает с дисплеем. Ее Вы можете посмотреть здесь.
Частота кварцевого резонатора, если быть точным, составляет 32768 Гц. Для того, чтобы цифры изменялись каждую секунду, необходимо использовать режим прерывания по переполнению таймера (256 тактов) и предделитель таймера на 128. В итоге запрос на прерывание будет возникать ровно каждую секунду.

Текст программы:

#include <avr/io.h> //подключение стандартной библиотеки ввода/вывода
#include <avr/interrupt.h> //подключаем библиотеку работы с прерываниями

ISR(TIMER2_OVF_vect)
{
static char s=0; //переменная, содержащая секунды
static char m=0; //переменная, содержащая минуты
static char h=0; //переменная, содержащая часы
s++;
if (s==60)
{
s=0;
m++;
}
if (m==60)
{
m=0;
h++;
}
if (h==24)
{
h=0;
}
}

int main(void)
{
//T2
TCCR2A = 0x00; //обычный режим работы таймера
TCCR2B = 0x05; //предделитель на 128
TIMSK2 = 0x01; //прерывание по переполнению
ASSR = 0x20; //использование внешнего кварцевого резонатора 32кГц
//инициализация дисплея и портов ввода/вывода в зависимости от того, куда Вы будете выводить информацию
sei(); //разрешаем глобальные прерывания
    while(1)
    {
        //любая программа
    }
}

Как видите, текст программы до безобразия прост.
Стоит отметить, что если Вам потребуется работать с регистрами TCNT2, OCR2A, OCR2B, TCCR2A, TCCR2B во время асинхронного режима работы таймера, то для доступа к ним необходимо убедиться, доступны ли они для записи путем контроля соответствующих битов регистра ASSR. Дело в том, что при работе в асинхронном режиме, все регистры таймера тактируются также от внешнего тактового генератора и работают медленнее чем сам микроконтроллер.