|
ATmega8 адресс метки |
|
|
|
Jun 2 2011, 17:45
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Здравствуйте форумчани! Нуждаюсь в вашей помощи по АВР студии (Ассемблер). MK ATmega8
Есть команда ICALL она делает вызов подпрограммы по адресу указаному регистром Z (r31:r30)
Допустим есть код с несколькими подпрограммами с метками, например sb1, sb2, sb3, и команда вызова ICALL Подскажите как получить адрес метки(ок), что бы задать их в регистр Z.
Сообщение отредактировал Shadovv13 - Jun 2 2011, 17:45
|
|
|
|
|
Jun 2 2011, 18:03
|
Гуру
     
Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047

|
Цитата(Shadovv13 @ Jun 2 2011, 21:45)  Есть команда ICALL она делает вызов подпрограммы по адресу указаному регистром Z (r31:r30)
Допустим есть код с несколькими подпрограммами с метками, например sb1, sb2, sb3, и команда вызова ICALL Подскажите как получить адрес метки(ок), что бы задать их в регистр Z. Если побайтово - то ldi ZH,high(адрес) ldi ZL,low(адрес). Или, если это таблица - описать метки как .dw адрес1,адрес2... и загружать из таблицы.
|
|
|
|
|
Jun 2 2011, 18:14
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
rx3apf Вы не так поняли! Код Label1: nop ret
Label2: nop ret Как получить адрес метки Label1?
|
|
|
|
|
Jun 2 2011, 18:42
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Спасибо большое щас опробуем!!
|
|
|
|
|
Jun 3 2011, 05:43
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
А не так ли надо корректно? : Код ldi ZH, high(Label1 >>1 ) ldi ZL, low (Label1 >>1 ) Насколько я помню, у AVR-ров словарная адрессация памяти программ.
Сообщение отредактировал alexeyv - Jun 3 2011, 05:46
|
|
|
|
|
Jun 3 2011, 06:14
|

Познающий...
     
Группа: Свой
Сообщений: 2 963
Регистрация: 1-09-05
Из: г. Иркутск
Пользователь №: 8 125

|
QUOTE (alexeyv @ Jun 3 2011, 14:43)  А не так ли надо корректно? : CODE ldi ZH, high(Label1 >>1 ) ldi ZL, low (Label1 >>1 ) Насколько я помню, у AVR-ров словарная адрессация памяти программ. Похоже, что так. Только я умножал на 2, а не делил. Т.е. мне нужно было прыгнуть на 0x1c00. В ассемблере написал 0x3800.
--------------------
Выбор.
|
|
|
|
|
Jun 3 2011, 07:39
|
Гуру
     
Группа: Участник
Сообщений: 3 834
Регистрация: 14-06-06
Из: Moscow, Russia
Пользователь №: 18 047

|
Цитата(alexeyv @ Jun 3 2011, 09:43)  А не так ли надо корректно? : Код ldi ZH, high(Label1 >>1 ) ldi ZL, low (Label1 >>1 ) Нет. Никаких умножений и делений в данном случае не нужно. Цитата Насколько я помню, у AVR-ров словарная адрессация памяти программ. Да. Поэтому для байтового доступа по команде LPM адрес надо умножать на 2. Но это другой случай.
|
|
|
|
|
Jun 3 2011, 15:27
|
Местный
  
Группа: Участник
Сообщений: 235
Регистрация: 20-11-10
Пользователь №: 61 032

