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

Глава 9. Программирование таймеров reti lpm temp , Z+ ; в temp - число из таблицы out OCRlAН, temp2 ; выводим старший out OCRlAL, temp ; выводим младший adiw countO , l ; увеличиваем счетчик 263 Прерывание Timer l Compare В идентично, только все А (и соответствующие пози­ ции битов) меняются на в и наоборот. Обратите внимание на два в общем-то лиш­ них усложнения : во-первых, отсчет позиций в таблице ведется отдельным двухбай­ товым счетчиком count l : countO, хотя у нас уже есть регистр z, который так и так отсчитывает позицию, начиная с удвоенного адреса метки N_s in (здесь мы приме­ нили модификацию команды lpm с постинкрементом) . Мы могли бы сравнивать непосредственно значение регистра z с нужным числом вместо отдельного счетчи­ ка, но здесь это сделано специально, чтобы не запутаться в сравнениях удвоенного двухбайтового адреса метки, к которому прибавляется двухбайтовое число текуще­ го адреса. Если сократить количество значений в таблице до величины меньше бай­ та (например, вдвое - до величины 1 56, при этом установку следует менять не в каждом прерывании, а в каждом втором), то процедура сравнения упростится, но не забудьте, что адресный регистр z все равно останется двухбайтовым. Во-вторых, мы отводим целый лишний регистр temp2 для хранения нуля, который записывается в старший байт регистра сравнения oCRlAН. Дело в том, что из-за бу­ феризации, о которой мы говорили ранее, всегда следует записывать регистр OCRlAН первым, даже если он равен нулю или другой константе. И в нашем случае жестких лимитов времени желательно загрузку обоих регистров делать строго друг за дру­ гом: пока мы будем извлекать байт из таблицы, счетчик продолжает считать, и чем дольше мы возимся, тем вероятнее, что момент перезагрузки счетчика вклинится между записью старшего и младшего байтов. Программа занимает 466 байтов в памяти, из которых две трети - · таблица значе­ ний синуса. Она будет работать почти без изменений в любом контроллере с па­ мятью 8 кбайт и менее, в котором име е тся Timer l (или другой таймер с двумя кана­ лами). Изменения коснутся только строк инициализации и обнуления выводов пор­ та, соответствующих OC l A и OC l B, - в других контроллерах они находятся на других местах (см. листинг 9 . 3) . Частота контроллера 8 МГц выбрана универсаль­ ная, на ней работают все модификации контроллеров, даже семейства Classic . Для проверки загрузите программу из архива (файл PWM_OC1_Si n .asm ) в контрол­ лер, поменяв в ней предварительно младшие три бита cs12 : cs 1 0 байта, загружаемо­ го в регистр тссюв, - вместо значения 0 0 1 (предделитель 1 : 1 ) подставьте значение 1 0 0 ( 1 :256) или 1 0 1 ( 1 : 1 024), и подключите к выводам 1 5 и 1 6 ATmega8 светодиоды. Они будут по очереди медленно менять яркость свечения от нуля до максимума и обратно. Если вы будете применять эту программу для инвертора, как описано далее, то не забудьте восстановить значение 0 0 1 и проверьте значение частоты на каждом из выводов - оно должно быть ровно 50 Гц. Как изменять значение часто­ ты синуса для других применений, вы уже поняли: можно менять тактовую частоту контроллера, можно задавать другой коэффициент деления на входе таймера, мож-

RkJQdWJsaXNoZXIy MTExODQxMg==