Все МК AVR в своем составе имеют как минимум один 8-разрядный и один 16-разрядный таймеры-счетчики (Т/С). Например МК семейства Mega имеют от двух до шести Т/С общего назначения. Таймеры-счетчики относятся к периферийным узлам МК, поэтому они могут работать автономно от процессорного ядра. То есть, в случае, когда процессор выполняет какую-то логическую операцию, Т/С отсчитывают интервал времени. Исходя из названия данного узла МК, видно основное назначения Т/С. Физически Т/С – это набор последовательно соединенных программируемых триггеров. Предназначены они для отсчета и измерения временных интервалов или используются как счетчики внешних событий. А также для генерации сигналов различной частоты или сигналов с широтно-импульсной модуляцией (ШИМ) или может работать в режиме часов реального времени. Некоторые таймеры-счетчики по своим функциональным возможностям сходны: Т/С0 такой же как Т/С2 (кроме Mega64 и Mega128), а Т/С1 такой же как Т/С3,Т/С4,Т/С5. В составе всех МК AVR сторожевой таймер. Он защищает наш контроллер от программного зависания. О нем поговорим в позже. Краткая картина того, как работают таймеры в МК AVR следующая. Для работы Т/С необходимы два регистра: один для счета (8 или 16 разрядов), другой для управления таймером-счетчиком. В последний регистр (регистр инициализации Т/С) записывают данное, которое определяет режим работы Т/С. Причем количество таких регистров может быть от одного до трех. После записи в регистр инициализации некоторой константы, Т/С начинает работать согласно заданному режиму, инкрементируя число записанное в регистре счета. 8-разрядный таймер-счетчик
Не будем лить воду, а перейдем к главному. 8-разрядные таймер-счетчики Т/С0 и Т/С2. Для нормальной работы имею следующие регистры: TCONTn,TCCRn,TCCRnA,TCCRnB,OCRn где n=0 или 2. TCONTn- счетный регистр; реверсивный счетчик. Этот тот регистр, состояния которого инкрементируется каждый такт тактового генератора от состояния 00000000 до 11111111. А после переполнения сбрасуется снова в ноль. OCRn - регистр сравнения. Во время работы Т/С, непрерывно происходит сравнения текущего состояния регистра TCONT и константы записанной в регистр OCRn. В случае совпадения можно организовать прерывание или изменить состояние вывода OCn. TCCRn,TCCRnA,TCCRnB – регистры предназначены для управления модулями Т/С. Формат этих регистров нужно смотреть в справочной литературе, поскольку для каждого МК AVR он может уникальным. Для примера рассмотрим формат этих регистров для МК Mega8535. Предположим мы работаем с таймером-счетчиком Т/С0 (Рисунок 1). Если вы посмотрите в документации на Mega8535, то увидите, что регистры TCCRnA и TCCRnB в ней отсутствуют. То есть для инициализации Т/С0 достаточно одного регистра TCRR0 (Рисунок 1). Рисунок 1. Формат регистра TCRR0 МК Atmega8535
Теперь, остановимся на каждом бите. FOC0 (7 бит) - Принудительное изменение состояния вывода OCn. Если сюда записать «1»,то вывод OCn будет изменятся в соответствии с установкой в битах COM01 и COM00. Прерывание при этом не генирируется. В режиме Fast и Phase Correct PWM этот бит должен быть установлен в «0». COM01, COM00 (5,4 бит) – эти биты определяют поведения вывода OCn при совпадении в режиме «Совпадение».
WGM01, WGM00(3,6 бит) – биты выбора режима работы таймера-счетчика Т/С0.
CS02, CS01, CS00 (2,1,0 биты) – управление тактовым сигналом для Т/С.
Например, нам нужно организовать мигание светодиода на выходе Porta B.3 (OC0) с задержкой 0.5 секунд. Теперь смотрим на выше приведенные регистр и его биты и ставим нолики и единички так, как бы мы хотели, чтоб работал наш Т/С0. Например, нам нужно организовать мигание светодиода на выходе Porta B.3 (OC0) с задержкой 0.5 секунд. Например, нам нужно организовать мигание светодиодов на выходе PortA с задержкой 250 микросекунд, в таком режиме: 00001111 11110000 00001111 11110000 …. Все очень просто, сначала инициализируем таймер-счетчик 0, а именно, выбираем режим работы Т/С0 и его запуск. Я выбрал режим работы совпадения таймера с регистром сравнения. Как только мой таймер достигнет значения, которое записано в регистре OCR0, произойдет прерывание и выполнится подпрограмма вывода данного на порт А. Прерывание будет происходить каждые 250мкс. Таким образом значения порта будет сменятся каждые 250мкс. Пусть вас не пугает граммотсткость программы, на самом деле в ней 50% места занимает таблица прерываний, которую вы просто копируйте перед началом написания программы. Сама программа начинается с метки RESET. Вот от туда и нужно начинать разборку программы. Текст программы:
.CSEG .ORG 0x0000 RJMP Reset .org INT0addr; External Interrupt 0 reti .org INT1addr;External Interrupt 1 reti .org OC2addr ; Timer/Counter2 Compare Match reti .org OVF2addr; Timer/Counter2 Overflow reti .org ICP1addr; Timer/Counter1 Capture Event reti .org OC1Aaddr; Timer/Counter1 Compare Match A reti .org OC1Baddr ; Timer/Counter1 Compare Match B reti .org OVF1addr; Timer/Counter1 Overflow reti .org OVF0addr ; Timer/Counter0 Overflow reti .org SPIaddr; SPI Serial Transfer Complete reti .org URXCaddr; USART, RX Complete reti .org UDREaddr ; USART Data Register Empty reti .org UTXCaddr; USART, TX Complete reti .org ADCCaddr; ADC Conversion Complete reti .org ERDYaddr; EEPROM Ready reti .org ACIaddr; Analog Comparator reti .org TWIaddr; Two-wire Serial Interface reti .org INT2addr ;External Interrupt Request 2 reti .org OC0addr; TimerCounter0 Compare Match rjmp P .org SPMRaddr ; Store Program Memory Read reti .org INT_VECTORS_SIZE; size in words reti RESET: ldi INIT1,low(RAMEND) ;инициализация стека out SPL,INIT1 ;----------------- ldi INIT1,high(RAMEND);----------------- out SPH,INIT1 ;----------------- ldi E,0xff ; инициализируем out ddrA,E ;----------------- ldi B,0xfА ; запись константы сравнения для Т/С0 out OCR0,B ;----------------- M:ldi C,0b00000010 ; инициализация Т/С0 out TIMSK,C ;----------------- ldi A,0b10001001 ;----------------- out TCCR0,A ;----------------- ldi A,0xf0
S: ;цикл ожидания sei rjmp S
P:swap А ;обмен тетродами out PORTA,А ;вывод результата на порт А reti
В этой программке вы можете побалыватся задавая различную тактовую частоту для Т/С0 (биты СS02-CS00) или меняя константу в OCR0 таким образом изменять частоту мирцания ваших диодов от 0 до нескоьких мегогерц (типа генератор импульсов).
Т/С могут работать в четырех основных режимах: -режим Normal; -режим СТС (сброс при совпадении); -режим Fast PWM; -режим Phase Correct PWM.
Для выбора одного из режимов служат биты WGMn2- WGMn0 регистров TCCRn (TCCRnA/TCCRnB)
Для выбора режима, опишим кратко каждый режим: Режим Normal - самый простой режим работы Т/С. Т/С работает в режиме счета, то есть при каждом тактовом сигнале счетчик инкриментирует свое значение. При переполнении (значения счетчика FF) T/C сбрасуется в ночальное значение. Режим СТС (сброс при совпадении) - в этом режиме Т/С работает также,только максимальное значение переполнения его определяется константой, которая находится в регистре сравнения OCRn. Каждый такт Т/С сравнивает свое новое значения со значением регистра OCRn, при совпеадении счетчик обнуляется. Режим Fast PWM -быстродействующий ШИМ, позволяет генирировать высокочастотный сигнал с широтно-импульсной модуляцией. Режим Phase Correct PWM - ШИМ с точной фазой. Как Fast PWM, предназначен для генерации сигналов широтно-импульсной модуляции. Однака счетный регистр здесь работает как реверсивный счетчик (инкрементирует значение пока не дошел до верхушки, а потом декрементирует , пока не дойдет к самому низу). Из названия режима видно, что используют этот режим в случаях , когда нужна более точная фаза сигнала.
Чтобы новичек не вступил, не начал записывать код по адресу векторов прерывания, лучше записывать всю таблицу. Либо же указывать дерективой .ORG с какой ячейки начать писать. Лично я привык видеть перед собой всю таблицу