|
Код ldi ZH, high(JT * 2) ; *2 !!! ldi ZL, low(JT * 2) lds Temp1, State lsl Temp1 ; *2 !!! add ZL, Temp1 brcc pc + 2 inc ZH
cli lpm Temp1, Z+ ; попробуй такой "+" без запрета прерываний lpm Temp2, Z sei
mov ZH, Temp1 mov ZL, Temp2
icall
JT: .db high(State_0), low(State_0) ; через .dw, кажись, hi/low были бы в обратном порядке... .db high(State_1), low(State_1) ; ... а так печатать дольше, зато наглядно и не думать ... Для наглядности как-то так.
|
|
|
|
|
Jun 19 2011, 15:15
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Всем привет!!! Нуждаюсь вашей помощи! Вот пример кода. Код ldi r19,0x90 out spl,r19
ldi ZH,high(b) ldi ZL,low(b) s: icall b:brtc en rjmp s
en:sbr r18,252 set ldi ZH,high(e00) ldi ZL,low(e00) cpi r18,252 breq s ldi ZH,high(e01) ldi ZL,low(e01) cpi r18,253 breq s ldi ZH,high(e11) ldi ZL,low(e11) cpi r18,255 breq s ldi ZH,high(e10) ldi ZL,low(e10) cpi r18,254 breq s
e00:clt sbrc r18,0 inc r10 sbrc r18,1 dec r10 ret
e01:clt sbrc r18,0 inc r10 sbrs r18,1 dec r10 ret
e11:clt sbrs r18,0 inc r10 sbrs r18,1 dec r10 ret
e10:clt sbrs r18,0 inc r10 sbrc r18,1 dec r10 ret При первом ret видает уведомление AVR Simulator: Stack Underflow at 0x001eПодскажите, может надо указать сегмент кода и озу???
|
|
|
|
|
Jun 19 2011, 16:22
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Цитата(Палыч @ Jun 19 2011, 19:12)  Ответ Вы найдёте сразу, если ответите на вопросы: 1) сколько раз выполнится команда ICALL до выполнения RET? 2) как и почему МК попал на команду RET? 1) Два раза. 2) Вишел из подпрограмы. По идее, в стеке до RET, сохранено два возврата, один с метки b,второй с метки e00Так о чем сообщает симулятор!? о повторном вызове ICALL ??
|
|
|
|
|
Jun 19 2011, 16:36
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(Shadovv13 @ Jun 19 2011, 20:22)  1) Два раза. 2) Вишел из подпрограмы. Этот код Код s: icall b:brtc en rjmp s выполнялся бы бесконечно, если бы стек не "наехал" на область регистров. Цитата(Shadovv13 @ Jun 19 2011, 20:22)  Так о чем сообщает симулятор!? о повторном вызове ICALL ?? Подумайте: может ли стек распологаться по указанному адресу?
|
|
|
|
|
Jun 19 2011, 17:31
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Цитата(Палыч @ Jun 19 2011, 19:36)  Этот код Код s: icall b:brtc en rjmp s выполнялся бы бесконечно, если бы стек не "наехал" на область регистров. Подумайте: может ли стек распологаться по указанному адресу? Частично изменил код... Код s: brtc en b:icall rjmp s Уведомление осталось.... AVR Simulator: Stack Underflow at 0x001еКакой адрес указать для стека в ATmega8?
Сообщение отредактировал Shadovv13 - Jun 19 2011, 17:34
|
|
|
|
|
Jun 19 2011, 17:38
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(Shadovv13 @ Jun 19 2011, 21:31)  Частично изменил код... Код s: brtc en b:icall rjmp s Уведомление осталось.... Этот кусок кода будет выполнятся до тех пор, пока не изменится флаг T. Кто (какая команда) его изменит. P.S. Так и не понял Вашей программы, но, наверное, ошибка здесь: должна ли выполняться команда с меткой е00, если не выполнится условие перехода предыдущей команды (breq s)? Цитата(Shadovv13 @ Jun 19 2011, 21:31)  Какой адрес указать для стека в ATmega8? Обычно стек устанавливают так, как это сделано в примерах в DS Цитата $001 RESET:ldi r16,high(RAMEND); Main program start $002 out SPH,r16 ; Set Stack Pointer to top of RAM $003 ldi r16,low(RAMEND) $004 out SPL,r16
|
|
|
|
|
Jun 19 2011, 19:06
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Ну вот так все выглядит. Код ldi r16,high(RAMEND) out SPH,r16 ldi r16,low(RAMEND) out SPL,r16
ldi ZH,high(b) ldi ZL,low(b) s: brtc en b:icall rjmp s
en:sbr r18,252 set ldi ZH,high(e00) ldi ZL,low(e00) cpi r18,252 breq s ldi ZH,high(e01) ldi ZL,low(e01) cpi r18,253 breq s ldi ZH,high(e11) ldi ZL,low(e11) cpi r18,255 breq s ldi ZH,high(e10) ldi ZL,low(e10) cpi r18,254 breq s
e00:clt sbrc r18,0 inc r10 sbrc r18,1 dec r10 ret
e01:clt sbrc r18,0 inc r10 sbrs r18,1 dec r10 ret
e11:clt sbrs r18,0 inc r10 sbrs r18,1 dec r10 ret
e10:clt sbrs r18,0 inc r10 sbrc r18,1 dec r10 ret Результат, все работает но сообщение все равно присутствует!! AVR Simulator: Stack Underflow at 0x0020 Может хрен сним?
|
|
|
|
|
Jun 19 2011, 19:27
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(Shadovv13 @ Jun 19 2011, 23:06)  Может хрен сним? Я в предыдущем своем посте сделал приписку - возможно, Вы её не заметили... По-моему, ошибка вот тут Код breq s
e00: clt Хотя я в Вашей программе не разобрался, но мне кажется, что вместо команды "BREQ S" в этом месте должно быть что-то другое.
|
|
|
|
|
Jun 19 2011, 19:54
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Обратите внимание что вначале стоит Код en:sbr r18,252 значит одно из четырех сравнении Код cpi r18,252;,253,254,255 сработает!
|
|
|
|
|
Jun 19 2011, 20:15
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(Shadovv13 @ Jun 19 2011, 23:54)  значит одно из четырех сравнении сработает! Если Вы в этом уверены, то вместо Код cpi r18,254 breq s "правильнее" было бы записать Код rjmp s Кстати, в Вашей программе регистр r18 не изменяется вовсе (за исключением приведенной Вами команды с меткой en)... Или приведён небольшой фрагмент кода? Тогда я совсем не уверен, что регистр r18 принимает только эти четыре значения.
|
|
|
|
|
Jun 19 2011, 21:14
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Код rjmp s разве что в последнем сравнении! Регистр R18 будет принимать значение из порта(кнопки и 2 младших бита енкодер), после опроса клавиш, старшие 6 бит уст. в 1, для удобства сравнения(положения енкодера определиться по грей коду 00 01 11 10 .... ) Первый вызов программы определяет положение и адрес обработки второго вызова, устанавливает флаг Т как индикатор захвата положения. Второй вызов определяет в какую сторону сместился енкодер, и проводи увеличение или уменьшение R10. Сбрасывает флаг Т, указывая необходимость делать захват положения. Ну вот так как кто!
Сообщение отредактировал Shadovv13 - Jun 19 2011, 21:16
|
|
|
|
|
Jun 19 2011, 22:03
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Если помните, как называлась тема с енкодером, дайте ссылку пожалуйста. А то поиском страниц много.
Ну и вопрос остался открытым.
|
|
|
|
|
Jun 20 2011, 13:33
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Цитата(Палыч @ Jun 20 2011, 07:33)  Посмотрел и прочел! Вопросы, обсуждаемые в теме, я для себя давно решил . И этот код как раз решает проблемы, с дребезгом, с резким поворотом енкодера, а также учет всех перепадов(переходов). Кстати там же я нашел много подобных решений, схожих с моим!!!!! Спасибо за ссылку!!!!
Сообщение отредактировал Shadovv13 - Jun 20 2011, 13:34
|
|
|
|
|
Jun 20 2011, 14:07
|
Участник
  
Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695

