Переключение между массивами. Б.О. v2.2
Автор: Сегодня поговорим о том, как задать в одной программе несколько массивов и переключаться между ними. Для начала уясним такую вещь: при сбросе (то есть, обработке прерывания Reset), содержимое регистров не стирается. Это позволяет нам использовать внешний вывод микросхемы "Reset" как переключатель между какими-то режимами программы. То есть, мы можем повесить на этот вывод кнопочку. Для того чтобы эта кнопочка стала переключателем, мы должны выделить какой-то регистр под счетчик сбросов. То есть, при каждом нажатии на кнопочку "ресет", содержимое регистра будет увеличиваться на 1. Вообще говоря, это будет происходить не только по нажатию на кнопочку, но и по другим причинам, вызывающим сброс (кроме отключения питания). Но остальные причины можно отнести скорей к аварийным, и их учитывать не будем. Итак, в самом самом начале выделим регистр. Пусть его зовут ResCnt: .def ResCnt=R21 Теперь можно прямо на метку ресет поставить инкремент этого регистра: Reset: inc ResCnt Можно - но не нужно. Ибо любая кнопочка имеет такую неприятную вещь - дребезг. А дребезг, в свою очередь, имеет всю остальную конструкцию и ее конструктора вместе взятых. Благодаря дребезгу, при единичном нажатии на кнопку, сброс может произойти несколько раз подряд. При этом, счетчик сосчитает все эти разы. Если команда инкремента будет стоять сразу по метке. А если не сразу? Правильно! Нужно поставить команду инкремента через задержку. Тогда ложные срабатывания, промежуток между которыми меньше времени задержки, не приведут к инкременту счетчика… Reset: ldi Temp1,0 ldi Temp2,0 l_res: dec Temp1 brne l_res dec Temp2 brne l_res inc ResCnt Ну вот что-то типа того. Теперь надо соорудить несколько массивов. Желательно, чтоб их количество было кратно какой-нибудь степени двойки. Пусть их будет четыре, и их зовут: Array0, Array1, Array2, и Array3. В каждый из массивов будет записана своя программа работы светодиодов. Допустим так:
0 - справа-налево Пишем: Array0: .db 0b10000000,0b01000000 .db 0b00100000,0b00010000 .db 0b00001000,0b00000100 .db 0b00000010,0b00000001 .db 0,0 Array1: .db 0b00000001,0b00000010 .db 0b00000100,0b00001000 .db 0b00010000,0b00100000 .db 0b01000000,0b10000000 .db 0,0 Array2: .db 0b10000001,0b01000010 .db 0b00100100,0b00011000 .db 0b00011000,0b00100100 .db 0b01000010,0b10000001 .db 0,0 Array3: .db 0b10000000,0b01000000 .db 0b00100000,0b00010000 .db 0b00001000,0b00000100 .db 0b00000010,0b00000001 .db 0b00000001,0b00000010 .db 0b00000100,0b00001000 .db 0b00010000,0b00100000 .db 0b01000000,0b10000000 .db 0,0 Ну, примерно так. Объясняю насчет нулей, которые мы ставим в конце каждого массива: ноль - это флажок окончания массива. Когда программа читает этот элемент - она не выводит его на индикацию, а возвращается к началу массива.
Ну да ладно, давайте писать прогу.
Точнее, ту ее часть, которая отвечает за выбор массива и его чтение. SelectArray: ;выбор массива andi ResCnt,0b00000011 ;отсечка лишних разрядов сч. сбросов cpi ResCnt,0 ;сравнение счетчика сбросов с конст. brne Tst1 ;если не равно - след. проверка ldi ZH,High(Array0*2) ;загрузка начального адреса массива ldi ZL,Low(Array0*2) rjmp ReadArray Tst1: cpi ResCnt,1 brne Tst2 ldi ZH,High(Array1*2) ldi ZL,Low(Array1*2) rjmp ReadArray Tst2: cpi ResCnt,2 brne Tst3 ldi ZH,High(Array2*2) ldi ZL,Low(Array2*2) rjmp ReadArray Tst3: ldi ZH,High(Array3*2) ldi ZL,Low(Array3*2) rjmp ReadArray ReadArray: ldi Temp,0 ;прибавление относит. адреса add ZL,Temp1 adc ZH,Temp lpm ;загрузка из ПЗУ mov Temp,R0 ;копирование в РОН cpi Temp,0 ;пороверка на нулевой элемент breq Init ;если нулевой - в начало inc Temp1 ;увеличение относит адреса на 1 rjmp Output ;перейти на вывод в порт Init: ldi Temp1,0 ;загрузить нач. значение rjmp SelectArray Output: out PortB,Temp ;вывод в порт reti ;выход из обработчика Коротко о том, что здесь происходит.
Поскольку мы переключаемся между четырьмя массивами -
нам нужно только 2 двоичных разряда (2^2 = 4).
Поэтому, все разряды старше 2-го мы хладнокровно вырезаем командой По сравнению с предыдущей версией, теперь при чтении массива мы также проверяем каждый элемент на равенство нулю. Как вы помните, ноль у нас означает окончание массива. Как только находится такой элемент - программа переходит по метке Init, которая скидывает счетчик элементов массива и все начинается по новой.
Ну вот и все! <<--Вспомним пройденное----Поехали дальше-->>
|
|
|||||||||||||||
|
||||