Внешний сторожевой таймер это костыль для плохих разработчиков, которые не могут разработать нормально работающую программу для микроконтроллеров или стабильно работающую схему.

Тем более встроенный WDT имеется у большинства современных микроконтроллеров.

Но бывают случаи, когда приходится иметь дело с готовой платой или модулем с определенными проблемами. Свой первый WDT я сделал для борьбы с редкими, но все же иногда происходящими зависаниями ESP8266. Причем софтовый ресет тогда не спасал и ESP-шка не хотела переподключаться к WiFi. Передергивание питания внешним WDT решило проблему.

Вторая проблема возникла с GSM контроллером Elecrow ATMEGA 32u4 A9G. Здесь имели место быть очень редко случающиеся зависание SIM-карты. (Кстати эту же проблема бывает и с USB-модемами 3G и 4G). Для борьбы с таким зависанием нужно передернуть питание на SIM-ке. И вроде даже вывод у GSM модема для этого есть, но в схемотехнику устройства данная возможность не заложена. И для достижения максимальной надежность пришлось снова обращаться к внешней сторожевой собаке.

Схему на таймере 555 я не стал повторять. Слишком много недостатков у нее выявилось:

  • Большие габариты и довольно много обвязки
  • Неудобная установка времени срабатывания подстроечным резистором
  • Довольно длительное время сброса (необходима разрядка конденсатора)
  • Ну и потенциальное зависание МК с низким уровнем на выходе таймера, когда таймер просто перестает срабатывать.
  • А проектов OpenSource в интернете, полностью соответствующих моим требованиям, я не нашел.

Требования к новому WDT


  • Низкая цена устройства, простота изготовления и малые габариты
  • Управление периодической сменой логического уровня 0/1 на входе
  • Простая настройка времени срабатывания (как вариант выбор из предустановленных интервалов)

Разработка железа


В качестве основной микросхемы выбрал микроконтроллер ATtiny13. Его возможностей оказалось более чем достаточно для моей задачи. А цена, с учетом уменьшения элементов обвязки — практически такая же как у 555 микросхемы.



Пять выводов МК (RESET решил не трогать) распределились следующим образом:

  1. Выход таймера
  2. Вход для сброса
  3. Три оставшихся вывода — задания времени срабатывания

Для коммутации питания используется P-канальный MOSFET. Подойдет любой совместимый по корпусу, но желательно брать с так называемым «логическим уровнем управления» — то есть полностью открывающийся от низкого напряжения 3-5В: IRLML2502, AO3415 и т.п. Несмотря на малые размеры, данный транзистор способен управлять нагрузкой в 4А. Если нужно коммутировать что-то другое, к этому выходу можно напрямую подключить реле на 5В.

Светодиод загорается в момент срабатывания таймера и отключения основного устройства.

Основной разъем для подключения к плате микроконтроллера имеет четыре вывода

  1. Общая шина
  2. Вход — сброс таймера
  3. Выход +5В (управляется таймером)
  4. Вход +5В

Два разъема — ICSP программатор и джамперы питания можно не устанавливать на плате. Микроконтроллер прошить в программаторе заранее, а время срабатывания задать постоянной перемычкой.

Список комплектующих



Изготовление


Платы получились маленькие — 18?22 мм. Я развел два варианта:

Для одностороннего изготовления ЛУТом:





И для заказа на заводе с улучшенным дизайном и переходами меж сторонами. (Закажу у китайцев, при случае)





Домашние технологии дают примерно такой прототип.







Прошивка


Для прошивки использовал самодельный программатор на баз Arduino Nano



Программировал я в среде Arduino IDE с установленной поддержкой Attiny13 — MicroCore. В последней версии IDE были проблемы программатора ArduinoISP, но нормально заработало в версии Arduino IDE 1.6.13. Разбираться, что там накосячила наизменяла дружная команда arduino.cc желания не возникло )))



