Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не обнуляется счётчик Сторожевого таймера
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
MaksimYrievich
Здравствуйте ! Подскажите, пожалуйста, может быть есть кто сталкивался с подобной проблемой программирования на СИ в WinAVR или AVRstudio 4.15 AvrGCC.

Вобщем не могу понять в чем причина сбрасывания микроконтроллера (после прошивки) при раскомментировании строки инициализации Сторожевого таймера в функции "AtMega128_PHR_RegulatorInit();"

Для сброса сторожевого таймера использую стандартную функцию "wdt_reset();" из файла <avr/wdt.h>:rolleyes: Весь проект в папке "AvrStudio4.15". Не пойму в чем дело. Как будто функция не сбрасывает сторожевой таймер И то же самое происходит при использовании стандартных фунций из файла <util/delay.h> когда начинаешь их использовать в основном файле программы "PH_Regulator_PHR_04_02.c" такие функции как _delay_ms();, _delay_us();.

Причем подобные проблемы возникают и в WinAVR... то же самое. Для того что бы открыть проект в WivAVR нужно просто открыть файл "PH_Regulator_PHR_04_02.c" в архиве с проектом. Если кто сталкивался подскажите в чём дело. Сам чувствую, что проблема из-за софта для программирования или что то не правильно подключил в исходниках. help.gif
Палыч
Цитата(MaksimYrievich @ Jul 4 2011, 22:56) *
Для сброса сторожевого таймера использую стандартную функцию "wdt_reset();"
Как сброс WDT по Вашему мнению должен работать, если
1. Вызов wdt_reset() закоментирован
2. Даже, если его раскоментировать: находится этот вызов в функции ZumerOut (другого вызова я не нашёл); функция ZumerOut ни откуда не вызывается, поэтому сброса WDT не производится.
MaksimYrievich
Цитата(Палыч @ Jul 5 2011, 11:32) *
Как сброс WDT по Вашему мнению должен работать, если
1. Вызов wdt_reset() закоментирован
2. Даже, если его раскоментировать: находится этот вызов в функции ZumerOut (другого вызова я не нашёл); функция ZumerOut ни откуда не вызывается, поэтому сброса WDT не производится.

Да нет, как бы это сказать правильнее... Вобщем если в функции "AtMega128_PHR_RegulatorInit();" раскоментировать любую ещё одну строку или две то микроконтроллер сбрасывается и начинает выполнение кода снова. Как будто стек что ли забивается или ещё что. Очень похоже на сброс от ватчдога, но на днях разобрался что он не причём. Вобщем каждый день сижу часов по пять и никак не въеду. На настоящий момент код выглядит вот так.. help.gif
Как бы сказать, получается, что не могу набить потолще функцию "AtMega128_PHR_RegulatorInit();" не понимаю чем глюк обусловлен

Вот этот рисунок посмотрите плиз там сам пример и вопрос. help.gif
Палыч
Цитата(MaksimYrievich @ Jul 6 2011, 20:58) *
Да нет, как бы это сказать правильнее... Вобщем если в функции "AtMega128_PHR_RegulatorInit();" раскоментировать любую ещё одну строку или две то микроконтроллер сбрасывается и начинает выполнение кода снова.
Как есть - так бы и сказали: убираем коментарий с такой-то строки и...
Частично ошибка видна: где-то там в этих строчках разрешается прерывание таймера, а соответствующей процедуры его обработки Вы не предусмотрели. В результате - вектор содержит команду перехода на адрес ноль, и при возникновении прерывания программа начинает выполнение заново...
MaksimYrievich
Странно, но я явно же не указывал разрешения от прерываний (SEI), я их запретил командой CLI() в самом начале. И ещё один аргумент несогласия, с вашим предположением это то , что такие строки как "//ASSR|= 1<<AS0;" или "//OCR0|= 31;" не должны бы как то влиять на прерывания, однако при их раскоментировании происходит сброс
Палыч
Может быть Вы не заметили, но и в текущем состоянии программа перезапускаeтся... Если Вы уберете разрешение прерывания по WDT, то всё прекрасно работает... Вы не успеваете сбрасывать WDT
MaksimYrievich
Нет не заметил. Или не понял о чём вы говорите. Инициализация сторожевого таймера происходит в главной функции и происходит после выполнения подпрограмм инициализации микроконтроллера и дисплея и МК до нее просто не доходит. Я же выше писал точнее рисунком показывал где заканчивается выполнение программы. Выполнение программы микроконтроллером заканчивается внутри функции "DisplayInit();". Причём так как указано в сообщении №3. Там рисунок и на нем указана проблема, для примера. Просто обратите внимание на порядок выполнения подпрограммы "DisplayInit();". Создается впечатление, что при выходе из подпрограммы "ComDispInit() " микроконтроллер сразу переходит на ресет. Вот версия проекта которая в отладке не сбрасывается. Вы правы подпрограмма "ZumerOut" слишком длинная и я в нее внес просто сброс сторожевого таймера и всё стало ништяк. Но это всё не решает более серьёзной, обозначенной выше проблемы Палыч...
Палыч
Цитата(MaksimYrievich @ Jul 6 2011, 23:29) *
Но это всё не решает более серьёзной, обозначенной выше проблемы
Нет здесь никакой проблемы... Уберите из программы разрешение работы WDT; разбиритесь с тем, что нужно сделать для нормальной работы функций _delay_; отладьте свою программу; ну, а потом уж (но, никак не раньше) вернёте в программу WDT...
MaksimYrievich
Цитата(Палыч @ Jul 6 2011, 23:40) *
разбиритесь с тем, что нужно сделать для нормальной работы функций _delay_;

Палыч, а что Вам не нравится про _делай_. Может быть я действительно что то не учёл или не знаю или не так подключил из файлов. Поясните пожалуйста, что Вы имеете конкретно ввиду?
Палыч
Цитата(MaksimYrievich @ Jul 6 2011, 23:44) *
что Вам не нравится про _делай_
Могу только Вас процитировать
Цитата
то же самое происходит при использовании стандартных фунций ... _delay_ms();, _delay_us();.
Как я себе понимаю, Вы не разобрались с правильным их использованием, и они отмеряют совсем не то время, что задано. Я не знаю точно, как в gcc правильно использовать эти функции (и поэтому подсказать не могу)... Но, например, для правильной их работы необходимо сообщить транслятору частоту тактового генератора - я не заметил: где это Вы делаете?
MaksimYrievich
Цитата(Палыч @ Jul 7 2011, 00:01) *
Я не знаю точно, как в gcc правильно использовать эти функции (и поэтому подсказать не могу)... Но, например, для правильной их работы необходимо сообщить транслятору частоту тактового генератора - я не заметил: где это Вы делаете?

А в чём Вы работаете? А то я уже устал с этим WinAVR и AVRStudio. Кошмар какой то не победимый!. Кстати при явном объявлении частоты проца ничего не изменяется - я пробовал, только лишняя ругань появляется о переопределении частоты МК. Частота мной выставляется в опциях компилятора.
MaksimYrievich
Ура!!!!!. Дет!!! райт!!! мазер!!! факу!!! Я разгадал этот ребус. Всё дело оказалось в том, что такие функции как "AtMega128_PHR_RegulatorInit();" в моём проекте т. е. те в которых явно не выделяется ни одна переменная должны быть объявлены как STATIC VOID. Так что да здравствует C/C++. И, господа, будьте внимательны!! Не натыкайтесь на мои грабли. Всем спасибо. Палыч, отдельное спасибо, за то что не бросал меня в трудную минуту.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.