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

Глава 7. Система команд АVR Аналогично выглядят команды чтения : ld temp , -Z / * с преддекрементом, чтение из ячейки с адресом Z-l , после выполнения команды регистр Z = Z- l * / ld temp , Z+ / * с постинкрементом, чтение из ячейки с адресом Z , после выполнения команды регистр Z = Z+l * / 185 Листинг 7 .9 иллюстрирует, как можно в цикле записать 1 6 ячеек памяти подряд одним и тем же значением из temp, начиная с нулевого адреса фрагмента памяти с адресами $ 1 0 0 - $ 1 FF (zн = 1 ) . ldi ZH, 1 clr ZL LoopW : st Z+ , temp ; сложили в память cpi ZL , 1 6 ; счетчик до 1 6 brne LoopW То же самое можно делать с помощью регистров х и У (соответствующий пример приведен в главе 13 в программе вывода на дисплей с I 2 С-интерфейсом) . Еще одна важная команда переноса данных - инструкция lpm, которая позволяет прочесть произвольный байт из памяти программ. Напомню, что большинство раз­ новидностей МК, в том числе и АVR, имеют гарвардскую архитектуру, когда па­ мять программ отделена от памяти данных, и в первую контроллер самостоятельцо ничего писать не может (кроме случая самопрограммирования). Потому хранение в памяти программ тех констант, которые никогда не будут изменяться, прямо ре­ комендуется разработчиками АVR, за много лет так и не сумевшими окончательно решить проблему безопасного хранения данных в EEPROM (см. главу 10) . Вот типичная задача такого рода: пусть контроллер осуществляет управление се­ мисегментным индикатором в динамическом режиме, когда в каждом такте прихо­ дится выводить разные цифры. Выстраивать рисунки (битовые маски) этих цифр каждый раз - замучаешься, и программа получится очень громоздкая и совершен­ но нечитаемая . Проще их «нарисовать» единожды и расположить по порядку (от нуля до 9) в любом месте программы (удобно- в начале сразу после векторов прерываний). Дать понять компилятору, что это особая область памяти, которая его не касается и должна быть перенесена без изменений, можно с помощью директи­ вы . dЬ, а чтобы потом можно было найти эту область, ее следует пометить обычной меткой: N_mas k : ;маски цифр на семисегментном индикаторе . dЬ оьоо 1 1 1 1 1 1 , оьо о о оо 1 1 0 , оьо 1 0 1 1 01 1 , оьо 1 0 0 1 1 1 1 , оьо 1 1 0 0 1 1 0 , оьо 1 1 0 1 1 0 1 , оьо 1 1 1 1 1 0 1 , оьо о о оо 1 1 1 , оьо 1 1 1 1 1 1 1 , оьо 1 1 0 1 1 1 1 Метка может располагаться и до, и после директивы . dЬ. Для лучшего понимания, как размещаются байты данных в памяти программ, следует учесть, что они, как и команды, объединяются здесь в двухбайтовые слова. Если число байтов, указанных

RkJQdWJsaXNoZXIy MTExODQxMg==