2 Yellow Tiger.
Слова "скорее всего" не надо понимать. В данном случае, simpleX, корректно намекнул - RTFM!
Т.е. если открыть в хелпе "студио" AVR Tools, то в разделе симуляции Notes for ATtiny2313 будет всего 4 строки. Одна из них The Watchdog is not simulated. Перевести?
Yellow Tiger писал(а):А как понимать слова "скорее всего" - как результат личного опыта, как цитату из некоей доки, о которой мы не знаем, или как-то иначе?
Как результат личного опыта (в AVR Studio). После нашел в хелпе иформацию об этом. "Скорее всего" было сказано на тот случай, если вам вдруг всё-таки удалось несмотря ни на что заставить IDE генерировать прерывания WDT =)
Для всех, кто ещё столкнётся с подобным.
При написании программы в CodeVisionAVR с использованием WDT
НЕ РЕКОМЕНДУЕТСЯ ПРИМЕНЯТЬ функции delay_ms или delay_us
встроенной библиотеки delay.h, поскольку в них имеется команда "wdr" сброса WD таймера.
Сам недавно наступил на эти "грабли" и благодарен a_skr за подсказку.
уточню, что применять задержки не то, чтобы не рекомендуется, а:
1. если WDT используется по своему прямому назначению - для защиты от зависаний, - то можно.
2. если WDT используется как генератор периодических прерываний, - то нужно иметь ввиду, что прерывания вы не получите пока выполняются функции задержек. а так ничего не мешает, если задержки используются относительно редко и прерываниями на эти моменты можно пожертвовать.
все вышесказанное относится только к CodeVisionAVR.
ELcat писал(а):Для всех, кто ещё столкнётся с подобным.
При написании программы в CodeVisionAVR с использованием WDT
НЕ РЕКОМЕНДУЕТСЯ ПРИМЕНЯТЬ функции delay_ms или delay_us
встроенной библиотеки delay.h, поскольку в них имеется команда "wdr" сброса WD таймера.
Сам недавно наступил на эти "грабли" и благодарен a_skr за подсказку.
Блин а я столько с wdt на tiny2313 промучился ,оказывается вот где засада.Кто знает,можно библиотеку cvavr подправить?
Подправить-то можно, да стоит ли? Правильнее всего задержки формировать при помощи таймеров. В моём случае WDT понадобился для вывода МК из "спячки", т.к. разрабатываемое устройство питается от батареи и для экономии энергии МК должен будет периодически "пробуждаться", опрашивать порты и заново уходить в "спячку". Лично мне сброс WDT в процедуре задержки даже наоборот кажется полезным - в рабочем цикле отпадает необходимость отключать WD.
Кто нибудь может дать нормальную инструкцию для начинающих, как включается WDT .
Как он сбрасывается. Желательно на С и для Atmel Studio (ибо есть нюансы с хидерами и самим языком С).
Моя проблема - отсчеты больших интервалов (до 180 мин). Были случаи зависания 2313.
Точнее, чем даёт datasheet (стр.42) не сможет дать никто. У ATtiny2313 WD с четырьмя возможными режимами: отключён, только прерывание, только сброс и прерывание с последующим сбросом (по окончанию первого интервала выдаётся запрос на прерывание, по второму - сброс). Максимально возможный интервал отсчёта - 8 секунд. Управляющий регистр один - WDTCSR. Именно он задаёт режим работы и временной интервал WD таймера. Будьте внимательны, некоторые операции с данным регистром требуют двух обращений (в первом необходимо установить бит разрешения изменений WDCE). Кроме того можно включить WD таймер соответствующим битом в поле фуз-битов.
Сброс WD таймера для всех компиляторов Си одинаков и выглядит как ассемблерная вставка с командой:
Так же следует учесть, что в случае с двойным срабатыванием (прерывание затем сброс), после первого срабатывания WD аппаратно сбрасывается бит разрешения прерываний WDIE регистра WDTCSR. Поэтому в обработчике прерываний WD необходимо предусмотреть команду восстановления данного бита, если и последующие срабатывания по задумке должны сопровождаться прерыванием, а не сбросом.
Ну а вообще, зависания столь простых микроконтроллеров, как Тини2313 могут быть обусловлены лишь плохой схемотехникой/разводкой печатной платы в условиях ЭМ помех с повышенной напряжённостью или наличием бага в вашем коде (например, ожидание какого-нибудь заведомо не происходящего события).
Спасибо за ответ.
Со схемотехникой - все в порядке. А вот с помехами - проблема. Изделие стоит в щите, где много импульсных БП и разных пускателей и реле.
Так что есть 100% уверенность в причине сбоев - помехи.
v_vovchek писал(а):Со схемотехникой - все в порядке...Так что есть 100% уверенность в причине сбоев - помехи.
Это взаимоисключающие явления. Если со схемотехникой и платой всё ок, то никакие помехи ей не страшны. Если причина зависаний не код, а именно помехи, то со схемотехникой и конструкцией платы не в порядке.
Добрый вечер. Столкнулся с проблемкой. Необходимо запустить на ATiny84 сторожевой таймер в режиме "только прерывание". На ATiny85 получилось, а на ATiny84 никак не получается. Reset получался. Спойлер
/* ATtiny 85/84, Atmel Studio 7 */
#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/atomic.h>
#include "tm1637(6).h"
volatile uint32_t n = 0;
ISR(WDT_vect){
n++;
led_digit(n);
}
int main(void){
serial_init();
led_digit(123456);// Test tm1637
// только прерывание
#if (__AVR_ATtiny85__)
// WDTCR – Watchdog Timer Control Register
WDTCR |= (1<<WDCE)|(1<<WDE);
WDTCR = (1<<WDIF)|(1<<WDIE)|
(1<<WDP2)|(1<<WDP1);// 1 Sec;
#endif
#if (__AVR_ATtiny84__)
// WDTCSR – Watchdog Timer Control and Status Register
WDTCSR |= (1<<WDCE)|(1<<WDE);
WDTCSR = (1<<WDIF)|(1<<WDIE)|
(1<<WDP2)|(1<<WDP1);// 1 Sec
#endif
_delay_ms(10);
sei();
while (1) { }
}
/*
//WDP3 - WDP2 - WPD1 - WDP0 - time
// 0 0 0 0 16 ms
// 0 0 0 1 32 ms
// 0 0 1 0 64 ms
// 0 0 1 1 0.125 s
// 0 1 0 0 0.25 s
// 0 1 0 1 0.5 s
// 0 1 1 0 1.0 s
// 0 1 1 1 2.0 s
// 1 0 0 0 4.0 s
// 1 0 0 1 8.0 s
*/
/*
Вы можете использовать сторожевой таймер только в режиме прерывания
(без сброса устройства), включив WDIE, а не WDE. Увеличьте (непостоянный)
счетчик в подпрограмме обслуживания прерывания,
и вы можете увеличить период таймера на все, что захотите.
*/
/*
WDE WDIE Watchdog Timer State Action on Time-out
0 0 Stopped None
0 1 Running Interrupt
1 0 Running Reset
1 1 Running Interrupt
*/
/*
Bit 3 – WDE: Watchdog Enable
Если WDE установлен, WDIE автоматически очищается
аппаратно при истечении времени ожидания. Это полезно
для обеспечения безопасности сброса сторожевого таймера
при использовании прерывания. После сброса бита WDIE
следующий тайм-аут приведет к сбросу.
Чтобы избежать сброса сторожевого таймера, WDIE должен
устанавливаться после каждого прерывания.
*/
/*
Bit 4 – WDCE: Watchdog Change Enable
Этот бит должен быть установлен, когда бит WDE записывается в логический ноль.
В противном случае сторожевой таймер не будет отключен. Однажды написано в
логическая единица, аппаратное обеспечение сбросит этот бит после четырех тактов.
См. Описание бита WDE для отключения сторожевого таймера.
процедура. Этот бит также должен быть установлен при изменении
битов предварительного делителя.
*/
// ATOMIC_BLOCK(ATOMIC_RESTORESTATE){}
Так вот и прыгаю с камешка на камешек. В этом контексте изучаю возможность применения WDT как альтернативу классическим таймерам Timer0/Timer1. Напр. обработать некоторые значения и каждые 8 сек. отправлять на индикатор.
Эйлер Леонард, или уберите строчку "WDTCSR |= (1<<WDCE)|(1<<WDE);", если вам только прерывание нужно, либо в прерывании каждый раз поднимайте WDIE назад: "WDTCSR |= (1<<WDIE)". Потому что в ДШ написано, что если WDE и WDIE выставлены одновременно, то при первом срабатывании таймера и переходе в прерывание, флаг WDIE снимается аппаратно и след. таймаут вызовет уже сброс, а не прерывание. У вас даже в комментарии это написано. Странно что цифры до 4 успевают дойти только в протеусе...
PS: Выводить цифры в прерывании не очень хорошо. Лучше led_digit вызывайте из основного цикла, в прерывании только инкрементируйте n.
NStorm, Благодарю за отклик. Приручить пёсика пока не удалось, не столь актуально. А Ваша рекомендация не размещать в прерываниях всякие индикаторы и телевизоры - это дело. (не скрою, есть такой грех). Пойду лучше повытряхиваю всё во while(1){}