|
Цитата(Shadovv13 @ Jun 20 2011, 04:06)  ... ldi ZH,high(b) ldi ZL,low(b) s: brtc en b:icall rjmp s en: ... Результат, все работает но сообщение все равно присутствует!! AVR Simulator: Stack Underflow at 0x0020 Может хрен сним? Ваш фрагмент работает точно так же, как и этот: Код s: brtc en БЕСКОНЕЧНЫЙ_ЦИКЛ: call БЕСКОНЕЧНЫЙ_ЦИКЛ rjmp s en: ... Т.е. если при переходе на метку "s" флаг "T" сброшен, всё будет нормально, но если флаг "T" установлен до перехода на метку "s", то программа входит в бесконечный цикл, непрерывно заполняя стек одним и тем же адресом возврата, о чём и кричит AVRstudio.
|
|
|
|
|
Jun 20 2011, 15:09
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Цитата(ae_ @ Jun 20 2011, 17:07)  Ваш фрагмент работает точно так же, как и этот: Код s: brtc en БЕСКОНЕЧНЫЙ_ЦИКЛ: call БЕСКОНЕЧНЫЙ_ЦИКЛ rjmp s en: ... Т.е. если при переходе на метку "s" флаг "T" сброшен, всё будет нормально, но если флаг "T" установлен до перехода на метку "s", то программа входит в бесконечный цикл, непрерывно заполняя стек одним и тем же адресом возврата, о чём и кричит AVRstudio. Спасибо уважаемый ae_. Кто же мог подумать что AVRstudio будет так глубоко анализировать!!! Думаю убрать метку b, она там в прицепе ненужна а регистр Z задам нулевой адрес(оставлю пустим). Так как Т флаг сто пудов буде сброшен, все будет норм. Ну а если нет РЕСТАРТ с 0
|
|
|
|
|
Jun 20 2011, 15:54
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Цитата(Палыч @ Jun 20 2011, 18:39)  В том то и дело, что сообщение - не результат анализа, а результат выполнения (симуляции выполнения) Вашей программы. Я с вами несогласен!!! В пошаговой отладке видно, что программа работает нормально и в бесконечный цикл не входит! Но при первом RET уведомляет, о возможном опустошении стека(я так думаю).
Сообщение отредактировал Shadovv13 - Jun 20 2011, 15:55
|
|
|
|
|
Jun 20 2011, 17:09
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Цитата(Палыч @ Jun 20 2011, 19:41)  Огласите значение указателя стека после его инициализации в начале программы и перед выполнением команды RET. Вначале: SP = 0x45F Перед RET: SP = 0x45D После RET: SP = 0x45F
|
|
|
|
|
Jun 20 2011, 19:08
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Цитата(Палыч @ Jun 20 2011, 21:59)  И - что? При выполнении RET выдаёт сообщение?
Стало как-то интересно... Поставил Studio, скопировал Вашу программу, оттранслировал, зашёл в режим отладки, дошагал до RET, получил те же значения указателя стека, но сообщение - нет!
Стесняюсь спросить: у Вас в отладчике какой Device выбран? Странно!!! Все перепроверил(может всякое быть) результат тодже  Может Студия глючная?? У меня. AVR Studio 4.12.498 Service Pack 4 GUI Version 4, 12, 0, 491 AVR Simulator 1, 0, 1, 8
|
|
|
|
|
Jun 20 2011, 19:41
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Цитата(Палыч @ Jun 20 2011, 22:34)  Ну, не самая последняя... Я вообще для эксперимента какую-то древность поставил. А, Вы точно указали симулятору в качестве Device значение ATmega8? Случайно что-то там типа mega8535 не указали? Не!!! Точна 8-мая!!!! Спецом проект пересоздал!
|
|
|
|
|
Jun 21 2011, 04:26
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(ae_ @ Jun 21 2011, 02:41)  подпрограммы e00, e01, e11, e10 абсолютно одинаковые Они выглядят такими, но отличаются командами SBRS/SBRC. Подозреваю, что ТС во время отладки изменяет регистры, поскольку, приведенная программа - всего лишь заготовка, неимеющая кода считывания состояния энкодера. При этом нарушается "нормальная" последовательность выполнения кода, и программа уходит в бесконечный цикл...
|
|
|
|
|
Jun 21 2011, 09:13
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Внес изменения. Полностью не исключает зависание в цикле, но на пошаговом должно быть видно не правильные переходы. Код ldi r16,high(RAMEND) out SPH,r16 ldi r16,low(RAMEND) out SPL,r16
ldi ZH,0 ldi ZL,0
ldi r18,255 s: brtc en icall rjmp s
en:sbr r18,252
|
|
|
|
|
Jun 21 2011, 11:55
|
Участник

