Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Странное поведение ATmega 16L
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
kanzler
Сталкиваюсь первый раз с таким поведением процессора. Применяю в проекте ATmega 16L.
При отладке программы, с применением JTAG, обнаружил что программа всегда в одном и том же месте уходит в сброс. Это стало проявляться когда к программе присоединил программный модуль, без этого модуля программа работает нормально. Пробовал различные способы устранения данной проблемы не помогает. В ATmega 16 таких проблем у меня не возникало ни когда. Кто сталкивался с такой проблемой? Посоветуйте как избавиться от этого.
oran-be
Уточните, сброс - это именно сброс, или просто попадание программного счетчика на вектор сброса? И что, та же прога при тех же условиях нормально пашет с Мегой16, а с Мегой16L не хтит?
andrvisht
Цитата(kanzler @ Jul 18 2007, 05:39) *
Это стало проявляться когда к программе присоединил программный модуль, без этого модуля программа работает нормально.


А этот модуль к портам доступ имеет ? Может с питанием что то происходит ? У меня были подвисания отладки и уход на конец области памяти....
Можно еще предположить стек, но тогда обычно просто зависает. но посмотреть стоит.
NVade
Уточняющий вопрос - насколько все одинаково в проектах на M16 и M16L: частота кварца (кстати, какая?), настройки компилятора, установки BOD.
У меня есть 2 предположения по симптоматике - сброс по сторожевому таймеру или переполнение стека.
vesago
9 против 10 просаживается стек. Допустим в каком цикле криво проинициализирован счетчик. 1 - касяк со сторожевым таймером. m16 и m16l в принципе из одной бочки розлиты.
alux
Цитата(kanzler @ Jul 18 2007, 05:39) *
Это стало проявляться когда к программе присоединил программный модуль, без этого модуля программа работает нормально.

У меня сегодня точно такая же проблема была, только с Мегой32L . При подключении вызова функции контроллер перезапускался. Правда проверял не JTAG ом, а просто дергаю ногами в разных местах программы. Т.е. программа зацикливается от начала до дергания ногой. Как выяснилось, в проблемной функции был проинициализирован большой массив [1064] в ОЗУ, что очевидно привело к переполнению стека.
defunct
Цитата
Странное поведение ATmega 16L

Господа, чтобы помощь была эффективной, а поведение МК не казалось странным.
1. Внимательно смотрим в исходник.
2. Если не понимаем почему код приводит к "странному" поведению МК - то исходник (в данном случае - присоединяемый модуль) выкладываем сюда.

Цитата
Кто сталкивался с такой проблемой? Посоветуйте как избавиться от этого.

Видать каждый на этом форуме может ответить что сталкивался. А чтобы избавиться посоветовать протереть пыль и постучать в бубен. Еще можно посоветовать - отсоединить модуль.
kanzler
WDT срабатывает вряд ли, так как я его не включаю. Переполнение стека - вполне возможно, но дело в том что у меня переменных огромных размеров нет. Ну а код, то могу предоставить полный проект, он не большой. Подключаемый модуль, это обработка двух кнопок (hardScanKey и keyboard). Если в файле hard.c в обработчике прерывания таймера 2 закомментировать строку systemFlag.KEYSCAN_FLAG = 1; и в основном цикле сделать условие if(systemFlag.TIMER0_FLAG), то сброс пропадает и программа работает нормально.

Плюс я обнаружил в каком месте программы происходит сброс. Это -
if(channelDetect[3])
{ countOnChannel[3]++;
countOnChannel[0] = 0; countOnChannel[1] = 0; countOnChannel[2] = 0;
if(countOnChannel[3] == 50)
{ hardLedsIndication(RED_LIGHT, RED_LIGHT, RED_LIGHT, GREEN_LIGHT);
countOnChannel[3] = 0;
}
}

файла hard.c функции void hardShowChannel(void)
kanzler
Цитата(defunct @ Jul 18 2007, 21:00) *
Господа, чтобы помощь была эффективной, а поведение МК не казалось странным.
1. Внимательно смотрим в исходник.
2. Если не понимаем почему код приводит к "странному" поведению МК - то исходник (в данном случае - присоединяемый модуль) выкладываем сюда.
Видать каждый на этом форуме может ответить что сталкивался. А чтобы избавиться посоветовать протереть пыль и постучать в бубен. Еще можно посоветовать - отсоединить модуль.


Молчание ягнять часть номер 5. Нафига было отправлять исходник, распинаться и кланяться?
Ясно одно - ни кто помочь не может ... пиво пьют, но только не "Клинское".

А то что отсоеденить модуль, то это я исам знаю, писалось в самом начале.
defunct
Цитата(kanzler @ Jul 20 2007, 21:48) *
Молчание ягнять часть номер 5.

Только сейчас появилась возможность детально посмотреть код.
Код названной вами функции сильно перегружен индексными операциями.

Ответьте на пару вопросов:
1. if(systemFlag.DETECT_FULL_FLAG)
{ hardShowChannel();
systemFlag.DETECT_FULL_FLAG = 0;
}
если закоментировать hardShowChannel(); в этом месте, то проблема исчезает. Верно?
2. Чему равен CSTACK?
3. Чему равен RSTACK?


