MaksimYrievich
Jan 2 2010, 18:32
Здравствуйте! Меня зовут Максим. Всеръез занимаюсь программированием. Может есть кто специалисты. Подскажите пожалуйста. Я пишу программу в AVR Studio на ассемблере. Программирую AtMega32. Так вот не могу понять почему при отладке программы - в дебаг режиме происходит сброс программы на метку RESET через определенные промежутки времени (262,14ms)? МОЖЕТ КТО ВСТРЕЧАЛ ТАКУЮ ПРОБЛЕМУ?
P.S. Причем команда WDR расставлена по листингу самой программы через каждые два шага, Со стеком программа работает корректно. Мной ошибки не выявлены. Если кто заинтересовался прикрепляю листинг своей программы (хотя , конечно не все поймут ее содержимое, просто на всякий случай). (Содержимое из файла копируется в созданный в AVR Studio 4.16 проект на AtMega32 8.00 мегагерц. Втыкаете листинг в проект и можно переходить в режим отладки).
Никогда ранее не сталкивался с проблемами непроизвольного сброса отладчика в AVR Studio 4.16. И не могу понять по какому событию в WatchDoge происходит сброс выполнения програмы. Инициализирую WatchDog в программе так:
Код
wdr
ldi r16, 15 ; Или 0b00001111 в двоичном виде "Сброс через около 2 сек"
out WDTCR, r16
wdr
и все через 262,14ms выполнения программы я снова на метке RESET. Если сбрасываю WDE то программа выполняется без проблем строго следуя операторам вызова подпрограмм и возврата из них. НО С НЕИНИЦИАЛИЗИРОВАННЫМ WATCHDOGOM Что не приемлемо для меня по условию задачи.
galjoen
Jan 2 2010, 19:52
Цитата(MaksimYrievich @ Jan 2 2010, 21:32)

Инициализирую WatchDog в программе так:
wdr
ldi r16, 15 ; Или 0b00001111 в двоичном виде "Сброс через около 2 сек"
out WDTCR, r16
wdr
А нужно примерно так:
Код
wdr ; сбрасываем Watchdog
ldi r16,1<<WDCE|1<<WDE; для доступа к регистрам
ldi r17,1<<WDE|2<<WDP1|1<<WDP1|1<<WDP0; период около 2100 mS
; ldi r17,1<<WDP1|1<<WDP0; пример запрета ватчдога
sts WDTCR,r16
wdr
sts WDTCR,r17
В даташите ведь об этом написано...
ЗЫ Не смотрел как у m32 расположены регистры ватчдога. Насчёт доступности их командами out. Если доступны - заменяем в моём примере sts на out.
MaksimYrievich
Jan 2 2010, 20:06
Интересно, а в каком датасшите написано про это? И в чем суть я ни как не пойму?
galjoen
Jan 2 2010, 20:18
В любом даташите на AVR, в разделе про ватчдог.
Больше подсказывать не буду, иначе не запомнится. А аналогичная фича, не только при работе с ватчдогом, на AVR используется...
Проверьте в отладчике, а затем прочтите в даташите.
ЗЫ Второй раз wdr можно не сбрасывать. Это я при копировании ошибся. Но так тоже работать будет.
MaksimYrievich
Jan 2 2010, 20:33
Цитата
; ***** WATCHDOG *********************
; WDTCR - Watchdog Timer Control Register
.equ WDP0 = 0 ; Watch Dog Timer Prescaler bit 0
.equ WDP1 = 1 ; Watch Dog Timer Prescaler bit 1
.equ WDP2 = 2 ; Watch Dog Timer Prescaler bit 2
.equ WDE = 3 ; Watch Dog Enable
.equ WDTOE = 4 ; RW
.equ WDDE = WDTOE ; For compatibility
Обратите пожалуйста внимание, что в подключаемых файлах так называемые "инки" нет регистра WDCE. В приведенном вами примере он учавствует. во второй строке кажись.
Короче говоря не существует регистра WDCE и приведенный вами листинг не пройдет компиляцию ваще
galjoen
Jan 2 2010, 20:34
Цитата(MaksimYrievich @ Jan 2 2010, 23:22)

Обратите пожалуйста внимание, что в подключаемых файлах так называемые "инки" нет регистра WDCE. В приведенном вами примере он учавствует. во второй строке кажись.
У m32 он называется WDTOE. Но суть от этого не меняется. Как и его значение (WDTOE=WDDE=WDCE=4).
MaksimYrievich
Jan 2 2010, 20:45
Попробовал но ни к чему не привело все равно выкидывает при том же времени. работает только команда out
galjoen
Jan 2 2010, 20:53
Цитата(MaksimYrievich @ Jan 2 2010, 23:45)

