logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Rozwiązano] Jak poprawnie skonfigurować Watchdog w ATmega644?

zbynio_k 26 Maj 2020 20:51 588 5
REKLAMA
  • #1 18720314
    zbynio_k
    Poziom 10  
    Witam,
    próbuję uruchomić Watchdag'a jak w temacie i mam problem
    reset wykonuje się pięknie a i program "wchodzi" w wektor ISR(WDT_vect), tylko, że 30 razy ....
    zapewne robię kardynalny błąd, z nieznajomości dogłębnej tematu
    poniżej kody

    main
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    funkcje watchdog'a
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    inicjacja OPRÓCZ watchdag'a (jakby ktoś pytał)
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    załączam również zrzut z terminala (to co się dzieje w obsłudze przerwania WDT)
    Jak poprawnie skonfigurować Watchdog w ATmega644?

    może ktoś wspomoże wskazaniem błędu
    pozdrawiam

    Dodano po 4 [minuty]:

    edit -
    wysyłanie na uart'a działa w buforze kołowym autorstwa Piotra Rzeszuta, biblioteka dołączona do płytki EVB firmy AndTech
    mogę pokazać, ale i tak analizator poziomów na out pinie 2, pokazuje wielokrotne wejście w obsługę przerwania
  • REKLAMA
  • #2 18720831
    dasej
    Poziom 32  
    Witam.

    Jak zrozumieć Twoje pytanie?

    Przerwanie WDT wykonuje się tylko 30 razy, czy się wiesza po tylu razach?
    Do czego jest Ci potrzebna obsługa WDT?

    W dobrze napisanym programie WDT raczej ma nie działać, tylko się wyzwolić jak coś nie pójdzie tak jak trzeba.
  • REKLAMA
  • #3 18721060
    zbynio_k
    Poziom 10  
    no nie doprecyzowałem, przed resetem przerwanie wykonuje się 30 razy, potem jest reset programowy > czyli jak w opisach

    Dodano po 14 [minuty]:

    edit -
    1 cykl od resetu do resetu to 30 razy wykonane przerwanie i potem reset
    wiem, że to brzmi niedorzecznie dlatego podejrzewam jakiś kardynalny błąd
    w ISR jest zmiana stanu pina i wysłanie na uarta > stąd wiem, że TO się dzieje 30 razy zanim nastąpi reset
  • REKLAMA
  • Pomocny post
    #4 18722188
    rylu
    Poziom 11  
    Witam,
    prawdopodobnie błąd jest w inicjalizacji watchdog. Wykorzystujesz do tego dwie funkcje, init_WDT() oraz init_watch_dog().
    Pierwsza init_WDT:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    w tej linijce nadpisujesz wartość w rej. WDTCSR czyli włączając watchdog ustawiasz preskaler na 0 czyli timeout jest równy 16ms. Dodatkowo zgodnie z tabelką poniżej, włączony zostaje tryb System Reset Mode
    Jak poprawnie skonfigurować Watchdog w ATmega644?

    ale już kolejna linijka
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    kolejne nadpisanie rejestru WDTCSR, w tym momencie ponieważ mieścisz się w czterech cyklach zegara ustawiasz bit WDE na 0 a bit WDIE na 1. Zgodnie z tabelką powyżej zmieniasz tryb z System Reset Mode na Interrupt Mode.
    Czyli cyklicznie co 16 ms wykonuje się obsługa przerwania od watchdog ale bez resetu mikrokontrolera. Dzieje się tak do momentu wywołania kolejnej inicjalizacji init_watch_dog.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Kolejny zapis do WDTCSR tym razem ustawienie preskalera na timeout 1s plus włączenie trybu System Reset Mode. Od tego momentu przerwanie nie wykonuje się a po 1s mikrokontroler resetuje się.
  • REKLAMA
  • #5 18733708
    zbynio_k
    Poziom 10  
    rylu napisał:

    Witam,
    prawdopodobnie błąd jest w inicjalizacji watchdog. Wykorzystujesz do tego dwie funkcje, init_WDT() oraz init_watch_dog().

    jest dokładnie tak jak kolega rylu napisał, konflikt prescalera w podwójnej inicjacji WatchDoga,
    zastosowałem init_WDT() wraz z odpowiednią inicjacją prescalera i wszytko działa

    kolego rylu, jeszcze raz dzięki, gratuluję spostrzegawczości i wiedzy
    pozdrawiam
    temat zamknięty
  • #6 18733713
    zbynio_k
    Poziom 10  
    rylu napisał:

    Witam,
    prawdopodobnie błąd jest w inicjalizacji watchdog. Wykorzystujesz do tego dwie funkcje, init_WDT() oraz init_watch_dog().

    jest dokładnie tak jak kolega rylu napisał, konflikt prescalera w podwójnej inicjacji WatchDoga,
    zastosowałem init_WDT() wraz z odpowiednią inicjacją prescalera i wszytko działa

    kolego rylu, jeszcze raz dzięki, gratuluję spostrzegawczości i wiedzy
    pozdrawiam
    temat zamknięty

    Dodano po 32 [sekundy]:

    jak wyżej
REKLAMA