Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Програмный сброс
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
maxus
Такой вопрос:
Как програмно (т.е. изнутри) сбросить AVR (ATMega128)? Апаратно понятно - по ресету все регистры переводятся в свои исходные состояния. А програмно? Надо их "вручную" переводить?
KRS
Использовать вотчдог

примерно так:

__disable_interrupt();
WDTCR=1<<WDE;
DeathLoop: goto DeathLoop;
bzx
Ресет контролера происходит в случае:
1. Power-on Reset - сброс по включению питания
2. External Reset - внешний сброс
3. Watchdog System Reset - сброс по вочдог таймеру
4. Brown-out Reset - проседание питания

Т.е. включи Watchdog на минимальное время и уйди в бесконечный цикл. Собственно maxus это уже предложил
G}{OST
Цитата(KRS @ Nov 10 2005, 18:21) *
Использовать вотчдог

примерно так:

__disable_interrupt();
WDTCR=1<<WDE;
DeathLoop: goto DeathLoop;

а точно - вот так (IAR 4.11):
Код
__disable_interrupt();

  // Write logical one to WDCE and WDE
  WDTCR = (1<<WDCE) |(1<<WDE);
  // Turn on WDT
  WDTCR = (1<<WDE) | (1<<WDP0) |(1<<WDP1);

#pragma diag_suppress=Pe236
  while(1);
#pragma diag_default=Pe236
maxus
Все понятно. Большее спасибо!!!
starter48
Цитата(maxus @ Nov 10 2005, 21:17) *
Такой вопрос:
Как програмно (т.е. изнутри) сбросить AVR (ATMega128)? Апаратно понятно - по ресету все регистры переводятся в свои исходные состояния. А програмно? Надо их "вручную" переводить?

Ещё такой вариант (переход по адр. 0, при таком сбросе не происходит инициализации регистров, что иногда очень желательно):
Код
void (*resetptr)(void) = 0x0000;

__disable_interrupt();
resetptr();
maxus
Этот вариант я вначале и пробовал. В некоторых ситуациях глючит (возможно как раз и из-за непереинициализации регистров) - разбираться не стал. smile.gif Вачдог, думаю - железно правильно все сбросит.
BVU
jmp START
KRS
Цитата(G}{OST @ Nov 10 2005, 17:35) *
Цитата(KRS @ Nov 10 2005, 18:21) *

Использовать вотчдог

примерно так:

__disable_interrupt();
WDTCR=1<<WDE;
DeathLoop: goto DeathLoop;

а точно - вот так (IAR 4.11):
Код
__disable_interrupt();

  // Write logical one to WDCE and WDE
  WDTCR = (1<<WDCE) |(1<<WDE);
  // Turn on WDT
  WDTCR = (1<<WDE) | (1<<WDP0) |(1<<WDP1);

#pragma diag_suppress=Pe236
  while(1);
#pragma diag_default=Pe236



Только лучше изменить строчку

WDTCR = (1<<WDE) | (1<<WDP0) |(1<<WDP1);

на
WDTCR = (1<<WDE) ;

тогда сброс произойдет намного быстрее
G}{OST
Цитата(KRS @ Nov 11 2005, 11:30) *
Только лучше изменить строчку

WDTCR = (1<<WDE) | (1<<WDP0) |(1<<WDP1);

на
WDTCR = (1<<WDE) ;

тогда сброс произойдет намного быстрее

А если точно - сброс произойдёт в 8 раз быстрее. wink.gif
IgorKossak
А если уж очень быстро надо и есть свободный вывод, то подключить его к выводу RESET и в нужный момент запрограммировать на выход.
Igor26
Цитата(IgorKossak @ Nov 15 2005, 14:51) *
А если уж очень быстро надо и есть свободный вывод, то подключить его к выводу RESET и в нужный момент запрограммировать на выход.

Проверенно. Классно!!!
Еще на х51 таким образом переключались в внутреннего ROM на внешний. Правда, это немного другая история...
starter48
Цитата(maxus @ Nov 11 2005, 14:11) *
Этот вариант я вначале и пробовал. В некоторых ситуациях глючит (возможно как раз и из-за непереинициализации регистров) - разбираться не стал. smile.gif Вачдог, думаю - железно правильно все сбросит.

Дело в том, что иногда нужно производить сброс чисто программно, как я показал в примере с переходом на адр. 0
Например, при запуске основной программы из бут-блока. Здесь тебе ни WDT, ни дёрганье RESET отдельной ногой не помогут.
IgorKossak
Цитата(starter48 @ Nov 16 2005, 08:06) *
Дело в том, что иногда нужно производить сброс чисто программно, как я показал в примере с переходом на адр. 0
Например, при запуске основной программы из бут-блока. Здесь тебе ни WDT, ни дёрганье RESET отдельной ногой не помогут.

Такой сброс, а это и не сброс вообще, а переход по заданному в явном виде адресу, выходит за рамки поднятой темы.
maxus
При сбросе все выводы ориентируются на ввод. Не получится ситуация, что вывод уже перевелся на ввод, а необходимое время для сброса еще не выдержано?
one_man_show
В таком случае сигнал растягивают ёмкостью
BVU
Цитата(one_man_show @ Nov 16 2005, 11:41) *
В таком случае сигнал растягивают ёмкостью

Немного подкорректирую - сигнал растягивают схемой 'формирователем', а емкость конденсатора играет роль фазосдвигающего элемента.
one_man_show
Корреция несомненно верная, но в большинстве случаев достаточно одного конденсатора smile.gif
Igor26
Цитата(maxus @ Nov 16 2005, 12:35) *
При сбросе все выводы ориентируются на ввод. Не получится ситуация, что вывод уже перевелся на ввод, а необходимое время для сброса еще не выдержано?

Чтоб этого избежать, мы применяли MAX691. На один из ее входов нужно подавать импульсную последовательность от процессора. Как только импульсы пропадали более чем, помоему, на пол секунды, происходило формирование достаточно длительного импульса сброса.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.