Ревич, Ю.В. Программирование микроконтроллеров 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. Второй способ проще (хотя сама процедура подсчета и сложнее), и его следует применять тогда, когда функция подсчета времени - основная, и других громоздких действий (кроме, возможно, индикации, на которой мы оста новимся далее) МК не производит.
Made with FlippingBook
RkJQdWJsaXNoZXIy MTExODQxMg==