Функция hardShowChannel() - в вашей программе ведь ничего не делает. ChanCounters (все) всегда == 0, т.о. никакой активности на портах нет. Проблема явно не с питанием, и явно не с M16L. Программа должна одинаково сбоить и на m16 и на m16L. Если есть возможность, бросте мне файлы проекта (*.ewp/ewd), попробую под отладкой.
kanzler
Цитата(defunct @ Jul 21 2007, 01:31) *
Только сейчас появилась возможность детально посмотреть код.
Код названной вами функции сильно перегружен индексными операциями.

Ответьте на пару вопросов:
1. if(systemFlag.DETECT_FULL_FLAG)
{ hardShowChannel();
systemFlag.DETECT_FULL_FLAG = 0;
}
если закоментировать hardShowChannel(); в этом месте, то проблема исчезает. Верно?
2. Чему равен CSTACK?
3. Чему равен RSTACK?
Функция hardShowChannel() - в вашей программе ведь ничего не делает. ChanCounters (все) всегда == 0, т.о. никакой активности на портах нет. Проблема явно не с питанием, и явно не с M16L. Программа должна одинаково сбоить и на m16 и на m16L. Если есть возможность, бросте мне файлы проекта (*.ewp/ewd), попробую под отладкой.


Хммм ... у меня есть проект где этих индексных операций больше чем в данном проекте, но тем не менее проект работает замечательно.
1. Нет, как раз этот модуль я не выключаю, а вот выключив:
#pragma vector=TIMER2_OVF_vect
__interrupt void timer2Handle(void)
{ //systemFlag.KEYSCAN_FLAG = 1;
}

И сделав условие в главном цикле:
if(systemFlag.TIMER0_FLAG)
вместо
if((systemFlag.TIMER0_FLAG) && (modeWork == 2))

таким образом работает только автоматический режим и программа работает без сбоев.
п.2 так и п.3 ответить не могу так как значения посмотреть не могу по причине того что монитор стека в AVR Studio показывает - disabled

В прилогаемом файле то что вы просили.
defunct
Цитата(kanzler @ Jul 21 2007, 05:48) *
1. Нет, как раз этот модуль я не выключаю, а вот выключив:
__interrupt void timer2Handle(void)

Этим отключается сканирование клавиатуры?


Цитата
И сделав условие в главном цикле:
if(systemFlag.TIMER0_FLAG)
вместо
if((systemFlag.TIMER0_FLAG) && (modeWork == 2))

не совсем понимаю это ваше условие.
modeWork устанавливается в 2 два при нажатии какой-то кнопки.
Какой кнопки?


Цитата
таким образом работает только автоматический режим и программа работает без сбоев.

Изъясняйтесь проще ;>
Мне не ведомо, что означает у вас автоматический режим, а что не автоматический.
Опишите как можно более подробно условия сбоя, например так:

Нажимаю кнопку которая коротит PINX с землей, по этой кнопке устанавливается флажек modeWork в 2. После очередного переполения таймера T0 этот флаг проверяется, вызывается функция hardShowChannel(); в которой происходит прыжек в начало программы.

Цитата
В прилагаемом файле то что вы просили.

Вы пользуете только ewd сборку, и код приведенный в предыдущем посте точно сбоит?
Под отладкой погонял - но ничего не перезагружается. Видать не выполняются какие-то условия.
Подправьте код main() сл. образом:

Код
{  
    resetB = MCUCSR;  
    MCUCSR  = 0;  // CLEAR OLD RESET FLAGS


и посмотрите чему равен resetB после сбоя.
kanzler
Цитата(defunct @ Jul 21 2007, 17:58) *
Этим отключается сканирование клавиатуры?

Да, отключается клавиатура.

Цитата(defunct @ Jul 21 2007, 17:58) *
не совсем понимаю это ваше условие.
modeWork устанавливается в 2 два при нажатии какой-то кнопки.
Какой кнопки?

Нажимаю кнопку которая коротит PINB2 с землей, по этой кнопке устанавливается флажек modeWork в
2.
Цитата(defunct @ Jul 21 2007, 17:58) *
2. После очередного переполения таймера T0 этот флаг проверяется, вызывается функция hardShowChannel(); в которой происходит прыжек в начало программы.
Вы пользуете только ewd сборку, и код приведенный в предыдущем посте точно сбоит?

Да имменно так и происходит и код сбоит. Правда я не совсем понял что есть ewd сборка?

Цитата(defunct @ Jul 21 2007, 17:58) *
Под отладкой погонял - но ничего не перезагружается. Видать не выполняются какие-то условия.
Подправьте код main() сл. образом:
Код
{  
    resetB = MCUCSR;  
    MCUCSR  = 0;  // CLEAR OLD RESET FLAGS


и посмотрите чему равен resetB после сбоя.

Хорошо попробую.


После сбоя содержимое регистра MCUCSR = 0x00.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.