Попробовал но ни к чему не привело все равно выкидывает при том же времени. работает только команда out
Описался. Вот так д.б.:
Код
wdr ; сбрасываем Watchdog
ldi r16, 1<<WDTOE|1<<WDE ; для доступа к регистрам
ldi r17,1<<WDE|1<<WDP2|1<<WDP1|1<<WDP0; период около 2100 mS
; ldi r17,1<<WDP1|1<<WDP0; пример запрета ватчдога
out WDTCR,r16
wdr
out WDTCR,r17
Ещё заметил, что у вас много команд wdr в программе. Желательно их иметь не более 2. Одна из которых при инициализации.
MaksimYrievich
Jan 2 2010, 21:30
Сейчас попробуем!?
Ничего не изменилось. Я вот думаю может это глюк компилятора. Может AVR Studio шалит?
А команды сброса сторожевого таймера в листинге своей программы я уже специально понавтыкал через каждые два шага. Просто у меня уже нет версий происходящего с программой. В том то и проблема что при постоянном сбросе ватчдога в листинге программы мы имеем стабильный вылет на метку RESET с завидным постоянством (262,14ms)
Есть еще версии??
galjoen
Jan 2 2010, 21:49
Цитата(MaksimYrievich @ Jan 3 2010, 00:30)

Есть еще версии??
Ватчдог тут ни при чём. Сейчас посмотрел даташит на m32. Там блокировки нет. Т.е. у вас инициализация была правильная, а я ошибся. Хотя так тоже работать будет.
Побробовал запустить в отладчике. Куча мелких глюков, типа:
Код
sei
reti
Но у меня по wdr не вываливается. У меня вообще не вываливается.
А у вас вываливается? Почему вы решили, что это по ватчдогу? Если посмотреть в окошке I/O View, а там в CPU флаг Watchdog Reset Flag, он при вылете на RESET у вас установлен? А ук-ль стека чему равен?
А если ватчдог (см. пример) запретить?
На мой взгляд что-то со стеком. В результате переход на неициализированную часть флеш...
Дождался. Действительно попали на RESET. Но не по ватчдогу. Флага его нет.
MaksimYrievich
Jan 2 2010, 22:11
Значит у вас не вываливается мой листинг программы говорите? Может быть AVR Studio переустановить? А куча разных глюков вываливается в окне MESSAGE? После нажатия кнопки DEBUG чтоли?
Цитата(MaksimYrievich @ Jan 3 2010, 00:59)

Значит у вас не вываливается мой листинг программы говорите? Может быть AVR Studio переустановить? А куча разных глюков вываливается в окне MESSAGE? После нажатия кнопки DEBUG чтоли?
Я тоже вижу что не по ватчдогу - нет его в MCUCRе по приходу на ресет. Вот сижу и не могу въехать. Первый раз с таким столкнулся. Причем , могу сказать, что если при подходе счетчика ко времени 262ms плюс, минус там сколько то , сбросить WDE не на долго и установить, то далее программа движется без вылетов
Цитата(galjoen @ Jan 3 2010, 00:49)

На мой взгляд что-то со стеком. В результате переход на неициализированную часть флеш...
Работу стека анализировал сбоев не обнаружено. Однако, сброс не осуществляется при отключенном ватчдоге 0<<WDE. Ход программы при 0<<WDE остается нормальным далеко за пределами 5 секунд.
galjoen
Jan 2 2010, 23:08
Цитата(MaksimYrievich @ Jan 3 2010, 01:11)

Вот сижу и не могу въехать.
Вначале нужно от глюков избавится. Типа таких:
Код
CLOCK:
nop
wdr
rjmp clock
ldi r16, ClearDispl
call CommandDisplay
Тут на команду ldi никогда не попадём.
Про последовательность sei reti я уже писал. Какой смысл тут в sei?
Одно это может к такому результату привести. Сразу после reti будет новое прерывание и ни одной команды из цикла CLOCK выполнено не будет. Ватчдог не сбросится.
Команду reti именно из-за этого и придумали. Чтобы хоть одна команда между двумя прерываниями выполнилась.
А так бы она не нужна была. Достаточно было бы
Код
sei
ret
написать.
Ну и множество других подобных глюков...
MaksimYrievich
Jan 3 2010, 00:20
В приведенном мной листинге программа специально зациклена для исключения ошибок в стеке просто для простоты понимания проблемы. В реальной программе конечно такой строки нет "rjmp CLOCK".
И действительно, SEI в прерывании ставить нельзя... Ситуация поправлена в исходниках спасибо за подсказку, но проблема то с вылетом остается !
У меня вылетает еще некое сообщение смысл которого я не могу разобрать - "Target not Ready". У вас есть такое? Может знаете что оно значит?
Сообщение об ошибке. Что это значит?
galjoen
Jan 3 2010, 16:38
Цитата(MaksimYrievich @ Jan 3 2010, 03:20)

