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

[Atmega8a][C] Problem z funkcją delay

anathor 10 Gru 2010 00:21 1731 13
REKLAMA
  • #1 8848909
    anathor
    Poziom 10  
    Witam,

    mam problem z ww. funkcją, ustawiłem fusebity na wewnętrzne 8Mhz i tak samo zadeklarowałem to w programie:
    
    #include <avr/io.h>
    #include <inttypes.h>
    
    
    #define F_CPU 8000000UL
    
    #include <util/delay.h>
    
    
    int main()
    {
    	DDRB = 0xFF;
    	int i;
    	while(1)
    	{
    		for(i=0;i<8;i++)
    		{
    			//zapalenie tylko i-tej diody (od lewej)
    			PORTB = ~_BV(i);
    			//co sekunde
    			_delay_ms(1000);	
    		}
            }
            return 0;
    }
    


    Jednak wtedy następuje małe przekłamanie - dioda nie zapala się co sekundę, tylko co 1/4 sekundy, jeżeli ustawię delay na 4000 ms, to wtedy zapala się co sekundę, lub kiedy zmienię F_CPU na 32Mhz. Z czego może wynikać ten błąd?
  • REKLAMA
  • REKLAMA
  • #3 8848930
    anathor
    Poziom 10  
    Tak, doczytałem to, ale nawet jeśli zrobię sekwencyjnie 4 delaye po 250 ms, to i tak wychodzi dokładnie to samo.
  • #4 8848948
    maniex
    Poziom 10  
    anathor napisał:
    lub kiedy zmienię F_CPU na 32Mhz. Z czego może wynikać ten błąd?


    chodzi Ci, że zmienisz na 2MHz, tak?
  • #5 8848951
    anathor
    Poziom 10  
    Nie, jak zmienię na 2MHz to przeskok jest jeszcze szybszy, przy zmianie na _32MHz_ osiągam zmianę zapania diod co sekundę.


    E. Dzieje się tak niezależnie od ustawień fusebitów, na każdej ustawionej częstotliwości, przy zdeklarowanym poprawnie F_CPU czas nie jest odmierzany prawidłowo.
  • #6 8848971
    Mexit
    Poziom 25  
    F_CPU ustawiasz tak jaki masz kwarc, a nie jak Ci się podoba!
  • #7 8848976
    anathor
    Poziom 10  
    Mexit, czytaj to co piszę, zmiana F_CPU była czysto teoretyczno-akademicka w celu zauważenia różnicy, jeżeli ustawiam F_CPU tak jak mam ustawiony kwarc, to czas jest odmierzany nieprawidłowo.
  • REKLAMA
  • #9 8849066
    anathor
    Poziom 10  
    Zrozumiałem to co napisałeś, poczytałem sobie, ale i to nie działało, problem leżał zupełnie gdzie indziej:

    Link

    Cytat:
    Bug #30363:_delay_xx() functions in <util/delay.h> are broken (AVR-libc)


    Do zamknięcia.
  • REKLAMA
  • #10 8849723
    mirekk36
    Poziom 42  
    Mexit napisał:
    The maximal possible delay is 262.14 ms / F_CPU in MHz.
    http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html

    Powinieneś zrobić pętlę z opóźnieniem


    Sam kolego sobie poczytaj bo opowiadasz i mnożysz takie nieprawdziwe opowieści.

    Spokojnie można używać _delay_ms(1000) a nawet i _delay_ms(5000) jeśli komuś potrzeba.

    Doczytaj dokładniej co oznacza to ograniczenie i z czym się wiąże bo ręce już opadają. Było to wiele razy tłumaczone na elektrodzie , a tu masz - znowu kolejne PLOTKI i banialuki.



    a to że koledzie zamiast trwać to 1s to trwa 1/4s może być spowodowane np złym ustawieniem fusebitów w procku albo oczywiście jak już było wspomniane błędnym ustawieniem F_CPU w stosunku do użytego taktowania.

    I namawiam autora żeby nie robił sobie żadnych własnych "lepszych" pętli opóźniająych niże wbudowane _delay_ms() czy _delay_us()
  • #11 8849736
    anathor
    Poziom 10  
    mirekk36 napisał:
    Mexit napisał:
    The maximal possible delay is 262.14 ms / F_CPU in MHz.
    http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html

    Powinieneś zrobić pętlę z opóźnieniem


    Sam kolego sobie poczytaj bo opowiadasz i mnożysz takie nieprawdziwe opowieści.

    Spokojnie można używać _delay_ms(1000) a nawet i _delay_ms(5000) jeśli komuś potrzeba.

    Doczytaj dokładniej co oznacza to ograniczenie i z czym się wiąże bo ręce już opadają. Było to wiele razy tłumaczone na elektrodzie , a tu masz - znowu kolejne PLOTKI i banialuki.



    a to że koledzie zamiast trwać to 1s to trwa 1/4s może być spowodowane np złym ustawieniem fusebitów w procku

    I namawiam autora żeby nie robił sobie żadnych własnych "lepszych" pętli opóźniająych niże wbudowane _delay_ms() czy _delay_us()



    Błąd wynikał z zastosowania AVR Toolchain, który ma cytowany przeze mnie powyżej bug w tej funkcji. Po zmianie na WinAVR funkcja _delay_ms(1000) prawidłowo odmierza sekundę.
  • #12 8849767
    mirekk36
    Poziom 42  
    anathor napisał:


    Błąd wynikał z zastosowania AVR Toolchain, który ma cytowany przeze mnie powyżej bug w tej funkcji. Po zmianie na WinAVR funkcja _delay_ms(1000) prawidłowo odmierza sekundę.


    Wszystko rozumiem, to też może być przyczyną jednak chciałem dobitnie zwrócić uwagę na te rozsiewane co jakiś czas plotki o tym, że _delay_ms() ma jakieś tam ograniczenia .... po prostu ludzie coś gdzieś tam usłyszą jakiś rykoszet informacji, potem to przemielą po swojemu a następnie po własnym kolejnym retuszu dalej klepią na forum.

    Chodzi mi tylko o to że nie ma żadnych przeszkód aby parametrem takich funkcji były stałe dosłowne o wartościach typu 1000, 2000, 12000 itp
  • #13 8850113
    tmf
    VIP Zasłużony dla elektroda
    Zamiast zmieniać cały toolchain wystarczy podmienić plik delay.h, albo ustawić symbol zmieniający sposób definiowania delay. Szczegóły masz w samym pliku delay.h.
REKLAMA