Ревич, Ю.В. Программирование микроконтроллеров AVR: от Arduino к ассемблеру

Глава 9. Программирование таймеров 233 значение, но в таком режиме таймеры, естественно, эксплуатировать бессмыс­ ленно. ПОДРОБНОСТИ Следует учитывать , что число тактов (таймера, а не контроллера) , которое отсчитает таймер до наступления события сравнения, на единицу больше заданного в регистрах сравнения числа. Это хорошо иллюстрируется последним примером - загрузив 1, вы считаете до 2-х (первый такт: счетный регистр = О, второй : счетный регистр = регистру сравнения = 1 ) . Поэтому и надо задавать число сравнения на единицу меньше необ­ ходимого числа отсчетов. Для величин в регистре сравнения порядка десятков тысяч , задаваемых в рассмотренном только что примере, ошибка будет сравнима с погреш­ ностью кварцевого резонатора , потому там это можно и не учитывать (см . далее разд. «Точная коррекция времени>>) . Подчеркнем : загружая в регистры сравнения какое-либо число, вы задаете именно длительность импульса на выходе ОС1 А, а не частоту переключения . Так, в послед­ нем случае, загружая 1, вы считаете до двух и таким образом увеличиваете период исходной частоты (0,25 мкс) вдвое , получая длительность импульса 0,5 мкс. По­ скольку период частоты складывается из двух длительностей , то и выходит частота не 2, а 1 МГц. Это нужно учитывать при подсчетах - если вызывать прерывание сравне­ ния (как показано далее) , то частота его возникновения будет обратной величиной именно длительности (в нашем случае 2 МГц) , а если рассматривать все это как гене­ ратор частоты на выводе, то частота определяется периодом переключения и будет равна 1 МГц. (Конечно, прерывания, возникающие с частотой 2 МГц, при 4-х МГц так­ товой частоты на практике использовать невозможно, потому это уточнение приведе­ но просто в качестве иллюстрации) . Однако применение вывода ОС 1А в автоматическом режиме решает лишь одну достаточно узкую задачу генерации частоты для внешнего потребителя. Для того чтобы выполнять еще какие-либо действия, необходимо разрешить соответствую­ щее прерывание, которое в таком случае носит название TIМl_сомРА (Timer 1 Compare Match А). Это можно сделать установкой бита ocrElA в регистре тrмsк: ldi temp, ( l<<OCIElA) ; разрешение прерывания TIMl_COMPA out TIMSK , temp Теперь сформулируем задачу создания электронных часов. Мы имеем прерывание TIМl_СОМРА, возникающее раз в секунду (для этого, еще раз напоминаю, в регистр сравнения загружается значение 62 499). Для отсчета минут достаточно создать от­ дельный счетчик до 59, а часов - еще один до 23 . Однако значение времени обыч­ но представляют в ВСD-формате (причем для индикации нужен распакованный формат) . Тут напрашиваются два варианта: или при необходимости вызывать каж­ дый раз процедуру преобразования hех-значения в BCD (она описана в главе 8), или усложнить процедуру подсчета времени, заранее разместив единицы и десятки часов, минут и секунд в отдельных регистрах. Первый способ целесообразнее в тех программах, где счет времени - не основная функция, и наблюдается дефицит свободных регистров, - тогда для подсчета времени потребуются всего три гло­ бальные переменные : для часов, минут и секунд, а распакованные значения можно хранить в SRAM. Второй способ проще (хотя сама процедура подсчета и сложнее), и его следует применять тогда, когда функция подсчета времени - основная, и других громоздких действий (кроме, возможно, индикации, на которой мы оста­ новимся далее) МК не производит.

RkJQdWJsaXNoZXIy MTExODQxMg==