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

Nieprawidłowy czas opóźnienia w funkcji _delay_ms - jak to naprawić?

ksiedzulek 20 Paź 2011 12:32 2507 9
REKLAMA
  • #1 10046340
    ksiedzulek
    Poziom 12  
    Posty: 78
    Witam,

    programik działa poprawnie (zapalające i gasnące diody) ale czas w jakim to się dzieje nie taki jaki bym chciał:/ w pierwszej pętli powinno to być około 2 sekund, a jest mniej niż sekunda:/ w czym problem?

    Cytat:

    #include<avr/io.h>
    #include<util/delay.h>


    int main()
    {
    DDRA=255;

    while(1)
    {
    int i=0;
    for (int k = PC0; k <= PC7; k++) {
    for (i = 0; i < 11; i++) { // powinno być około 2 sek.
    _delay_ms(200);
    }
    PORTA |= (1<<k);


    }

    for (int k = PC7; k >= PC0; k--) {
    for (i = 0; i < 3; i++) { // też się nie zgadza
    _delay_ms(200);
    }
    PORTA &= ~(1<<k);

    }

    }
    return 1;
    }
  • REKLAMA
  • REKLAMA
  • REKLAMA
  • #4 10046674
    sweter_007
    Poziom 14  
    Posty: 139
    Pomógł: 3
    Ocena: 15
    Po za tym używając funkcji _delay_ms(argument) oraz _delay_us(argument) należy zwracać uwagę na maksymalną wartość argumentu dla danego zegara i nie należy jej przekraczać.
    http://www.nongnu.org/avr-libc/user-manual/gr...delay.html#gad22e7a36b80e2f917324dc43a425e9d3
    _delay_ms(argument)
    The maximal possible delay is 262.14 ms / F_CPU in MHz.
    _delay_us(argument)
    The maximal possible delay is 768 us / F_CPU in MHz.
  • REKLAMA
  • #5 10046880
    janbernat
    Poziom 38  
    Posty: 3954
    Pomógł: 468
    Ocena: 51
    sweter_007-rozpowszechniasz przesądy.
    Przeczytaj dokładnie co jest napisane w tym linku który podałeś.
  • #6 10048096
    ksiedzulek
    Poziom 12  
    Posty: 78
    dzięki Panowie, okazało się (że nie wiem czemu,ale) fuse bity były ustawione na 8MHz
  • #7 10049099
    sweter_007
    Poziom 14  
    Posty: 139
    Pomógł: 3
    Ocena: 15
    W programowaniu nie chodzi o przesądy a poprawne działanie programu. Trzymanie się podanych zaleceń, będzie eliminowało przynajmniej część pytań: dlaczego cuś nie działa.
  • #8 10049139
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    sweter_007 napisał:
    W programowaniu nie chodzi o przesądy a poprawne działanie programu. Trzymanie się podanych zaleceń, będzie eliminowało przynajmniej część pytań: dlaczego cuś nie działa.


    Co najciekawsze mądrze piszesz, tylko źle to w praktyce stosujesz jeszcze.

    Janbernat napisał, że szerzysz przesądy, żeby delikatnie określić to, że niestety szerzysz (no sorki) bzdury. Ale jak tu nie napisać inaczej skoro ty zamiast doczytać to co jest napisane w linku na który się sam powołujesz, nadal z uporem twierdzisz, że masz rację.

    Ponieważ nie tylko ja osobiście ale już także wiele osób tłumaczyło na elektrodzie o co chodzi w tym temacie (delay w avr gcc) - to nie będę strzępił po raz setny języka, sam użyj szukajki i znajdź odpowiedź na ten tamat - tzn dlaczego funkcje _delay_ms oraz _delay_us nie mają żadnych ograniczeń co do maksymalnych wartości w aspekcie prawidłowego działania programu. Można bowiem najspokojniej w świecie stosować np to tak:

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


    i będzie to zupełnie prawidłowo działać.

    Zatem tak jak radził ci janbernat przeczytaj jeszcze raz albo i ze dwa razy informacje podane w linku na który się powołałeś, a jeśli będziesz miał problemy ze zrozumieniem, czy angielskim - to dopytaj jeszcze raz na elektrodzie zamiast opowiadać takie niestworzone historie.

    polecam ci szczególnie te dwa fragmenty z linku do poczytania i lepszego zrozumienia:

    Cytat:
    When the user request delay which exceed the maximum possible one, _delay_ms() provides a decreased resolution functionality. In this mode _delay_ms() will work with a resolution of 1/10 ms, providing delays up to 6.5535 seconds (independent from CPU frequency). The user will not be informed about decreased resolution.


    oraz to:

    Cytat:
    If the user requests a delay greater than the maximal possible one, _delay_us() will automatically call _delay_ms() instead. The user will not be informed about this case.


    Zamiast kończyć czytanie, albo czytanie ze zrozumieniem na tym zdaniu:

    Cytat:
    The maximal possible delay is 262.14 ms / F_CPU in MHz.


    czy na tym:

    Cytat:
    The maximal possible delay is 768 us / F_CPU in MHz.
  • #9 10049997
    sweter_007
    Poziom 14  
    Posty: 139
    Pomógł: 3
    Ocena: 15
    Eh. Gratuluje panu mirekk36 wyśmienitej znajomości języka angielskiego. Jestem oczarowany po prostu. Jednak jak to w programowaniu: "prawie robi wielką różnicę". Napisałem, że nie należy przekraczać tych wartości a nie, że nie można! Programista nie jest informowany o utracie rozdzielczości w związku z czym traci pełną kontrole nad wykonywaniem się programu. To właśnie Pan sieje zamieszanie, że można przekraczać wyznaczone wytyczne bez konsekwencji. _delay_ms(1000)!=1s. Bez warning to nie takie oczywiste...i to mi panowie chodzi.
  • #10 10051718
    mirekk36
    Poziom 42  
    Posty: 9195
    Pomógł: 964
    Ocena: 2289
    sweter_007 napisał:
    Po za tym używając funkcji _delay_ms(argument) oraz _delay_us(argument) należy zwracać uwagę na maksymalną wartość argumentu dla danego zegara i nie należy jej przekraczać.


    Dla odświeżenia pamięci, kto to napisał ?

    Można przekraczać bez żadnych dziwnych objawów dla działania programu, który i tak posługuje się tak długimi opóźnieniami. To, że tracimy rozdzielczość nie oznacza, że nagle program przestanie działać albo będzie źle działał. Co to za różnica czy przy jakimś sztucznie długim opóźnieniu _delay_ms , które nawiasem mówiąc może być i tak zakłócone przez dowolne przerwanie, nawet gdybyś pan nie przekraczał owych wspomnianych przez siebie maksymalnych wartości. Więc co to za różnica czy _delay_ms(1000) będzie trwało nawet 10ms krócej albo dłużej ? - ŻADNA różnica.

    Zatem z punktu widzenia odmierzania i posługiwania się tak długimi opóźnieniami to utrata rozdzielczości jest po prostu w ogóle nieistotna. I to z tego warto sobie zdać sprawę - zamiast doszukiwać się wyimaginowanych błędów w programie panie kolego....

    A dodać należy, że posługiwanie się opóźnieniami nawet 500us w pętli głównej programu czy też w funkcjach mija się z celem ... powinno się pisać wszystkie funkcje w sposób nieblokujący.

    Za to jeśli przy starcie programu jeszcze przed wejściem w pętlę główną i nawet po odpaleniu sei() .... zrobię sobie prostą np animację na diodach LED, wyświetlaczu LED czy tym podobne rzeczy - to jeszcze raz powtarzam - jeśli zechcę dać

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


    to mogę i każdy może to zrobić bez najmniejszych obaw.

Podsumowanie tematu

✨ Użytkownik zgłosił problem z funkcją _delay_ms, która nie realizuje oczekiwanego opóźnienia 2 sekund, a zamiast tego generuje krótsze opóźnienie. Odpowiedzi wskazują, że przyczyną może być nieprawidłowe ustawienie częstotliwości procesora w fuse bitach, co wpływa na działanie funkcji opóźnienia. Użytkownik dowiedział się, że jego procesor działa na 8 MHz, co wymaga odpowiedniego skonfigurowania kompilatora. Dodatkowo, podano informacje o maksymalnych wartościach argumentów dla funkcji _delay_ms oraz _delay_us, które nie powinny być przekraczane, aby uniknąć utraty rozdzielczości opóźnienia. Dyskusja zawiera również uwagi na temat znaczenia przestrzegania zaleceń dotyczących programowania.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA