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

[Atmega162][C] funckja delay przerywa wykonywanie programu

maciej_blocho 18 Mar 2011 15:29 1777 14
  • #1 9291738
    maciej_blocho
    Poziom 2  
    Witam,

    mam problem z atmega162 - każde wywołanie funkcji _delay_ms lub _delay_us przerywa wykonywanie programu. Fusebity ustawione na: efuse - FF, hfuse: C9, lfuse: EF, korzystam z usbasp, kwarc 12M

    Taki kod działa - na wyjściu jest 0:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Po odkomentowaniu linijki z f-cja delay na wyjściu pozostaje logiczna jedynka. Na Atmedze16 w tej samej konfiguracji(ten sam programator, kwarc i fuse'y) nie ma zadnych problemów. Co może powodować takie zachowanie?

    pozdrawiam
    Maciej
  • #2 9291764
    wdogli
    Poziom 18  
    Spróbuj tak:


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #3 9291799
    maciej_blocho
    Poziom 2  
    Spróbowałem, nie pomogło. Po instrukcji delay program przestaje wykonywac dalsze instrukcje.
  • #4 9292016
    Marczeli_P
    Poziom 20  
    To wstaw tam większe opóźnienia rzędu 1s to będzie efekt widoczny naocznie. Przy ms-kundach przemiata tak szybko że miernikiem mierząc będziesz miał 1
  • Pomocny post
    #5 9293480
    Andrzej__S
    Poziom 28  
    Proponowałbym spróbować:
    #define F_CPU 12000000UL przesunąć przed #include <util/delay.h>, bo opóźnienia będą nieprawidłowe. Kompilator nie wyświetlał żadnych ostrzeżeń?
    Wyłączyć fusebit WDTON (hfuse=0xD9 zamiast 0xC9), bo on włącza watchdoga, a nigdzie go nie resetujesz. Przy ustawionych domyślnie bitach WDP2:WDP1:WDP0 na 0 mikrokontroler będzie się resetował co 16ms.
  • #6 9293495
    tadzik85
    Poziom 38  
    Panowie skończcie z tym definiowaniem F_CPU w plikach *.c

    to robi się w makefilu


    A później wam coś za wolno działa nie działa.
  • #7 9294029
    maciej_blocho
    Poziom 2  
    @Andrzej_s: Dzięki za pomoc - chodziło o watchdoga. Kompilator wyświetlał ostrzeżenia związane z tym ze to była redefinicja F_CPU - dopisałem to tylko po to, żeby była jasność, że jest zdefiniowane(w makefile'u rzecz jasna). Natomiast drążąc dalej temat jak wyjaśnić to, że na atmedze16 przy identycznej kofiguracji fuse'ów wszystko działało elegancko?
  • Pomocny post
    #8 9294074
    mirekk36
    Poziom 42  
    maciej_blocho napisał:
    Natomiast drążąc dalej temat jak wyjaśnić to, że na atmedze16 przy identycznej kofiguracji fuse'ów wszystko działało elegancko?


    Na procku ATmega162 ale podobnie na ATmega88 itp ... też działa elegancko. Tyle, że trzeba doczytać w nocie i pamiętać, że domyślnie Watchdog jest włączony. I wcale nie trzeba go zaraz fusami wyłączać bo po co? Może się często przydać a nawet przydaje w trakcie działania najróżniejszych programów.

    Wyłączyć go po prostu trzeba programowo. Albo jak najszybciej na początku main() o czym ludzie zapominają a najlepiej w sekcji init

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


    wystarczy to dodać na początku programu przed main() w takich prockach i masz problem z głowy raz - dobrze - i na pewno ;) .... a w swoim programie możesz z niego korzystać spokojnie - włączać i wyłączać kiedy chcesz. Ważne, że po resecie będzie automatycznie wyłączany w odpowiednim momencie.
  • Pomocny post
    #9 9294809
    Andrzej__S
    Poziom 28  
    mirekk36 napisał:

    I wcale nie trzeba go zaraz fusami wyłączać bo po co?
    ...
    Wyłączyć go po prostu trzeba programowo.


    W takim razie nie bardzo rozumiem treści tabelki ze strony 53 datasheet. Konkretnie chodzi mi o kolumnę zatytułowaną "How to Disable the WDT", w której - dla WDTON programmed - jest napisane "Always enabled".

    No i później jeszcze na stronie 56:
    Cytat:

    Safety Level 2 In this mode, the Watchdog Timer is always enabled, and the WDE bit will always read as one. A timed sequence is needed when changing the Watchdog Time-out period.

    Ja to rozumiem tak, że nie da się wyłączyć watchdoga przy WDTON programmed. Można jedynie zmienić time-out.
    Nie mam niestety możliwości w tej chwili tego przetestować, ale ten dokument zdaje się potwierdzać moje przypuszczenia. Mógłby ktoś rozwiać wątpliwości?

    maciej_blocho napisał:

    Natomiast drążąc dalej temat jak wyjaśnić to, że na atmedze16 przy identycznej kofiguracji fuse'ów wszystko działało elegancko?

    ATmega16 nie ma fuse bitu WDTON. W tym miejscu jest fuse bit o nazwie CKOPT konfigurujący tryb pracy oscylatora.
  • #10 9295811
    maciej_blocho
    Poziom 2  
    Wszystko jasne, dzięki:)
  • #11 9295860
    mirekk36
    Poziom 42  
    Andrzej__S napisał:
    [Nie mam niestety możliwości w tej chwili tego przetestować, ale ten dokument zdaje się potwierdzać moje przypuszczenia.

    No niestety twoje przypuszczenia nie do końca idą w dobrą stronę, i najlepiej będzie jak znajdziesz chwilkę czasu na przetestowanie tego. To co podałem to nie jest jakiś mój wymysł na gorąco napisany, tylko wykorzystuję to na co dzień w tego typu prockach.


    Andrzej__S napisał:
    Mógłby ktoś rozwiać wątpliwości?.


    Przeczytaj dokładnie sobie rozdział "Watchdog System Reset" z PDF'a np od ATmega88/168/328

    to rozwieją się twoje wątpliwości do końca i zobaczysz o co tu chodzi.
  • #12 9296993
    Andrzej__S
    Poziom 28  
    mirekk36 napisał:

    Przeczytaj dokładnie sobie rozdział "Watchdog System Reset" z PDF'a np od ATmega88/168/328

    No tak, ja to czytałem.
    Cytat:

    The Watchdog always on (WDTON) fuse, if programmed, will force the Watchdog Timer to System Reset mode. With the fuse programmed the System Reset mode bit (WDE) and Interrupt mode bit (WDIE) are locked to 1 and 0 respectively. To further ensure program security, alterations to the Watchdog set-up must follow timed sequences. The sequence for clearing WDE and changing time-out configuration is as follows:
    ...

    Z tego można wnioskować, że WDE można wyłączyć nawet przy zaprogramowanym WDTON. Jednak tu jest mowa o ATmega162, a nie ATmega168. Nota katalogowa od ATmega162 nieco inaczej opisuje watchdoga. Szczególnie mam tu na myśli "Table 22. WDT Configuration as a Function of the Fuse Settings of M161C and WDTON" na stronie 53, gdzie jest podane:
    M161C - Programmed/Unprogrammed
    WDTON - Programmed
    Safety Level - 2
    WDT Initial State - Enabled
    How to Disable the WDT - Always enabled
    How to Change Time-out - Timed sequence


    No i później:
    Cytat:

    Safety Level 2 In this mode, the Watchdog Timer is always enabled, and the WDE bit will always read as one. A timed sequence is needed when changing the Watchdog Time-out period.


    mirekk36 napisał:

    To co podałem to nie jest jakiś mój wymysł na gorąco napisany, tylko wykorzystuję to na co dzień w tego typu prockach.

    Ja tego nie kwestionuję. Byłem tylko ciekawy, czy jesteś pewien, że w ATmega162 działa to tak samo jak np. w ATmega168. Bo dziwi mnie trochę to, co pisze Atmel (jak wyżej).
    Ja tymczasem nie mam możliwości tego przetestować, bo nie mam pod ręką akurat takiego procesora, i nie wiem kiedy będę miał. Nie będę raczej kupował go specjalnie do testu watchdoga :)
  • #13 9297004
    mirekk36
    Poziom 42  
    No tak , przepraszam zasugerowałem się, że to to samo co w ATmega88 .... zaraz zajrzę do noty m162 - bo też przyznam, że akurat tej nie używałem ...

    Dodano po 2 [minuty]:

    ........ nie no zaraz, nie mam wprawdzie teraz czasu żeby to analizować - ale na pierwszy rzut oka wygląda to tak samo jak w m88. Nawet masz w tejże nocie przykład w asm i C jak wyłączyć Watchdoga. Tyle że ja pokazałem jeszcze jak to wstawić w sekcję INIT
  • #14 9297109
    dondu
    Moderator na urlopie...
    tadzik85 napisał:
    Panowie skończcie z tym definiowaniem F_CPU w plikach *.c
    to robi się w makefilu

    Pójdźmy dalej :) :
    Skończcie używać WinAVR i Programmers Notepad a zacznijcie AVR Studio i definiujcie w opcjach zapominając, że Makefile istnieje (po co się męczyć).
  • #15 9299399
    Andrzej__S
    Poziom 28  
    mirekk36 napisał:

    Nawet masz w tejże nocie przykład w asm i C jak wyłączyć Watchdoga.


    Dotyczy to jednak chyba "Safety level 1". W trybie "Safety level 0" można zmieniać wartość bitu WDE w dowolnej chwili bez konieczności użycia "timed sequence".
    W opisie bitu WDE z rejestru WDTCR można też znaleźć taki zapis:
    Cytat:

    In safety level 2, it is not possible to disable the Watchdog Timer, even with the algorithm described above. See “Timed Sequences for Changing the Configuration of the Watchdog Timer” on page 56.

    a "safety level 2" dotyczy sytuacji, w której fuse bit WDTON jest zaprogramowany, niezależnie od ustawień fuse bitu M161C.

    Przepraszam za moją dociekliwość, ale być może w ten sposób uda się za jakiś czas uniknąć tematu "Dlaczego nie mogę wyłączyć watchdoga w ATmega162?" :)
REKLAMA