ЭЛЕКТРОНИКА Прерывания сторожевого таймера не вызываются

Mark_gresh

✩✩✩✩✩✩✩
28 Янв 2026
29
1
Здравствуйте! Я программирую под тини2313а, в Ардуино ИДИ. Неодобрительные взгляды за использование "Абдурины" просьба перевести в спящий режим - я программирую только на регистрах, даже либы каталога avr/ скуплюсь подключать. Неодобрительные взгляды за то,что ленюсь спросить у ИИ, просьба перевести в спящий режим - ИИ нынче тупой пошёл,и хоть он и лез в Интернет,всё равно приплетает несуществующие регистры и прочую бурду. Так вот,я настраиваю сторожевой таймер как будильник из глубокого сна, но прерывание почему-то вышло на прогулку из МК,оно не вызывается. Пробовал не 8 секунд, а 16 мс - то же самое.Убирал бит прерывания из настройки - ждёт 8-9 секунд, ресетится вместе с прескалером и начинает дискотеку в стиле "а-ля бутлуп". То есть сброс работает. Но в прерывании - нет.
Мой код в майнере -
C++:
int main(){

  DDRB |= (...);

  DDRA |= (...);

  DDRD |= (...);

  PORTB |= (1<<DIOD);

  _my_delay_ms(100);

  PORTB &= ~(1<<DIOD);

  USICR |= 0B00100010;

  MCUSR &= ~(1<<WDRF);
  WDTCSR |= (1<<WDE)|(1<<WDCE);
    WDTCSR |= (1<<WDIE)|(1<<WDP0)|(1<<WDP3);
    MCUCR = 0B00110011;
    GIMSK |= (1<<INT0);
    lable:
    asm volatile("sleep");
    goto lable;
}
В самом начале прерывания я моргаю диодом,как на первых строчках. Стартовое моргание нормально, в прерывании не происходит. В чём может быть проблема?
 

Bruzzer

★★★★✩✩✩
23 Май 2020
846
263
Желательно приводить короткий код целиком.
В том коде, что вы показали я не увидел глобальное разрешение прерываний.
И мне кажется, что с регистром WDTCSR вы работаете неправильно (не по даташиту, но не уверен, т.к. сам не пробовал).
 
Изменено:

Mark_gresh

✩✩✩✩✩✩✩
28 Янв 2026
29
1
Желательно приводить короткий код целиком.
извините, просто спешил сильно.
В том коде, что вы показали я не увидел глобальное разрешение прерываний.
пробовал и с sei() в начале, тот же результат.
И мне кажется, что с регистром WDTCSR вы работаете неправильно (не по даташиту, но не уверен, т.к. сам не пробовал).
Я думал,что так по даташиту. Как минимум,я его с десяток раз в день перечитываю по частям. И сброс при такой же настройке, только без бита WDIE, работает. Но может и что-то забыл. Буду очень рад,если поправите.
 

Sergo_ST

★★★★★★✩
15 Мар 2020
1,331
968
@Mark_gresh, Вот так нужно инициализировать wdt таймер:
C++:
__asm__ __volatile__ ("WDR"); //сброс таймера wdt
MCUSR = 0x00; //очистка флагов сброса мк
WDTCSR = (1<<WDCE) | (1<<WDE); //разрешили изменения wdt
WDTCSR = (1<<WDIE) | (1<<WDP0) | (1<<WDP3); //установили режим прерывания по таймауту в ~8сек
sei(); //разрешили прерывания глобально
При этом вектор прерывания должен быть обязательно объявлен, или пустой(EMPTY_INTERRUPT) или с обработчиком(ISR).