... Ситуация поправлена в исходниках спасибо за подсказку, но проблема то с вылетом остается !
Я уже писал, что не стоит пытаться решить проблемму подправив к.л. одну команду. У вас глюков там множество. Даже если всё каким то чудом заработает, то это не значит, что после минимальных изменений будет продолжать работать. Поэтому нужно посидеть под отладчиком. Причём отладить каждую подпрограмму в отдельности. А подпрограмму обработки прерывания особенно! Вставить после инициализации call на неё и смотреть что происходит с регистрами. Всё ли восстанавливается как было. Программа у вас небольшая, и вполне можно это сделать. И только когда вы будете уверены во всех подпрограммах, то можно идти дальше. Вам опыта не хватает, так компенсируйте это трудолюбием. А потом и опыт появится. По листингу видно, что вы стараетесь, но эти старания пропадают даром из-за ошибок, описок, непонимания того как работает аппаратура и т.п.
Вот например в обработчике прерывания написано:
Код
ldi r25, SREG
; а д.б. так:
in r25, SREG
В итоге у вас SREG будет изменятся в этом прерывании, и будут совершенно непредсказуемые глюки, которые можно искать неделями...
Ну описались, с кем не бывает. Но если ВДУМЧИВО пройтись отладчиком, такая ошибка находится мгновенно.
MaksimYrievich
Jan 3 2010, 18:26
Спасибо за подсказку. Видимо мне действительно не хватает внимания - признаю. Иначе бы я здесь не был. Кстати вы не могли бы подсказать чем или как вы находите такие ошибки (применительно к AVR Studio) ведь в отладчике равнозначно работает команда "ldi" и "in" ОДИНАКОВО ПРАВИЛЬНО. Хотя правильно, конечно, ldi т.к. SREG регистр ввода-вывода как минимум, а не константа. Но я еще раз хочу подчеркнуть, что отладчику AVR Studio побарабану и работают две команды. В этом случае классический анализ загрузки, выгрузки - в, из РВВ не подходит. Может я чего то просто не знаю, существует ли автоматический метод обнаружения таких проблем в AVR Studio. Мой отладчик молчит, тупо пояснив мне, что "Assembly complete, 0 errors. 0 warnings".
С уважением, Максим.
galjoen
Jan 3 2010, 19:13
Автоматически ничего не обнаружится - это ассемблер.
Вдумчиво пройтись отладчиком - это значит после нажатия Ctrl+F7 открыть окошко "Proceccor", а в нём "Registers" и, нажимая кнопку F11, смотреть имеются ли различия в том, что должна была делать эта команда по задумке, и что происходит реально. И при этом, конечно, следить в т.ч. и за флагами в SREG, и за содержимым регистров и т.д.
Перед тестовыми вызовами подпрограммы обработки прерывания заполнить (вручную) регистры (например, первый раз AA, второй 55, третий C3 и т.д.), SREG (тоже поразному) и ук-ль стека (можно одинаково). После возврата всё должно стать так-же.
И не экономте время на отладке. Написали кусочек, пока не забыли что зачем - сразу отладчиком его. В итоге кучу времени съэкономите. AVR-Studio для этого вполне нормальные возможности даёт.
А понажимав как следует на F11, вы и код оптимальнее составлять начнёте. С этим у вас тоже проблеммы...
MaksimYrievich
Jan 3 2010, 19:43
Может кините код какой нибудь взглянуть как надо работать? Кстати все это я сделал но все равно выкидывает из цикла основной программы
galjoen
Jan 3 2010, 21:14
Там ещё глюки есть...
Но не надо добиваться чтобы заработало. Нужно чтобы ошибок не было. Тогда работать будет.
А пример моего кода можно взять в разделе AVR. Найдите тему RST7 - "Необычное использование аппаратного умножителя" (вроде так называется). Она, наверное, станице на 5-й. Там оптимизировалось по быстродействию. Быстрое деление 16/16. Тактов за 60 получилось. М.б. кому пригодится...
MaksimYrievich
Jan 3 2010, 22:48
galjoen
Ещё как пригодится!!! А как вы считаете на C++ освоить программирование - писать большие по размеру программы будет удобнее?
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.