Давайте попробуем ещё раз. Придерживайтесь следующих советов.
1) Используйте для всего мнемонические имена.
а) Поименуйте регистры
б) Поименуйте ячейки памяти
в) Поименуйте порты ввода/вывода
2) Используйте коментарии везде где это возможно. ( не надо писать "сложить r14 и r15" это и так видно. Описывайте смысл того, что вы делаете)
приведу пример моего написания
В начале идёт подробное описание проекта с указанием версии и распиновки сигналов.
Код
;****************************************************************
;* *
;* Приборный щиток для трактора "Беларусь". *
;* Версия 1.16. *
;* *
;* На шаговых двигателях. Шесть приборов. *
;* Без использования внешних регистров. *
;* Цифровая фильтрация входных данных. *
;* *
;* *
;* PC2 - ADC2 - Температура охладителя. *
;* 3 - ADC3 - Давление масла в двигателе. *
;* 4 - ADC4 - Давление воздуха в пневмосистеме. *
;* 5 - ADC5 - Давление масла в КПП. *
;* 6 - ADC6 - Уровень топлива. *
;* 7 - ADC7 - Напряжение. *
;* *
;* *
;* Двигатель MS1. *
;* PB1 - Общий провод обмоток (-). *
;* PB0 - Провод обмотоки 1 (1+). *
;* PB2 - Провод обмотоки 2 (2+). *
......
Далее объявление имён портов и констант
Код
.equ SCL = pb5; Для I2C (Двигатель 5)
.equ SDA = pb4; Для I2C (Двигатель 5)
.equ Fclk = 8000; Частота микрокотроллера 8МГц
.equ Tclk = 125; Период микрокотроллера 125нс
Далее объявление регистров (обратите внимание на объявление регистра флагов r15 и рабочие регистры wl,wh. Рабочие регистры не имею специального предназначения и используются для промежуточного хранения. Я даю всегда такие наименования из проекта в проект. Поэтому в тексте сразу чётко вижу, что данный регистр - рабочий (work). Я его могу изменить во всём проекте изменив только одну строчку.
Код
.def Faz0 = r8; Фаза в которой находится двигатель 0
.def Faz1 = r9; Фаза в которой находится двигатель 1
....
.def bitp = r15;
.equ bendc = 0 ; Конец расчётам в прерывании
.equ bwdr = 1 ; Сброс от WatchDog-а
.equ boff = 2 ; Возврат по провалу питания
....
.def wl = r24
.def wh = r25
Объявление памяти
Код
.dseg
Nint: .byte 1 ; Счётчик прерываний
speed: .byte 1 ; скорость движения стрелки
...
Далее у меня идут вектора, подпрограммы и прерывания.
ну например подпрограммы
Код
;========================================================================
; Инициализация вторичных буферов произвольной длины.
;------------------------------------------------------------------------
; Входные регистры: wl - номер буфера, Y - адрес буфера
; Выходные регистры: Y - адрес следующего буфера
; Портятся регистры: wh, wil, wih, Zl, Zh, Xl, Xh, r0, r1
; Занято стэка : -
bufinit:
ldi Xh,0
mov Xl,wl ; номер канала в Xl
lsl Xl ; умножить на 512
ldi Zl,low(TabStrel*2); Загрузить адрес таблицы пересчёта
ldi Zh,high(TabStrel*2)
add Zh,Xl ; найти начало таблицы данных
lpm wh,Z
tst wh
breq bufinit0
ldi wh,$ff ; В начале обрыв !!!
....
Приведу пример инициализации примерно аналогичной вашей
Код
.if chip == 88
.equ kadcsra = exp2(aden)+exp2(adsc)+exp2(adate)+exp2(adps1)+exp2(adps2)
.else
.equ kadcsra = exp2(aden)+exp2(adsc)+exp2(adfr)+exp2(adps1)+exp2(adps2)
.endif
; Для внутреннего АЦП
;.equ kadmux = exp2(refs1)+exp2(refs0)+exp2(adlar)
; Для внешнего АЦП
.equ kadmux = exp2(adlar)
ldi chan,0
ldi wl,kadcsra+exp2(adif)
.if chip == 88
sts adcsra,wl; сбросить флаг завершения преобразования
.else
out adcsr,wl; сбросить флаг завершения преобразования
.endif
mov wl,chan
subi wl,-2 ; начать с канала 2
ori wl,kadmux
.if chip == 88
sts admux,wpl; включить новый канал
.else
out admux,wpl; включить новый канал
.endif
Вы выработаете свой стиль, но вы должны сразу видеть что именно происходит.
Как понятнее скажите? Или так
ldi r16,0b10000110 ;установка режима АЦП
out $06,r16
Или так, к примеру?
ldi wl, (ADEN<<1)+(ADPS1<<1)+(ADPS2<<1)
out ADCSR,wl
sbis $06,4
или
sbis ADCSR,ADIF
lds r16,$64
sts $74,r16
или так?
.equ lenbuf = $10
...
.dseg
InBuf: .byte lenbuf
OutBuf: .byte lenbuf
....
lds wl,InBuf
sts OutBuf,wl