Группа: Участник
Сообщений: 29
Регистрация: 2-06-11
Пользователь №: 65 445

|
Поставил студию.... AVR Studio 4.18.684 GUI Version 4, 18, 0, 670 AVR Simulator 1, 0, 2, 1 Итог!!!!! Извините что вам и себе мозги парил и время отнимал! ВСЕ ЗАРАБОТАЛО!!!!! ВСЕМ СПАСИБО!!!!
|
|
|
|
|
Jun 22 2011, 11:56
|
Участник
  
Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695

|
Цитата(Shadovv13 @ Jun 21 2011, 20:55)  ВСЕ ЗАРАБОТАЛО!!!!! Прошу прощения, проглядел SBRS/SBRC в подпрограммах e00-e11. В Вашей программе обработка состояний энкодера выполняется за два хода, первый-второй. Номер хода(условно) хранится во флаге Т, а состояние первого хода сохраняется в виде адреса подпрограммы в ZH:ZL. Энкодер для МК - очень медленное устройство, за время между изменениями состояния энкодера могут выполниться миллионы инструкций. Неужели ZH:ZL нигде более не используется в Вашей программе? Если используется, то приходится многократно сохранять/восстанавливать два регистра. Кстати, если забыли сохранить Z, то это причина переполнения стека, т.к. ICALL выполняется неизвестно куда. Зачем? Ведь можно хранить всего лишь 2 бита - предыдущее состояние энкодера, не используя уникальную пару ZH:ZL. И зачем обрабатывать изменения энкодера за два хода? ведь любой из двух сигналов с него может перескочить 1/0 или 0/1 и вернуться обратно (от помехи или если энкодер находится на границе переключения). Не нужно считать первый-второй, можно каждое изменение считать сразу "вторым ходом". Далее, считываем текущее значение, сопоставляем его с предыдущим, решаем что нужно сделать: +1,-1, или ничего. Затем текущее состояние энкодера переместить в "предыдущее" и ждать новых изменений.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|