Данный пример предназначен, скорее всего, для начинающих радиолюбителей. Он показывает, как настроить простой таймер счетчик в микроконтроллере Atmega8.
В микроконтроллере Atmega8 существует простой нулевой таймер. Который просто считает и сохраняет значение в регистре TCNT0. Для того чтобы настроить этот таймер необходимо записать определенные значения битов в регистры. Сначала настраиваем предделитель, для этого существуют 3 бита CS0,CS1,CS2. Комбинации этих битов задают определенный «темп» счета регистра TCNT0.
Допустим наш микроконтроллер работает на частоте 1000000Гц. Предделитель мы выбрали 64. Это означает что в регистр TCNT0 будет считать с частотой 1000000/64=15625Гц. Период счет получаем 1/152625=64мкс (микросекунды). То ест каждые 64 микросекунды происходит увеличение значения счетного регистра TCNT0 на единицу. Максимальное значение этого регистра составляет 255. При его переполнении происходит прерывание по переполнению и сброс регистра в 0. Время необходимое для переполнения счетчика определяем путем перемножения периода счета и колличество итераций таймера 64мкс*256=16384 мкс или 16,384 мс (милисекунды).
На рисунке представленны основные регистры тамера Atmega8. Для того чтобы его настроить нужно всего лишь записать определенные значения в два регистра TCCR0 и TIMSK. Как найти период прерывания сказано выше.
Изменить данный период прерывания 16,384мс можно с помощью предделителя, и получить требуемую частоту прерывания.
А если мы хотим чтобы наш светодиод включался на одну секунду. То нам необходимо ввести еще одну переменную в метод прерывания, и произвести инверсию вывода по достижению определенного значения. В одной секунде 1000мс, период нам тоже известен 16,384 мс. 1000/16,384=61,035. Добавить условие, если наша переменная достигла значения 61 то делаем инверсию вывода.
Если ввести такое условие, то 1 секунда будет равна 0.999447 с. За одни сутки погрешность составит 47,7 секунд.
#include <avr/io.h> #include <avr/interrupt.h> unsigned char count=0; ISR (TIMER0_OVF_vect) { count++; if (count==61) { PORTD=~PORTD;count=0; } } int main(void) { DDRD=0xff;// Настраиваем порт D на выход TCCR0=(1<<0)|(1<<1); //Настраиваем предделитель TIMSK=(1<<TOIE0); // Запускаем таймер asm("sei"); while(1) { asm("nop"); } }
Комментарии