Базовый счетчик (Counter Unit)
Основной частью 16-разрядного таймера/счетчика 1 является реверсивный базовый счетчик TCNTn. Его блок-схема изображена на следующем рисунке 5.4:

Рис. 5.4. Блок-схема базового счетчика.
Расшифруем сигналы изображенные на блок-схеме.
Count – инкремент или декремент величины базового счетчика TCNTn.
Direction – Выбор направления счета.
Clear – очистка базового счетчика TCNTn.
clkTn – тактирующий сигнал таймера/счетчика 1.
TOP – Сигнализирует, что счетчик достиг максимального значения.
BOTTOM – Сигнализирует, что счетчик достиг нулевого значения.
16-разрядный счетчик состоит из двух 8-разрядных регистров TCNT1H:TCNT1L, причем обращение к старшему регистру происходит косвенно, через временный регистр TEMP. Это сделано для того, чтобы CPU могло считывать/записывать и старший и младший байты этого регистра одновременно. Если основная программа и подпрограммы обработки прерываний используют обращение к регистрам посредством TEMP, то прерывания должны быть запрещены на время обращения из основной программы. Более подробно этот вопрос описан в разделе «Обращение к 16-разрядным регистрам».Отметим, что запись в регистр TCNT во время работы счетчика может дать непредсказуемые результаты.
В зависимости от режима работы значение базового счетчика может быть очищено, увеличено, или уменьшено на каждом цикле тактирования.
На рисунке 5.4 представлена блок-схема базового счетчика. Элементы, которые непосредственно не являются частью базового счетчика, обозначены серым цветом.
Как уже отмечалось, таймер/счетчик 1 может получать тактовый сигнал от СК, СК после предварительного делителя и от внешнего вывода. Способ тактирования определяется битами CSn2:0 (Clock Select). Если биты CSn2:0 равны нулю – счетчик остановлен. Однако значение TCNT может быть изменено ЦП в независимости от тактирующего сигнала счетчика clkTn.
Режим работы таймера/счетчика определяется установкой битов режима генерации сигнала (Waveform Generation mode) WGMn3:0. Они расположены в регистрах управления таймера/счетчика А и В (TCCRnA и TCCRnB)
Флаг переполнения таймера/счетчика TOVn (Timer/Counter Overflow) устанавливается в соответствии с режимом работы и используется для генерации прерывания по переполнению базового счетчика.
Обращение к 16-разрядным регистрам
Рассмотрим некоторые тонкости в обращении к 16-разрядным регистрам таймера/счетчика 1. Регистры TCNTn, OCRnA/B/C и ICRn – 16-разрядные и обращение к ним происходит через 8-разрядную шину данных процессора. Для записи или чтения этих регистров необходимо две операции чтения/записи. Обращение к старшему 8-разрядному регистру происходит косвенно, через временный регистр TEMP. Это сделано для того, чтобы CPU могло считывать/записывать и старший и младший байты этого 16-разрядного регистра одновременно. Если основная программа и подпрограммы обработки прерываний используют обращение к регистрам посредством TEMP, то прерывания должны быть запрещены на время обращения из основной программы.
На примере 16-разрядного регистра базового счетчика рассмотрим правильную последовательность операций записи/чтения.
Запись в таймер/счетчик 1 - TCNT1
Когда процессор производит запись в старший байт (TCNT1H) записываемые данные размещаются в регистре TEMP. Затем, когда CPU производит запись в младший байт (TCNT1L) данные младшего байта объединяются с байтом данных регистра TEMP и все 16 битов одновременно переписываются в регистр таймера/счетчика TCNT1. Следовательно, при 16-разрядных операциях обращение к старшему байту (TCNT1H) должно выполняться первым. При использовании таймера/ счетчика 1 в качестве 8-разрядного таймера достаточно производить запись только младшего байта.
Чтение таймера/счетчика 1 - TCNT1
Когда процессор считывает младший байт (TCNT1L), то содержимое TCNT1L направляются непосредственно в CPU, содержимое старшего байта (TCNT1H) размещается в регистре TEMP и при считывании старшего байта (TCNT1H) его содержимое процессор принимает из регистра TEMP. Следовательно, при 16-разрядных операциях первым должно выполняться обращение к младшему байту (TCNT1L). При использовании таймера/ счетчика 1 в качестве 8-разрядного таймера достаточно производить запись только младшего байта.
Теперь можно сформировать основное правило для операции чтения/записи 16-разрядных регистров таймеров/счетчиков.
-
-
Для записи 16-разрядного регистра старший байт должен быть записан перед младшим;
-
Для чтения 16-разрядного регистра младший байт должен быть прочитан перед старшим.
-
Рассмотрим пример обращения к регистру базового счетчика TCNT1. Такой же принцип используется для обращения к регистрам OCRnA/B/C и ICRn.
...
; Запись в TCNTn значения 0x01FF
ldi r17,0x01
ldi r16,0xFF
out TCNT1H,r17
out TCNT1L,r16
; Чтение из TCNTn в r17:r16
in r16,TCNT1L
in r17,TCNT1H
...
Как отмечалось ранее – если основная программа и подпрограммы обработки прерываний используют обращение к регистрам посредством TEMP, то прерывания должны быть запрещены на время обращения из основной программы.
