Есть нехитрая тестовая плата с атмегой, у кот. используются только два порта на вывод. Сама атмега ATMega 128 16AI-L. Пишу программу, кот. выводит бегущую единицу на порты. Работает. То же, но на атмеге 64 16AI - не пашет. Залипают состояния на выводах. Подключил к ней внешн. источник опорного напряжения и получилась следующая вещь 1я программа: Код (Text): ldi tmp_r,0xff start: com tmp_r out PORTB,tmp_r rjmp start -- работает, чередует единицы и нули на выводах 2я программа: Код (Text): ldi tmp_r,0xff start: com tmp_r out PORTB,tmp_r rcall aaa rjmp start aaa: ret -- Не работает. Из-за пустой процедуры (стек и остальные необходимые элементы я, ессно конфигурировал). На выводах залипает 1. И всё. Почему - загадка. Может быть, конечно, что это из-за того, что оставшиеся ноги висят в воздухе, НО! во-первых, на первом мк работает всё даже без ВИОН, а во-вторых, насколько я помню на каждом выводе есть подтягивающий резистор и по-умолчанию они включены. Кто сталкивался с проблемой или какие мысли есть подскажите!
А ты абсолютно уверен, что правильно стек конфигурируешь во втором МК? Тут вся разница как-раз в его использовании. Кстати, если имеется микросхема-драйвер RS-232, то можно попробовать через неё поотлаживать, т.к. возможности отладки через JTAG я так понимаю нет. Посмотри, куда указатель стека реально указывает. Кстати, у тебя RAM внешняя? tmp_r, я так понимаю, один из регистров r(или всё-таки область памяти). Возможно ошибка при обращении к внешней памяти.
А как насчет работы в симуляторе avrstudio или vmlab? Там тоже самое? Выложи полный текст второго примера, вместе с процедурами инициализации...
Привет! Если конечно нет возможности в симуляторе покопаться, хотя это ОЧЕНЬ НЕВЕРНО, т.к. такие проблемы будут и их надо уметь решать... + освоить "инструмент" для этого на будущее + себя уважать будешь... Так вот, если уж смекалку проявлять, то в подобных случаях, ну например, все нужное (симулятор, среда, полезняшки) где то там.., а тебе типа "в полевых, окопных" условиях деять нядо, то я бы смекал так: 1. разчленить на еще более пошаговые действия даже такую программу(!), с тем, чтобы даже тестером можно было "вынюхать" причину и "точку клина". 2. впреть использовать второй, третий... порт как ОТЛАДОЧНО-ДИСПЛЕЙНЫЙ, выдавая в него нечто уникальное на каждом шаге, вплоть до особо интересующих регистров. В данном случае, скажем выдавать регистр стека на другой порт ДО и ВНУТРИ и ПОСЛЕ rcall(!)... 3. Самое продвинутое после победы над посл.портом. Настроить и использовать последовательный порт, соединив его нуль-модемным соединением с машиной на COM порт + программа-терминалка(НЕХ режим в ней должOн быть!), как простейшее и первейшее средство работы с контроллером в диалоге+"его отчетность". Делее можно "учить" свою прогу реагировать на твои коды клавиш от машины и делать то, что нужно или ветвить(!) алгоритм на неких узловых моментах твоей проги... Словом полезно во многих аспектах, т.к. это и освоение и продвижение и эффективность и пробирование сил, железа, методов, процедур... В данном случае, простейшая, но уже эффективная мутация твого кода в данном направлении следующая: start: com tmp_r out PORTB,tmp_r rcall aaa com tmp_r out PORTB,tmp_r ;; rjmp start stop: rjmp stop aaa: com tmp_r out PORTB,tmp_r ret Что в итоге имеем? Имеем на твоем порту бит на 3ей позиции и пустой цикл в конце(но ты будешь это знать и уверен). Это будет свидетельствовать, о том, что со стеком все в норме. Очень похоже, что он у тебя не работает правильно, ребята правы. Еще посмотри, проверь тип RET(!)соответствует ли rcall т.е. короткий, длинный... вызов должен соответствовать АНАЛОГИЧНОМУ RET! Иначе стек невыровнен и по RET`у можно "улететь" в дремучие степи... Да, если ты всеже "улетаешь по выходу", но заходишь в aaa: com tmp_r out PORTB,tmp_r ret то понятно, что будешь иметь бит только на 2 позиции и "висяк" т.д. АГА!??? Успехов в смекалке и анализе!
Dimson конфигурирую так: ldi tmp_r,LOW(RAMEND);Установка стека out SPL,tmp1_r ldi tmp_r,HIGH(RAMEND) out SPH,tmp_r tmp_r = r16 compnet В симуляторе всё ессно работает. VaStaNi Я уже и так расчленил проблему и дочленил её до вышеописанных примеров. И если ты внимательно читал, то у меня залипают состояния на ногах, поэтому я ничего мониторить, к сож., не могу -- Продолжаю грешить на ВИОН сконфигурирован только бит ACBG. Больше ничего не трогал. Включение Brown-out и выключение PUD ничего не дают
А если всё-таки попробовать через RS-232 отладить? Или выводы в альтернативном режиме тоже не работают? Необходимо узнать следующее: выполняется-ли программа во втором случае или где-то зависает? Если выполняется, то трабл точно аппаратный, а если нет, то ты скорее всего где-то что-то недоконфигурировал и из-за этого всё очень нестабильно может работать. В любом случае интересно знать куда "улетает" программа после rcall aaa. Возможно в reset всё уходит. Кстати, выполнение кода в симуляторе далеко ещё не значит, что он будет также в реальном МК работать. В симуляторе стек можно хоть на регистровую область сконфигурить и всё будет очень даже замечательно выполняться (по крайней мере в AVR Studio 3.5 так было)
gilg Конечно на вывод Dimson Буду пробовать. Сразу вопрос на будущее, если это аппаратый глюк, то может быть стоит обезопасить себя подключением земли через резисторы на свободные выводы? Включить brown-out? Поднять напряжение на ВИОН почти равным напряжению питания???
Кстати, не может такого быть, что какое-нибудь прерывание разрешено? И ещё: ты говорил, что push/pop работает, а вот значение, которое ты берёшь из стека после push-а точно соответсвует тому, что ты туда заталкиваешь? На мой взгляд тут дело в работе с внешней памятью всё-таки (если она есть). Или ты только внутреннюю RAM юзаешь? Скорее всего идет прыжок куда-нибудь не туда, а после этого reset, инициализация и т.д.
Dimson Память только внутренняя. Вообще кроме атмеги почти ничего нет Да и не включено ничего. Вот полный текст 1й версии Код (Text): .include "m64def.inc" .def tmp1_r =r16 .org 0 rjmp init init: cli ldi tmp1_r,LOW(RAMEND) out SPL,tmp1_r ldi tmp1_r,HIGH(RAMEND) out SPH,tmp1_r ldi tmp1_r,(1<<ACME) out SFIOR,tmp1_r ldi tmp1_r,(1<<ACBG) out ACSR,tmp1_r ldi tmp1_r,0xff out DDRA,tmp1_r loop: com tmp1_r out PORTA,tmp1_r rjmp loop А значение выковыренное из стека чё-то не догадался посмотреть. Вечером гляну.
Можно попробовать провести чистый эксперимент и выкинуть всё "ненужное": 1) Инициализацию компаратора (а вдруг поможет ). 2) Всякие там макросы типа LOW(RAMEND) и HIGH(RAMEND) можно попробовать заменить на обычные числа (просто какой-нибудь адрес памяти вбить и проверить).
Dimson Компаратор используется в роли внешнего источника опорного напряжения. Без него на новых микрухах даже первый пример не катит. RAMEND проверял в map-файле - всё корректно. Это уже "чистый" эксперимент
А тактируется там всё нормально? Reset нормально формируется при запуске? Всё как в мануалах написано ? Очень странно, что без ВИОНА не работает.
Глюк был связан с тем, что был записан бит совместимости с Atmega103. Снял и всё стало работать. Всем спасибо.
riban А вот у меня как-то на 162-й какой-то умник установил фуз JTAG, а он рубит старшие линии адреса... два месяца долбались ))) да, СЕЙЧАС это уже смешно...