Тиньку настроил на работу от внутреннего резонатора с частотой 1.2МГц. Программа простая — настраиваем входы/выходы, считываем PB2 -PB4 и определяем время срабатывания, настраиваем таймер и переходим в режим IDLE. По прерыванию по таймеру определяем состояние контрольного входа. Если состояние изменилось на противоположное, сбрасываем счетчик. Если показания счетчика превысило установленное время срабатывания — передергиваем питание на выходе.

#define F_CPU 1200000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

boolean pb1_state; 
volatile uint16_t pb1_count;

// Оброботчик прерывания по таймеру TIMER0
ISR(TIM0_OVF_vect){
   pb1_count++;  
}

int main(){
// Устанавливаем выход PB0 
   DDRB |= (1 << PB0);      // pinMode(PB0, OUTPUT); 
   PORTB &= ~(1 << PB0);    // digitalWrite(PB0, LOW);}
// Устанавливаем вход PB1 с подтягиванием 
   DDRB &= ~(1 << PB1);    // pinMode(PB1, INPUT_PULLUP);   
   PORTB |= (1 << PB1);    
// Устанавливаем вход PB2 с подтягиванием 
   DDRB &= ~(1 << PB2);    // pinMode(PB2, INPUT_PULLUP);   
   PORTB |= (1 << PB2);    
// Устанавливаем входы PB3 с подтягиванием 
   DDRB &= ~(1 << PB3);    // pinMode(PB3, INPUT_PULLUP); 
   PORTB |= (1 << PB3);    
// Устанавливаем входы PB4 с подтягиванием 
   DDRB &= ~(1 << PB4);    // pinMode(PB4, INPUT_PULLUP);  
   PORTB |= (1 << PB4);    
// Определяам время срабатывание таймера по входам PB2,PB3,PB4 (перемычки подтягивают к земле) (период, сек = TM/4 )
   uint16_t TM = 0;
   bool pb2 = false;
   bool pb3 = false;
   bool pb4 = false;
   if( PINB & (1 << PINB2) )pb2 = true;
   if( PINB & (1 << PINB3) )pb3 = true;
   if( PINB & (1 << PINB4) )pb4 = true;

   if( pb2 == true  && pb3 == true  && pb4 == true )TM = 4;         //Таймаут 1 сек
   else if( pb2 == false && pb3 == true  && pb4 == true  )TM = 8;   //Таймаут 2 сек
   else if( pb2 == true  && pb3 == false && pb4 == true  )TM = 20;  //Таймаут 5 сек
   else if( pb2 == false && pb3 == false && pb4 == true  )TM = 40;  //Таймаут 10 сек
   else if( pb2 == true  && pb3 == true  && pb4 == false )TM = 80;  //Таймаут 20 сек
   else if( pb2 == false && pb3 == true  && pb4 == false )TM = 120; //Таймаут 30 сек
   else if( pb2 == true  && pb3 == false && pb4 == false )TM = 240; //Таймаут 60 сек
   else if( pb2 == false && pb3 == false && pb4 == false )TM = 480; //Таймаут 120 сек
   pb1_count = 0;
   pb1_state = false;
// Отключаем ADC
   PRR = (1<<PRADC); // shut down ADC
// Настраиваем таймер
   TIMSK0 = (1<<TOIE0);  // Включаем таймер TIMER0
   TCCR0B = (1<<CS02) | (1<<CS00); // Пределитель таймера на 1/1024
// Задаем режим сна
   MCUCR &= ~(1<<SM1); // idle mode
   MCUCR &= ~(1<<SM0); // idle mode
   MCUCR |= (1<<SE);
   sei();
   while(1) {
// Зпсываем до прерывания по таймеру    
     asm("sleep");
// Таймер сработал 
     TIMSK0 &= ~ (1<<TOIE0);  // Останавливаем TIMER0       
// Считываем состояние PB1
    bool pb1 = false;
    if( PINB & (1 << PINB1) )pb1 = true;  
// Если состояние входа инвертировалось, сбрасываем время
    if( pb1 != pb1_state )pb1_count = 0;
    pb1_state = pb1;
// Если превышено время установки таймера
    if( pb1_count >= TM ){
       PORTB |= (1 << PB0);    // digitalWrite(PB0, HIGH);}
       _delay_ms(1000);        // Ждем секунду
       PORTB &= ~(1 << PB0);   // digitalWrite(PB0, LOW);}
       pb1_count = 0;          // Сбрасываем счетчик
    }
    TIMSK0 = (1<<TOIE0);    // Включаем таймер TIMER0
    sei();           
   
  }
  return 0;
}

