Рассмотрим некоторые тонкости в обращении к 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, то прерывания должны быть запрещены на время обращения из основной программы.