Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Watchdog ATmega328 i uzycie cli();

Jakub17 04 Mar 2018 10:21 411 9
  • #1 04 Mar 2018 10:21
    Jakub17
    Poziom 6  

    Witam.

    W internecie w różnego rodzaju źródłach informacji na temat watchdoga popularny jest jeden z przykładów:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Moje pytanie: Po co wyłączać przerwania po uruchomieniu watchdoga? Nie rozumiem tego działania. Probowałem zastosować powyższy kod w swoim przykładowym programie. Niestety napis wyświetla się tylko raz, co świadczy o tym
    że procesor nie jest resetowany.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0 9
  • #2 04 Mar 2018 10:24
    excray
    Poziom 39  

    Chyba ma to sens tylko jako element kodu bootloadera i ma służyć do przeprowadzenia resetu procesora. Autor chce mieć pewność, że WDT nie zostanie przypadkowo skasowany bądź wyłączony w przerwaniu które mogłoby wystąpić, dlatego na wszelki wypadek blokuje przerwania.

    0
  • #3 04 Mar 2018 10:29
    Jakub17
    Poziom 6  

    A gdy przerwanie załóżmy wystąpi po uruchomieniu watchdoga, ale przed instrukcją cli(). Wtedy w przerwaniu zostanie wyłączony watchdog i cały program zatrzyma się na while(1)? To w takim razie można używać przerwań do wyłączania watchdoga?

    0
  • #4 04 Mar 2018 10:35
    excray
    Poziom 39  

    Jakub17 napisał:
    A gdy przerwanie załóżmy wystąpi po uruchomieniu watchdoga, ale przed instrukcją cli(). Wtedy w przerwaniu zostanie wyłączony watchdog i cały program zatrzyma się na while(1)?

    Tak. Należałoby przenieść cli() przed kod uruchomienia watchdoga aby zapobiec takiej ewentulności.
    Jakub17 napisał:
    To w takim razie można używać przerwań do wyłączania watchdoga?

    Wszystko wedle rozsądku programisty. Samo przerwanie nie dezaktywuje WDT. Gdzieś w kodzie obsługi przerwania musiałby być taki kod umieszczony. Generalnie programista musi zdawać sobie sprawę z tego co i gdzie może się wydarzyć.

    0
  • #5 04 Mar 2018 10:51
    Jakub17
    Poziom 6  

    A mógłbyś się odnieść jeszcze do zamieszczonego programu? Jest prosty i wydaje się poprawnie napisany (no oprócz tego cli() o który powiedziałeś post wyżej, ale nie używam w tym kodzie przerwań) a mimo to napis "Uruchomienie watchdoga" nie wyświetla się co 1 s. Następuje tylko jedno wyświetlenie przy starcie programu a później nic...
    W ogóle mam jakieś problemy z przeprogramowaniem flash gdy w kodzie pojawiają się instrukcje watchdoga. Programuje uC przez Atmel Studio 7. Gdy zapisuje plik elf do pamięci pojawia się błąd (wartości adresów się zmieniają)

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Gdy nie ma instrukcji z biblioteki wdt.h to wszystko działa ok.

    0
  • #6 04 Mar 2018 11:06
    excray
    Poziom 39  

    Musisz pamiętać o tym, że raz uruchomiony watchdog będzie działać dalej nawet po resecie. Sprawdź w DSie które bity rejestru WDTCSR zostaną skasowane po resecie a które nie i wyciągnij wnioski.

    0
  • #7 04 Mar 2018 11:16
    Jakub17
    Poziom 6  

    W dokumentacji pojawia się dla mnie mała niejednoznaczność

    str. 77 DS ATmega328

    Konfigurowanie ustawień Watchdoga

    1. In the same operation, write a logic one to the Watchdog change enable bit (WDCE) and Watchdog
    System Reset Enable (WDE) in Watchdog Timer Control Register (WDTCSR.WDCE and
    WDTCSR.WDE). A logic one must be written to WDTCSR.WDE regardless of the previous value of
    the WDTCSR.WDE.
    2. Within the next four clock cycles, write the WDTCSR.WDE and Watchdog prescaler bits group
    (WDTCSR.WDP) as desired, but with the WDTCSR.WDCE cleared. This must be done in one
    operation.


    Ad 2. Czyli w ciągu jednej instrukcji muszę wzerować bit WDCE i dokonać stosownych ustawień Watchdoga np. tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod



    A teraz przenoszę się na str. 80

    Bit 4 – WDCE: Watchdog Change Enable
    This bit is used in timed sequences for changing WDE and prescaler bits. To clear the WDE bit, and/or
    change the prescaler bits, WDCE must be set. Once written to '1', hardware will clear WDCE after four
    clock cycles.


    Tu z kolei napisane jest, że przy konfigurowaniu watchdoga tak jak w kodzie zamieszczonym powyżej, bit WDCE zostanie wykasowany w ciągu 4 cykli zegara.

    To w końcu jest konieczne ręczne wykasowanie tego bitu przy konfiguracji Watchdoga czy pozostawić go w spokoju aby został wykasowany po 4 cyklach? Tylko czy wtedy ustawienia watchdoga się zapiszą... Niestety nie mogę tego sprawdzić, bo czy tak czy tak to watchdoga nadal nie działa mi poprawnie.

    0
  • #8 04 Mar 2018 11:24
    excray
    Poziom 39  

    Wszystko słusznie ale czemu tak przywiązałeś się do tego bitu WDCE który jest używany tylko jako zabezpieczenie przed przypadkową modyfikacją rejestru WDTCSR. Zwróć uwagę na WDE - jego opis oraz parametr "Initial value" w tabelce. Ten bit nie jest domyślnie kasowany przy resecie a to oznacza, że po resecie watchdog dalej działa ale już z czasem time-out 20ms. Dlatego jako pierwszą czynność po uruchomieniu jaką musisz wykonać jest:
    - skasowanie flagi WDRF w MCUSR
    - wyłączenie watchdoga.

    0
  • #9 04 Mar 2018 11:34
    Jakub17
    Poziom 6  

    Zastosowałem Twoje wskazówki ale jest jedno ALE. Oto poprawiony kod:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Wszystko opisałem, co każda linijka robi. Problem jest nadal z biblioteką wdt.h. Nie mogę zaprogramować flash gdy tylko pojawi się w kodzie jakakolwiek funkcja z biblioteki wdt.h (występuje błąd przy weryfikacji flash taki jak zamieściłem kilka postów powyżej, ale z innymi adresami). Jak widzisz w moim kodzie linijka z wdt_reset() jest zakomentowana, wtedy pamięć flash się programuje. No ale prescaler nie jest wtedy resetowany... Wiesz w czym może być problem?

    0
  • #10 04 Mar 2018 22:02
    ghost2000
    Poziom 17  

    Widzę, że w ".init3" włączasz WDT. Jak chcesz aby zawsze pracował a nie używasz przerwań od WDT, zrób to bitami konfiguracyjnymi.

    0