Весь код уместился в 340 байт — ровно треть от килобайта памяти тиньки. Работа таймера проверяется просто — в зависимости от времени установки — периодически загорается светодиод на 1 сек. В это время на выходе Vвых напряжение 5В пропадает. Если контакт «вход» с периодичностью 1 сек замыкать на землю — сброс не производится и светодиод не загорается.

Управление WDT в основной программе следующее

#define PIN_WDT 5 //GPIO контроллера, куда подключен WDT
bool WDT_flag = false;

// Инициализация порта таймера
void WDT_begin(){
   pinMode(PIN_WDT,OUTPUT);
   digitalWrite(PIN_WDT,WDT_FLAG);
}

// Сброс таймера (не реже чем 1 на время срабатывания WDT, установленное перемычкой)
void WDT_reset(){
   if( WDT_flag)WDT_flag = false;
   else WDT_flag = true;
   digitalWrite(PIN_WDT,WDT_FLAG);
}

Вот собственно а все. Все исходные файлы, схемы и печатные платы можно скачать с
Github

Комментарии (45)


  1. jaiprakash
    06.04.2019 12:16
    +1

    К сожалению, в сложной электромагнитной обстановке AVR-ка прекрасно зависает вместе с её сторожевиком.


    1. sav13 Автор
      06.04.2019 12:27

      Так можно практически про любую маломощную схему сказать. 24 вольтовое клацкающее реле с током обмотки по 0.5А тут намного надежнее )))
      Делал WDT под свою задачу — удаленные устройства сбора информации на GSM с небольшим бюджетом, когда выезд на место перегрузить зависший модем очень затратное мероприятие


      1. jaiprakash
        06.04.2019 12:57

        Против вашего решения ничего не имею, даже неиспользование специальных микросхем можно объяснить тем, что нужно было срочно, а тиньки валялись россыпью.
        Я скорее пишу как предупреждение тем, кто попытается применить это в других условиях.
        Чисто умозрительно, чем проще микросхема, тем лучше справится с помехами, а МК не просты.


        1. olartamonov
          06.04.2019 13:15

          В тиньке вообще свой вотчдог есть. Стоит его использовать.

          Ну и вообще вся программа написана странно. Заводим таймер, по изменению состояния на входе сбрасываем его счётчик, по переполнению — сбрасываем контролируемое устройство. Всё.

          Hint: и да, в качестве таймера можно использовать таймер собственного вотчдога тиньки ;)


          1. jaiprakash
            06.04.2019 13:26

            У меня как-то AVR стабильно зависал вместе с вочдогом. Из-за наводок. Так что «глупый» внешний вочдог имхо надёжнее.


            1. sav13 Автор
              06.04.2019 13:43

              ХЗ. У меня AVR-ки сами по себе не зависали. Вот всякие там ESP-шки это да. Хотя в области сильных электромагнитных помех я их не ставил. Там как то уже промышленные решения нужны.


            1. olartamonov
              06.04.2019 15:01

              Так что «глупый» внешний вочдог имхо надёжнее


              Это всегда.


            1. sim31r
              07.04.2019 00:28

              WDT не должен висеть в прерывании и еще есть несколько нюансов. Если помеховая обстановка такая что «ужас-ужас», можно проверять значение всех переменных и чуть что не так перезагружать микроконтроллер. В итоге, как бы не изменилось содержание RAM, микроконтроллер просто не сможет зависнуть.
              Умный ватчдог может кроме простого зависания отслеживать сбой в передаче данных, не корректные данные с модема, изменение потребления тока схемой, не корректное питание, защищать от высоких и низких температур, ограничивать количество перезагрузок если они не помогают и еще по мелочам.


              1. jaiprakash
                07.04.2019 14:20

                Я наверное непонятно выразился.
                Происходила полная остановка всего, включая внутренний wdt. Как проверять ram, если тактирование зависло?
                Чем умнее внешний вочдог, тем он более подвержен воздействию. И вот нам уже нужны надзиратели за надзирателями.


                1. Andy_Big
                  07.04.2019 16:09

                  Происходила полная остановка всего, включая внутренний wdt.

                  Да, тактирование вачдога от общего клока — слабое место. Хорошо когда в контроллере есть IWDT — совершенно независимый вачдог, тактирующийся от собственного внутреннего генератора :)


                  1. jaiprakash
                    07.04.2019 16:15

                    Так в AVR независимый генератор для вочдога. Останавливались оба.


                    1. Andy_Big
                      07.04.2019 17:09

                      Тогда фиг знает… Это какие наводки должны быть чтобы низкочастотный неуправляемый RC-генератор завис :)


                      1. jaiprakash
                        07.04.2019 18:09

                        Достаточно в схеме индуктивности с высоковольтными выбросами. Да, можно всё развязать гальванически и заэкранировать, но в прототипе было по-простому. Хоть и не на висящих проводах, плата была вытравлена, но не сильно помогло.


          1. sav13 Автор
            06.04.2019 13:38

            По INT0 думал, но решил, что может всякий «мусор» ловить и сбрасываться
            Переполнение счетчика можно настроить на 30 секунд?


            1. olartamonov
              06.04.2019 15:09

              По INT0 думал, но решил, что может всякий «мусор» ловить и сбрасываться


              а) Подавления дребезга и фильтрации мусора у вас в коде нет, так что ваше решение лучше только тем, что на мусор будет реагировать только при его прилёте в момент опроса, что не есть надёжная защита

              б) Ничто не мешает на прерываниях сделать не просто ловлю импульса сброса, а определение его ширины и сравнение с минимально допустимой — но тогда будьте добры со стороны контролируемого устройства обеспечить формирование импульсов сброса заданной ширины (и это всё не имеет практического смысла в 99,999 % случаев)

              Переполнение счетчика можно настроить на 30 секунд


              Вы у меня спрашиваете? Тиньки вы программируете, я их и в руках-то не знаю сколько лет не держал. Это в даташите написано.


  1. jaiprakash
    06.04.2019 12:40

    А что не так со специализированными сторожевиками, типа ADM6316, ADM823, ADM824?


  1. olartamonov
    06.04.2019 12:44

    А STWD100 и прочие аппаратные вотчдоги, коих выпускается полно, благородному дону чем не угодили?..

    Ну и если уж делать свой, то зачем такой гроб, как ATTiny13? Есть же PIC10, есть ATTiny4/5/9/10 в SOT23.


    1. sav13 Автор
      06.04.2019 13:28

      Ни вижу, почему бы благородному дону не собрать WDT на тиньке 13 )))
      На самом деле вы правы, руководствовался принципом — слепила из того что было.
      Тиньки были в наличии, а остальное покупать нужно.


  1. Vanellope
    06.04.2019 13:52

    А почему такие тонкие дорожки на плате?


    1. sav13 Автор
      06.04.2019 13:59

      0.33 сигнальные
      0.50 питание
      Нормально для ЛУТ. Удобно между контактами 2.54 пропускать


  1. neitri
    06.04.2019 14:25

    Предложу свой вариант программы
    #define F_CPU 1200000UL
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    
    volatile uint16_t pb1_count;
    
    // Оброботчик прерывания по таймеру TIMER0
    ISR(TIM0_OVF_vect){
       pb1_count++;  
    }
    
    int main() {
    // Устанавливаем выход PB0 и вход PB1 PB2 PB3 PB4 с подтягиванием 
      DDRB = (1 << PB0)| (~(1 << PB1)) | (~(1 << PB2)) | (~(1 << PB4));
      PORTB = ~(1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (1 << PB4);
      
    // Определяам время срабатывание таймера по входам PB2,PB3,PB4 (перемычки подтягивают к земле) (период, сек = TM/4 )
      byte i=0;
      if( PINB & (1 << PINB2) ) i+=1;
      if( PINB & (1 << PINB3) ) i+=2;
      if( PINB & (1 << PINB4) ) i+=4;
      uint16_t TM;
      switch (i){
        case 0: TM=4; break;
        case 1: TM=8; break;
        case 2: TM=20; break;
        case 3: TM=40; break;
        case 4: TM=80; break;
        case 5: TM=120; break;
        case 6: TM=240; break;
        default: TM=480;
      }
      
       pb1_count = 0;
       boolean pb1_state = false;
    // Отключаем ADC
       PRR = (1<<PRADC); // shut down ADC
    // Настраиваем таймер
       TIMSK0 = (1<<TOIE0);  // Включаем таймер TIMER0
       TCCR0B = (1<<CS02) | (1<<CS00); // Пределитель таймера на 1/1024
    // Задаем режим сна
       MCUCR &= ~(1<<SM1); // idle mode
       MCUCR &= ~(1<<SM0); // idle mode
       MCUCR |= (1<<SE);
       sei();
       while(1) {
    // Зпсываем до прерывания по таймеру    
         asm("sleep");
    // Таймер сработал 
    // Считываем состояние PB1
        bool pb1 = false;
        if( PINB & (1 << PINB1) )pb1 = true;  
    // Если состояние входа инвертировалось, сбрасываем время
        if( pb1 != pb1_state )pb1_count = 0;
        pb1_state = pb1;
    // Если превышено время установки таймера
        if( pb1_count >= TM ){
           PORTB |= (1 << PB0);    // digitalWrite(PB0, HIGH);}
           pb1_count = 0;
           //_delay_ms(1000);        // Ждем секунду
           while (pb1_count<4){};
           PORTB &= ~(1 << PB0);   // digitalWrite(PB0, LOW);}
           pb1_count = 0;          // Сбрасываем счетчик
        }
      }      
    }


    1. sav13 Автор
      06.04.2019 15:38

      Согласен. Над оптимизацией кода еще работать и работать.
      Только вот ваш код у меня меньше не получается. Может быть LTO оптимизатор компилятор мою конструкцию преобразует в что-то еще более компактное?


    1. neitri
      06.04.2019 16:23

      const uint16_t AT[] PROGMEM ={4,8,20,40,80,120,240,480};
      TM=AT[i];
      Program Memory Usage: 320 bytes 31,3 % Full
      Data Memory Usage: 18 bytes 28,1 % Full

      static const uint16_t AT[] PROGMEM ={4,8,20,40,80,120,240,480};
      TM=AT[i];

      Program Memory Usage: 266 bytes 26,0 % Full
      Data Memory Usage: 2 bytes 3,1 % Full


    1. Andy_Big
      06.04.2019 18:36

      byte i=0;
      if( PINB & (1 << PINB2) ) i+=1;
      if( PINB & (1 << PINB3) ) i+=2;
      if( PINB & (1 << PINB4) ) i+=4;

        uint16_t TM;
        switch ((PINB & 0x1C)){
          case 0: TM=4; break;
          case 1<<2: TM=8; break;
          case 2<<2: TM=20; break;
          case 3<<2: TM=40; break;
          case 4<<2: TM=80; break;
          case 5<<2: TM=120; break;
          case 6<<2: TM=240; break;
          default: TM=480;
        }
      


      1. neitri
        06.04.2019 18:50

        static const uint16_t AT[] PROGMEM ={4,8,20,40,80,120,240,480};
        TM=AT[((PINB & 0x1C)>>2)];


        1. Andy_Big
          06.04.2019 18:54

          Ну да, так еще компактнее получится :)


      1. Andy_Big
        06.04.2019 19:15

        Кстати, если условие свича изменить на такое:

        switch ((PINB & 0x1C)>>2){
            case 0: TM=4; break;
            case 1: TM=8; break;
            case 2: TM=20; break;
            case 3: TM=40; break;
            case 4: TM=80; break;
            case 5: TM=120; break;
            case 6: TM=240; break;
            default: TM=480;
          }

        То компилятор оптимизирует его еще лучше.
        Но наиболее компактный вариант — у neitri


  1. AKudinov
    06.04.2019 14:34
    +1

    Внешний сторожевой таймер это костыль для плохих разработчиков, которые не могут разработать нормально работающую программу для микроконтроллеров или стабильно работающую схему.

    Вот это да-а-а…
    Статью с таким начальным посылом можно дальше не читать?


    1. Sun-ami
      06.04.2019 16:18

      Да, посыл в корне неверный. Сторожевой таймер — это защита прежде всего от аппаратных сбоев, которые невозможно предотвратить на 100% — всегда есть естественная радиация, и возможны внешние электромагнитные воздействия, от которых не спасут все применяемые на практике меры противодействия им. И применяются они не только в микроконтроллерах, но и в промышленных компьютерах и серверах.


  1. olartamonov
    06.04.2019 15:15

    // Сброс таймера (не реже чем 1 на время срабатывания WDT, установленное перемычкой)


    И, кстати, да, но нет.

    Таймеры на встроенных в контроллер RC-генераторах довольно нестабильны по температуре, поэтому надо смотреть не номинальное время срабатывания у вас на столе (оно же «установленное перемычкой»), а минимально возможное в температурном диапазоне эксплуатации устройства. Оно запросто может отличаться на десятки процентов.


    1. sav13 Автор
      06.04.2019 17:34

      В ATtiny13 4-е поколение встроенного генератора, имеющее неплохую внутреннюю калибровку. Как правила, настройка калибровочных значений идет уже с завода. При необходимости можно произвести самостоятельную температурную калибровку с достижением 1% точности, что для моих задач более чем достаточно


      1. olartamonov
        06.04.2019 18:58
        +2

        При необходимости можно произвести самостоятельную температурную калибровку с достижением 1% точности


        Вы планируете к своему вотчдогу ещё и высокоточный термодатчик добавлять?..


  1. RamirezRodrigues
    06.04.2019 17:26
    +2

    Удивлен, что в устройстве, которое делается «для достижения максимальной надежности», нет резистора 10K для ноги reset и конденсатора 100 nF на питание.

    easyelectronics.ru/podklyuchenie-mikrokontrollera-likbez.html


    1. sav13 Автор
      06.04.2019 17:28

      На ресет, как и на другие входы, есть встроенная подияжка
      0.1мкф по питанию — в даташите такого нету. А если учесть, что высокочастотной нагрузки нету, то в принципе можно и обойтись


    1. sav13 Автор
      07.04.2019 15:28

      Почему бы не обратиться по подтяжке к даташиту на AVR?

      When designing a system where debugWIRE will be used, the following must be observed:
      • Pull-Up resistor on the dW/(RESET) line must be in the range of 10k to 20 k?. However, the
      pull-up resistor is optional.



  1. Andy_Big
    06.04.2019 18:46

    Только я что-то не понял плюсов подобного принципа работы вачдога — строго периодичное изменение сигнала. Вроде вачдоги всегда строятся на превышении времени между сбросами, а не на строгой синхронности с отслеживаемым девайсом, которому нельзя ни шага влево-вправо от заданного периода сброса.


  1. apple01
    06.04.2019 18:50

    image
    Мой вариант watchdog на ATTINY13 для ESP8266 в формате шилда Wemos D1. Питание подается через разъем USB, программирование задержек осуществляется перемычками на оборотной стороне. В случае зависания ESP8266 ей отключается питание на выбранный интервал времени.


  1. slog2
    06.04.2019 21:48
    +2

    Я на схеме не увидел ни одного конденсатора, шунтирующего питание. Сомневаюсь что этот «костыль для плохих разработчиков» будет надёжнее самого защищаемого устройства.


    1. KN_Dima
      07.04.2019 06:57

      Повесить МК можно не только по питанию, но и по… выходу, а они здесь выведены напрямую, так что да — вы правы.


  1. amartology
    07.04.2019 09:55
    +2

    Внешний сторожевой таймер это костыль для плохих разработчиков, которые не могут разработать нормально работающую программу для микроконтроллеров или стабильно работающую схему.
    Вот где-то тут я начал подозревать, что автор не понимает в вочдогах примерно ничего.

    Тем более встроенный WDT имеется у большинства современных микроконтроллеров.
    И второе предложение усугубило это подозрение.

    Вот что пишет про вочдоги автор, которому действительно можно доверять (Ганссл):
    WDTs are not emergency outs, but integral parts of our systems. The WDT is as important as main() or the runtime library, it's an asset that is likely to be used, and maybe used a lot.


  1. AKudinov
    07.04.2019 10:22

    Окончательно закрепляет впечатление комментарий выше про подтяжки на входах и фильтрацию питания.


    1. sav13 Автор
      07.04.2019 15:18

      Подскажите литературу про обязательную внешнюю подтяжку?
      В даташите на ATtiny13 сказано, что встроенной подтяжки вполне достаточно

      When designing a system where debugWIRE will be used, the following must be observed:
      • Pull-Up resistor on the dW/(RESET) line must be in the range of 10k to 20 k?. However, the
      pull-up resistor is optional.


      1. jaiprakash
        07.04.2019 16:23

        Это правило хорошего тона, основанное на практике. Если вы можете абсолютно гарантировать что все ваши устройства никогда не попадут в условия наводок, или возможный слёт прошивки для вас неважен — необязательно подтягивать.


        1. AKudinov
          07.04.2019 16:58

          Прямо вот с языка сняли про правило хорошего тона.
          В даташите на ATtiny13 сазано, что подтяжка на входе Reset имеет сопротивление 30..80 кОм. Да, «на столе» и в «тепличных условиях» этого достаточно, но в более жёстких условиях сопротивление хочется иметь поменьше, чтобы амплитуда импульсов напряжения, наводимых помехами на входы МК, была поменьше, потому и нужен внешний резистор. Я бы его вообще намертво к питанию приколотил, но через Reset ещё debugWire ходит.
          Ну, а ёмкость 0.1 мкФ рядом с выводами питания — просто классика жанра. С одной стороны, улучшает стабильность работы самой микросхемы (контур, через который текут высокочастотные токи помех, замыкается через ёмкость, его площадь и индуктивность снижаются, уменьшая вероятность возникновения бросков напряжения, способных завесить микросхему; мы же стабильно работающую схему проектируем), с другой стороны, защищает цепи питания от внешнего мира (опять же, токи помех замыкаются через ёмкость).


          1. olartamonov
            07.04.2019 19:37

            Вообще говоря, как минимум в STM32 и EFM32 на ресете есть фильтр, который гарантированно отсекает помехи длительностью до 50 нс, в результате чего встроенной подтяжки вполне достаточно — при отсутствии длинной дорожки до ресета и электроэрозионного станка в радиусе нескольких метров.

            В тиньке они тоже есть, но их параметры в явной форме даташит не сообщает.