Повторим: для того, чтобы манипуляции со счетными регистрами были успешными, при чтении необходимо сначала прочесть младший байт TCNTxL, потом старший TCNTxH, при записи сначала записать старший байт TCNTxH, потом младший TCNTxL. Аналогичное правило действует для всех 16-разрядных регистров Timer 1, которые мы будем рассматривать далее, за исключением регистров управления TCCR1A и TCCR1B, которые по сути есть два раздельных регистра, а не один.
* * *
Напомним, что если вам попадется старый «классический» AT90S2313, то приведенную здесь программу можно использовать для него без изменений.
Способ отсчета времени с помощью прерывания таймера по сравнению более понятен и удобен, чем с предзагрузкой значений в счетный регистр, — хотя бы потому, что число, с которым сравнивается содержимое счетных регистров, можно загружать только один раз. Если потом запустить таймер, то больше об этом можно не думать — все будет происходить автоматически. Поскольку в Tiny2313 и большинстве моделей
* * *
Подробности
Прерывание по сравнению происходит в момент, когда счетчик досчитывает до наперед заданного значения, хранящегося в специальном регистре сравнения. Есть одна тонкость, связанная с этим режимом. Входной тактовый сигнал счетчика обычно делится в соответствии с заданным коэффициентом деления (в наших примерах это 1/64). Поэтому в нашем случае каждое состояние счетчика остается неизменным в течение 64 тактов процессора. Так в какой именно момент возникает прерывание — сразу, как только счетчик досчитал до заданного значения, или в момент, когда это заданное значение в счетчике должно уже смениться следующим? Если предположить, что в AVR все устроено, как на рис. 16.13, в, то имеет место первый случай — счетчик начинает новый отсчет с первого системного такта сразу после совпадения величин. Тогда состояния счетчика получаются неравноправными: все они длятся по 64 системных такта (в соответствии с выставленным коэффициентом предделителя), кроме последнего, который длится один системный такт независимо от коэффициента деления. Так это было устроено в «классической» серии AVR. А вот для счетчиков семейств Меда и Tiny все иначе: там событие совпадения наступает по последнему такту при совпадении, в момент, когда состояние счетчика должно уже смениться. Поэтому, если вы зададите в регистрах сравнения, к примеру, число 2, то при коэффициенте деления 1/64 Timer 1 в МК AT90S2313 отсчитает до возникновения прерывания 129 системных тактов (или примерно 2 такта входной частоты счетчика), а в МК ATtiny2313 — 192 системных такта (ровно 3 такта входной частоты). Таким образом, в первом случае коэффициент деления входной частоты таймера в режиме сравнения равен установленному числу N плюс один такт системного генератора, а во втором — числу
* * *
Причем в этом режиме можно упростить программу предельно — один из выводов контроллера (при прерывании с применением регистра сравнения
Для того чтобы установить режим сравнения, нужно вместо прерывания по переполнению разрешить прерывание по сравнению
Есть в этом деле и еще один нюанс. Что будет происходить с таймером после того, как значения в счетных регистрах и регистрах сравнения станут одинаковыми (кроме того, что произойдет прерывание)? Ясно, что тут могут быть варианты: таймер может продолжить счет, обнулиться, установиться в какое-то наперед заданное значение и т. п. Это поведение настраивается — для выбора режима обнуления (чтобы после сравнения таймер пришел бы в исходное состояние) следует установить бит WGM12 (в «классической» версии МК он назывался CTC1) — бит номер 3 в регистре TCCR1B.
Программа с учетом всего сказанного будет выглядеть таким образом: