Например TDA7294

Форум РадиоКот • Просмотр темы - Сторожевой таймер ATMega16
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Пн июл 28, 2025 03:56:42

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 5 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Сторожевой таймер ATMega16
СообщениеДобавлено: Пн мар 21, 2016 12:02:38 
Родился

Зарегистрирован: Пн мар 21, 2016 11:36:03
Сообщений: 2
Рейтинг сообщения: 0
Сразу скажу - я новичок в программировании микроконтроллеров. Пишу на CodeVisionAVR.
Для моего проекта нужно использовать сторожевой таймер, во избежание некоторых непредвиденных ситуаций.

Так вот, этот код работает и по таймеру сбрасывает:
Код:
void main(void)
  {
    PortInit(); // Инициализацыия портов
    lcd_init(16);

    // Watchdog Timer initialization
    // Watchdog Timer Prescaler: OSC/2048k ~2 сек
    WDTCR=(0<<WDTOE) | (1<<WDE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
   
    while (1)
      {
      }
  }

если написать так, то таймер не срабатывает, так как есть #asm("wdr"):
Код:
void main(void)
  {
    PortInit(); // Инициализацыия портов
    lcd_init(16);

    // Watchdog Timer initialization
    // Watchdog Timer Prescaler: OSC/2048k ~2 сек
    WDTCR=(0<<WDTOE) | (1<<WDE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
   
    while (1)
      {
        #asm("wdr") // Сброс сторожевого таймера
      }
  }


А теперь самое интересное... В этом коде по таймеру не сбрасывается, хотя и #asm("wdr") вообще нету:
Код:
void main(void)
  {
    char i;
    char symb;

    PortInit(); // Инициализацыия портов
    lcd_init(16);

    // Watchdog Timer initialization
    // Watchdog Timer Prescaler: OSC/2048k ~2 сек
    WDTCR=(0<<WDTOE) | (1<<WDE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);

    symb = ':';
    lcd_gotoxy(0,0);                                //|
    lcd_putsf("  ALARM SYSTEM  ");                  //|
    delay_ms(500);                                  //|
    for (i=0;i<=15;i++)                             //|
      {                                             //| 
        lcd_gotoxy(i,1);                            //|
        lcd_putchar(symb);                          //|  Выводим анимацию символа ":"
        delay_ms(10);                               //|
      }                                             //|
    delay_ms(500);                                  //|
    lcd_clear();                                    //|
   
    while (1)
      {
        // тут должна быть команда сброса сторожевого таймера
      }
  }


Какой бы я код ни писал дальше (в цикле while (1) {}) - естественно по таймеру не сбрасывает...
Помогите, пожалуйста, разобраться почему так происходит? :?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Сторожевой таймер ATMega16
СообщениеДобавлено: Пн мар 21, 2016 16:29:06 
Родился

Зарегистрирован: Пн мар 21, 2016 11:36:03
Сообщений: 2
Рейтинг сообщения: 0
Начал удалять строки...
Пришел к тому, что как только добавляю строку #asm("wdr") сторожевой таймер не делает сброс вообще:
Код:
void main(void)
  {
    PortInit(); // Инициализацыия портов
    lcd_init(16);

    // Watchdog Timer initialization
    // Watchdog Timer Prescaler: OSC/2048k ~2 сек
    WDTCR=(0<<WDTOE) | (1<<WDE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0);
    #asm("wdr") // Сброс сторожевого таймера
    while (1)
      {
       
      }
  }

Я не понимаю, почему так? :dont_know:

По идее код выше должен работать так:
1. Инициализирую порты.
2. Инициализирую экран (хоть тут и не использую, от удаления этой строки ничего не меняется)
3. Инициализирую сторожевой таймер.
4. Сбрасываю его сразу.
5. Вхожу в пустой цикл.
6. По истечении ~2,1с - сторожевой таймер должен сбросить микроконтроллер и начать всё сначала.

Но пункт 6 не выполняется... Точнее в цикл заходит и всё что в цикле выполняет. Я в цикле для пробы сделал перемещение точки по экрану - она перемещается нормально и бесконечно... Но сброса нету...
Если убрать #asm("wdr") (п.4) - всё работает. Но получается что на исполнение всей программы выделяется ~2,1с - для меня этого мало, да и не нужно постоянно делать сброс.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Сторожевой таймер ATMega16
СообщениеДобавлено: Пн мар 21, 2016 19:01:27 
Друг Кота
Аватар пользователя

Карма: 32
Рейтинг сообщений: 482
Зарегистрирован: Сб сен 10, 2011 17:46:25
Сообщений: 3832
Рейтинг сообщения: 0
кодевиженовский визард настраивает ватчдог так:
Код:
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/2k
// Watchdog Timer interrupt: Off
#pragma optsize-
#asm("wdr")
WDTCSR=0x18;
WDTCSR=0x08;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

может в этом дело, проверить не могу ввиду наличия отсутствия установленного кодевижена


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Сторожевой таймер ATMega16
СообщениеДобавлено: Пн мар 21, 2016 20:38:18 
Говорящий с текстолитом
Аватар пользователя

Карма: 8
Рейтинг сообщений: 209
Зарегистрирован: Чт июн 10, 2010 20:11:19
Сообщений: 1520
Рейтинг сообщения: 0
oleg110592 писал(а):
кодевиженовский визард настраивает ...
...как говно. В плане понятности кода. Куча абсолютно ненужных комментариев и полное отсутствие нужных, использование магических чисел.
Возможно, дело в бите WDCE (мера предосторожности, чтобы собака не менялась случайно).


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Сторожевой таймер ATMega16
СообщениеДобавлено: Пн мар 21, 2016 22:31:09 
Друг Кота
Аватар пользователя

Карма: 32
Рейтинг сообщений: 482
Зарегистрирован: Сб сен 10, 2011 17:46:25
Сообщений: 3832
Рейтинг сообщения: 0
визард сейчас вроде исправился - по битикам с реальными названиями раскладывает, старые версии грешили магическими числами, никого из пользователей кодевижена это не волновало, ведь благодаря "чудо" визарду отпадает необходимость чтения документации. Похоже дело в отключении оптимизации - кодевижен при компиляции "оптимизирует" дважды запись в один и тот же регистр. А как с ватчдогом работать написано в документации, которую обычно не читают:
Цитата:
The Watchdog always on (WDTON) fuse, if programmed, will force the Watchdog Timer to Sys-
tem Reset mode. With the fuse programmed the System Reset mode bit (WDE) and Interrupt
mode bit (WDIE) are locked to 1 and 0 respectively. To further ensure program security, altera-
tions to the Watchdog set-up must follow timed sequences. The sequence for clearing WDE and
changing time-out configuration is as follows:
1. In the same operation, write a logic one to the Watchdog change enable bit (WDCE) and
WDE. A logic one must be written to WDE regardless of the previous value of the WDE
bit.
2. Within the next four clock cycles, write the WDE and Watchdog prescaler bits (WDP) as
desired, but with the WDCE bit cleared. This must be done in one operation.

Даже пример в документации есть:
Код:
void WDT_Prescaler_Change(void)
{
__disable_interrupt();
__watchdog_reset();
/* Start timed  equence */
WDTCSR |= (1<<WDCE) | (1<<WDE);
/* Set new prescaler(time-out) value = 64K cycles (~0.5 s) */
WDTCSR  = (1<<WDE) | (1<<WDP2) | (1<<WDP0);
__enable_interrupt();
}


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 5 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y