Универсальный сторожевой таймер на ATtiny13


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

    Тем более встроенный 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
    Share post
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 45

      +2
      К сожалению, в сложной электромагнитной обстановке AVR-ка прекрасно зависает вместе с её сторожевиком.
        0
        Так можно практически про любую маломощную схему сказать. 24 вольтовое клацкающее реле с током обмотки по 0.5А тут намного надежнее )))
        Делал WDT под свою задачу — удаленные устройства сбора информации на GSM с небольшим бюджетом, когда выезд на место перегрузить зависший модем очень затратное мероприятие
          +1
          Против вашего решения ничего не имею, даже неиспользование специальных микросхем можно объяснить тем, что нужно было срочно, а тиньки валялись россыпью.
          Я скорее пишу как предупреждение тем, кто попытается применить это в других условиях.
          Чисто умозрительно, чем проще микросхема, тем лучше справится с помехами, а МК не просты.
            +2
            В тиньке вообще свой вотчдог есть. Стоит его использовать.

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

            Hint: и да, в качестве таймера можно использовать таймер собственного вотчдога тиньки ;)
              0
              У меня как-то AVR стабильно зависал вместе с вочдогом. Из-за наводок. Так что «глупый» внешний вочдог имхо надёжнее.
                0
                ХЗ. У меня AVR-ки сами по себе не зависали. Вот всякие там ESP-шки это да. Хотя в области сильных электромагнитных помех я их не ставил. Там как то уже промышленные решения нужны.
                  +1
                  Так что «глупый» внешний вочдог имхо надёжнее


                  Это всегда.
                    0
                    WDT не должен висеть в прерывании и еще есть несколько нюансов. Если помеховая обстановка такая что «ужас-ужас», можно проверять значение всех переменных и чуть что не так перезагружать микроконтроллер. В итоге, как бы не изменилось содержание RAM, микроконтроллер просто не сможет зависнуть.
                    Умный ватчдог может кроме простого зависания отслеживать сбой в передаче данных, не корректные данные с модема, изменение потребления тока схемой, не корректное питание, защищать от высоких и низких температур, ограничивать количество перезагрузок если они не помогают и еще по мелочам.
                      0
                      Я наверное непонятно выразился.
                      Происходила полная остановка всего, включая внутренний wdt. Как проверять ram, если тактирование зависло?
                      Чем умнее внешний вочдог, тем он более подвержен воздействию. И вот нам уже нужны надзиратели за надзирателями.
                        0
                        Происходила полная остановка всего, включая внутренний wdt.

                        Да, тактирование вачдога от общего клока — слабое место. Хорошо когда в контроллере есть IWDT — совершенно независимый вачдог, тактирующийся от собственного внутреннего генератора :)
                          0
                          Так в AVR независимый генератор для вочдога. Останавливались оба.
                            0
                            Тогда фиг знает… Это какие наводки должны быть чтобы низкочастотный неуправляемый RC-генератор завис :)
                              0
                              Достаточно в схеме индуктивности с высоковольтными выбросами. Да, можно всё развязать гальванически и заэкранировать, но в прототипе было по-простому. Хоть и не на висящих проводах, плата была вытравлена, но не сильно помогло.
                    0
                    По INT0 думал, но решил, что может всякий «мусор» ловить и сбрасываться
                    Переполнение счетчика можно настроить на 30 секунд?
                      +1
                      По INT0 думал, но решил, что может всякий «мусор» ловить и сбрасываться


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

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

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


                      Вы у меня спрашиваете? Тиньки вы программируете, я их и в руках-то не знаю сколько лет не держал. Это в даташите написано.
              +2
              А что не так со специализированными сторожевиками, типа ADM6316, ADM823, ADM824?
                +1
                А STWD100 и прочие аппаратные вотчдоги, коих выпускается полно, благородному дону чем не угодили?..

                Ну и если уж делать свой, то зачем такой гроб, как ATTiny13? Есть же PIC10, есть ATTiny4/5/9/10 в SOT23.
                  0
                  Ни вижу, почему бы благородному дону не собрать WDT на тиньке 13 )))
                  На самом деле вы правы, руководствовался принципом — слепила из того что было.
                  Тиньки были в наличии, а остальное покупать нужно.
                  0

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

                    0
                    0.33 сигнальные
                    0.50 питание
                    Нормально для ЛУТ. Удобно между контактами 2.54 пропускать
                    0
                    Предложу свой вариант программы
                    #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;          // Сбрасываем счетчик
                        }
                      }      
                    }


                    Вот чего я не ожидал.
                      byte i=0;
                      if( PINB & (1 << PINB2) ) i+=1;
                      if( PINB & (1 << PINB3) ) i+=2;
                      if( PINB & (1 << PINB4) ) i+=4;
                      const PROGMEM uint16_t AT[]={4,8,20,40,80,120,240,480};
                      uint16_t TM=AT[i];
                    Этот код на 40 байт кода и на 8 байт озу больше.
                      0
                      Согласен. Над оптимизацией кода еще работать и работать.
                      Только вот ваш код у меня меньше не получается. Может быть LTO оптимизатор компилятор мою конструкцию преобразует в что-то еще более компактное?
                        0
                        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
                          0
                          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;
                            }
                          
                            0
                            static const uint16_t AT[] PROGMEM ={4,8,20,40,80,120,240,480};
                            TM=AT[((PINB & 0x1C)>>2)];
                              0
                              Ну да, так еще компактнее получится :)
                              0
                              Кстати, если условие свича изменить на такое:
                              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
                            +2
                            Внешний сторожевой таймер это костыль для плохих разработчиков, которые не могут разработать нормально работающую программу для микроконтроллеров или стабильно работающую схему.

                            Вот это да-а-а…
                            Статью с таким начальным посылом можно дальше не читать?
                              +1
                              Да, посыл в корне неверный. Сторожевой таймер — это защита прежде всего от аппаратных сбоев, которые невозможно предотвратить на 100% — всегда есть естественная радиация, и возможны внешние электромагнитные воздействия, от которых не спасут все применяемые на практике меры противодействия им. И применяются они не только в микроконтроллерах, но и в промышленных компьютерах и серверах.
                              +1
                              // Сброс таймера (не реже чем 1 на время срабатывания WDT, установленное перемычкой)


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

                              Таймеры на встроенных в контроллер RC-генераторах довольно нестабильны по температуре, поэтому надо смотреть не номинальное время срабатывания у вас на столе (оно же «установленное перемычкой»), а минимально возможное в температурном диапазоне эксплуатации устройства. Оно запросто может отличаться на десятки процентов.
                                0
                                В ATtiny13 4-е поколение встроенного генератора, имеющее неплохую внутреннюю калибровку. Как правила, настройка калибровочных значений идет уже с завода. При необходимости можно произвести самостоятельную температурную калибровку с достижением 1% точности, что для моих задач более чем достаточно
                                  +2
                                  При необходимости можно произвести самостоятельную температурную калибровку с достижением 1% точности


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

                                easyelectronics.ru/podklyuchenie-mikrokontrollera-likbez.html
                                  –1
                                  На ресет, как и на другие входы, есть встроенная подияжка
                                  0.1мкф по питанию — в даташите такого нету. А если учесть, что высокочастотной нагрузки нету, то в принципе можно и обойтись
                                    –1
                                    Почему бы не обратиться по подтяжке к даташиту на 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.


                                    0
                                    Только я что-то не понял плюсов подобного принципа работы вачдога — строго периодичное изменение сигнала. Вроде вачдоги всегда строятся на превышении времени между сбросами, а не на строгой синхронности с отслеживаемым девайсом, которому нельзя ни шага влево-вправо от заданного периода сброса.
                                      0
                                      image
                                      Мой вариант watchdog на ATTINY13 для ESP8266 в формате шилда Wemos D1. Питание подается через разъем USB, программирование задержек осуществляется перемычками на оборотной стороне. В случае зависания ESP8266 ей отключается питание на выбранный интервал времени.
                                        +2
                                        Я на схеме не увидел ни одного конденсатора, шунтирующего питание. Сомневаюсь что этот «костыль для плохих разработчиков» будет надёжнее самого защищаемого устройства.
                                          0
                                          Повесить МК можно не только по питанию, но и по… выходу, а они здесь выведены напрямую, так что да — вы правы.
                                          +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.
                                            0

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

                                              0
                                              Подскажите литературу про обязательную внешнюю подтяжку?
                                              В даташите на 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
                                                Это правило хорошего тона, основанное на практике. Если вы можете абсолютно гарантировать что все ваши устройства никогда не попадут в условия наводок, или возможный слёт прошивки для вас неважен — необязательно подтягивать.
                                                  0
                                                  Прямо вот с языка сняли про правило хорошего тона.
                                                  В даташите на ATtiny13 сазано, что подтяжка на входе Reset имеет сопротивление 30..80 кОм. Да, «на столе» и в «тепличных условиях» этого достаточно, но в более жёстких условиях сопротивление хочется иметь поменьше, чтобы амплитуда импульсов напряжения, наводимых помехами на входы МК, была поменьше, потому и нужен внешний резистор. Я бы его вообще намертво к питанию приколотил, но через Reset ещё debugWire ходит.
                                                  Ну, а ёмкость 0.1 мкФ рядом с выводами питания — просто классика жанра. С одной стороны, улучшает стабильность работы самой микросхемы (контур, через который текут высокочастотные токи помех, замыкается через ёмкость, его площадь и индуктивность снижаются, уменьшая вероятность возникновения бросков напряжения, способных завесить микросхему; мы же стабильно работающую схему проектируем), с другой стороны, защищает цепи питания от внешнего мира (опять же, токи помех замыкаются через ёмкость).
                                                    +1
                                                    Вообще говоря, как минимум в STM32 и EFM32 на ресете есть фильтр, который гарантированно отсекает помехи длительностью до 50 нс, в результате чего встроенной подтяжки вполне достаточно — при отсутствии длинной дорожки до ресета и электроэрозионного станка в радиусе нескольких метров.

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

                                            Only users with full accounts can post comments. Log in, please.