Страница 1 из 1
в эмуляторах не работает стек ATmega16 что яделаю не так?
Добавлено: Пн фев 16, 2009 16:17:44
Qwq
Здравствуйте!
Почему-то из подпрограммы не возвращает, а отправляет в начало исполняемого сегмента.
что я сделал не так?
В железе не пробывал ибо пока не на чем.
код ниже.
Длинные коды оформляйте вложением. Паятель.
Re: в эмуляторах не работает стек ATmega16 что яделаю не так
Добавлено: Пн фев 16, 2009 18:38:20
smac
Qwq писал(а):Здравствуйте!
Почему-то из подпрограммы не возвращает, а отправляет в начало исполняемого сегмента.
что я сделал не так?
Вот смотрите здесь
Код: Выделить всё
brne sensorinuse ;то обрабатываем это самое чегонибудь
Вы переходите на метку sensorinuse, где есть такой код
Код: Выделить всё
cpi sensor,1 ; если считали 1
brne s1 ; тогда обрабатываем функцией S1
cpi sensor,2 ; Если считали 2
brne s2 ; тогда обрабатываем функчией S2
где s1 и s2 фактически подпрограммы.
По выходу из s1 иди s2 выполняетс ret, которая вынимает из стка адрес возврата, поскольку в стеке у вас ничего нет, то адрес возврата неизвестен, и возврат может быть куда угодно.
Т. е. s1 и s2 Вы вызывете некорректно, а сдедовательно дальнейшие действия уже смысла не имеют. Корретктный вызов подпрограмм делается так:
Вообще на мой взгляд програма бездумно написана, на самом деле чтобы заработа править много надо.
Добавлено: Пн фев 16, 2009 18:46:39
Caturday
Таблица обработки прерываний неправильна - раз, стек по-моему надо инитить так:
Код: Выделить всё
ldi Temp,low(RamEnd*2)
out SPL,temp
ldi Temp,high(RamEnd*2)
out SPH,temp
два
Добавлено: Пн фев 16, 2009 20:01:37
Pooher
Таблица обработки прерываний неправильна - раз, стек по-моему надо инитить так:
Код:
ldi Temp,low(RamEnd*2)
out SPL,temp
ldi Temp,high(RamEnd*2)
out SPH,temp
Чушь полная
Код: Выделить всё
MAIN замкнутая функция в которой мы все делаем
main:
in sensor,PinB ;проверяем сенсоры
clr temp, 0 ; обнуляем temp
cpse sensor, temp ;если sensor =0, то пропускаем следующую команду
RCALL sensorinuse ;то ВЫЗЫВАЕМ ПОДПРОГРАММУ sensorinuse
rjmp main
И здесь тоже подправить:
Код: Выделить всё
sensorinuse:
cpi sensor,1 ; если считали 1
breq s1 ; тогда обрабатываем функцией S1
cpi sensor,2 ; Если считали 2
breq s2 ; тогда обрабатываем функчией S2
ret
s1:
ldi temp, 0b00000110 ; оба мотора вперед
rcall usemotor
ret
s2:
ldi temp, 0b00001001 ; оба мотора назад
rcall usemotor
ret
В данном случае ret в s1 и s2 осуществляют выход из подпрограммы sensorinuse.
Добавлено: Вт фев 17, 2009 14:17:15
Qwq
Всем обгромное спасибо. сам бы я очень долго пытался понять что не так...