Ну, для начала закиньте в несколько регистров наиболее часто используемые значения (0, 1, 2, 0x80, 0xFF и т.д.)
Код: Выделить всё
.def _0=r0
.def _FF=r1
.def temp=r16
.cseg
clr _0 ; можно не писать, т.к. при сбросе там 0, но это считается не приличным
clr _FF ;
dec _FF
Теперь это будет выглядеть так:
Код: Выделить всё
ldi temp, high(RAMEND); инициализация стека
out SPH, temp;
out SPL, _FF; SPL всегда равно этому значению во всех моделях, где память больше 255 байт (>=256)
; а если память меньше 256 байт, то можно не инициализировать SPH (его скорее всего и не будет как такового)
;**************************************************************
out DDRD, _0 ;Д на вход. Можно не писать, т.к. после сброса по умолчанию на вход
out PORTD, _FF ;подтягиваем Д к пит через рез
out DDRC, _FF ;порт С на вых
;**************************************************************
MAIN:
rcall START
ldi temp, 0b10
out PORTC, temp ;зажзигаем лед, 1 ножка порта С
;Здесь Вы, кстати, меняете весь порт, что также считается не айс. Но здесь это не критично. Правильнее использовать команды чтения-модификации-записи
;В Вашем случае можно эти две команды заменить одной out PORTC, _FF (если на остальных ногах ничего не висит)
rcall SUKA
rcall START
out PORTC, _0 ;гасим лед, 1 ножка порта С
; аналогично. Чтение-модификация-запись
rcall SUKA
rjmp MAIN
Теперь задержка.
Код: Выделить всё
PUKA:
ldi r31,10 ;задержка. Инициализацию r30 нулем можно сделать в самом начале,но можно и не делать. В конце цикла он также = 0
Loop1:
sbiw Z, 1
brne Loop1
ret
P.S. Маленькое отступление на тему когда можно не инициализировать регистры нулем, т.к. при старте они = 0. Дело в том, что здесь регистры - та же память (к ним можно даже обратиться через команды записи и чтения в память) и они после сброса (и после выключения некоторое время, совсем чуть-чуть) помнят последнее свое состояние. Если Вы в программе пользуете их с нулевым значением и нигде дальше этот 0 не меняете, то можно не парится и не инициализировать их. А если их значение меняется, то после сброса в них окажется последнее значение, которое может отличаться от 0. И далее Ваша программа будет уже работать не правильно. Аналогично - переменные в памяти и их начальная инициализация.
Некоторые регистры периферии сбрасываются в начальное положение при рестарте автоматически
Пример - написанная мной задержка. Если во время ее выполнения вы сбросите контроллер (подачей 0 на ножку reset, например) то в регистре r30 может оказаться не нулевое значение. и первая задержка при следующем цикле работы контроллера будет немного меньше. Но только первая и Вы это вряд ли заметите. Если у Вас дребезг обрабатывается "впритык", можно на единицу увеличить старший регистр (r31=11), чтобы исключить ложные срабатывания.
P.P.S. Зачем было делать вложение, если Вы весь текст из этого вложения привели здесь? Также Вам бы с rjmp-ами разобраться.. Положили сюда больше, чем надо. И скажу по секрету, антидребезг Вы не совсем правильно организовали. Задержку из основного цикла нужно убрать. Оставить только ту, что по факту нажатия. Вообще, лучше для кнопки задействовать внешнее прерывание. Также забыли вектора прерываний обозначить (Хотя здесь можно и сразу код писать, но лучше как-то с ними). Да и так.. Поднакарулесели Вы..
В общем так примерно должно быть:
Код: Выделить всё
.def MASK_PIN_LED=r20
...
.cseg
...
ldi MASK_PIN_LED, 0b10
...
MAIN:
in temp, PORTD
andi temp, (1<<3)
brne Main
in temp, PORTC
eor temp, MASK_PIN_LED; меняем значение светодиода на противоположное
out PORTC, temp; отправляем значение в порт
ldi r31, 10 ;исключаем дребезг
Loop1:
sbiw Z, 1
brne Loop1;
rjmp Main
А остальные пуки, куки и суки можно выкинуть.