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

[c]Atmega16 - funkcje z delay.h

mojsamspam 15 Sie 2009 11:46 2304 9
  • #1 6895349
    mojsamspam
    Poziom 11  
    Witam,

    mam problem z działaniem funkcji _delay_ms() - nie powoduje oczekiwanego opóźnienia w milisekundach - opóźnienie jest zbyt małe (około 20 krotnie mniejsze od oczekiwanego). Aby otrzymać prawidłowe opóźnienie musiałem utworzyć funkcję _delay_ms2().. kod poniżej.

    Na forum znalazłem podobny problem:
    https://www.elektroda.pl/rtvforum/topic1054215-0.html
    Zapoznałem się z:
    http://mikrokontroler.info/avr/biblioteki/opoznienia-i-ich-dokladnosc-delayh/

    Korzystam z zestawu uruchomieniowego EVB 4.3
    Z avrdude wyciągnąłem fuse bity:
    hFuse: D0
    lFuse: EF
    Lock Bit: 3F

    
    #define F_CPU 1000000
    #include <avr/io.h>
    #include <util/delay.h>
    
    _delay_ms2(double ms)
    {
    	int i;
    	for(i=0;i<ms;i++) _delay_ms(20);
    }
    
    int main(void)
    {
    DDRD  = 0x01;
    while(1)
    {
     PORTD|=0x01;
     _delay_ms(2000);
     PORTD&=~0x01;
     _delay_ms(2000);
    }
    }
    


    Pozdrawiam i dziękuję

    [c]Atmega16 - funkcje z delay.h
  • #2 6895506
    BoskiDialer
    Poziom 34  
    A może po prostu procesor idzie 20 razy szybciej niż to zadeklarowano w F_CPU?

    Sprawdź też czy zmiana wartości F_CPU z 1000000 na 1000000UL ma wpływ na makra opóźniające.
  • #3 6895533
    gothye
    Poziom 33  
    Zmien optymalizacje programu na -O0
  • #4 6895581
    mojsamspam
    Poziom 11  
    Cytat:
    Sprawdź też czy zmiana wartości F_CPU z 1000000 na 1000000UL ma wpływ na makra opóźniające.


    nic się nie zmieniło. Dioda podłączona do PORTD0 wciąż mruga zbyt szybko

    Cytat:
    Zmien optymalizacje programu na -O0


    również nic to nie dało.

    Problem jest o tyle uciążliwy, że w każdej z bibliotek, które wywołują _delay_ms() muszę zwiększać wartość opóźnienia, aby np. poprawnie zainicjalizować wyświetlacz LCD (HD44780)

    Pozdr
  • #5 6895596
    BoskiDialer
    Poziom 34  
    gothye napisał:
    Zmien optymalizacje programu na -O0

    Żeby została wkompilowana biblioteka liczb zmiennoprzecinkowych. Funkcji _delay_ms i _delay_us można używać tylko i wyłącznie przy załączonej optymalizacji.

    mojsamspam: Nie musisz. Po prostu zdefiniuj F_CPU na 20000000, tak jak byś taktował procesor zegarem 20MHz - wszystkie opóźnienia będą zajmować odpowiednio więcej cykli.
  • #6 6895770
    mojsamspam
    Poziom 11  
    @BoskiDialer, dzięki za pomoc.

    ustawienie F_CPU na 20000000 nic nie daje - efekt jest taki sam jak przy 1000000.

    Ściągnąłem najnowsze WinAVR, lecz problem nie znikł
  • #7 6897086
    m.bartczak
    Poziom 16  
    Wg. dokumentacji:

    "The maximal possible delay is 262.14 ms / F_CPU in MHz."
  • Pomocny post
    #8 6897372
    BoskiDialer
    Poziom 34  
    m.bartczak napisał:
    Wg. dokumentacji:
    "The maximal possible delay is 262.14 ms / F_CPU in MHz."


    A ja zacytuję cały fragment
    delay.h napisał:
    The maximal possible delay is 262.14 ms / F_CPU in MHz.

    When the user request delay which exceed the maximum possible one,
    _delay_ms() provides a decreased resolution functionality. In this
    ode _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.

    Tak więc nie to jest problemem.

    Aktualnie obstawiam na: nadpisanie F_CPU (ze względu na niezależność czasu oczekiwania od zmian), wrzucanie złego hex'a lub kompilowanie nie tego projektu. Już różne rzeczy widziałem.
  • Pomocny post
    #9 6898391
    m.bartczak
    Poziom 16  
    Boski ma rację - sprawdziłem w kodzie, powinno działać w miarę dobrze, ALE:

    In order for these functions to work as intended, compiler optimizations must be enabled, and the delay time must be an expression that is a known constant at compile-time.

    -- stąd propozycja wyłączenia optymalizacji nie jest najlepsza.

    Inna rzecz: zmienna F_CPU jest ustawiana wewnątrz tego okna którego screenshot ustawiłeś, zmień tam tę wartość, usuń F_CPU z kodu i zobacz jeszcze raz.
  • #10 6898677
    mojsamspam
    Poziom 11  
    Znalazłem przyczynę problemów. We właściwościach projektu miałem dodaną ścieżkę do bibliotek #include. Po usunięciu ścieżki funkcja _delay_ms() działa jak należy (przy F_CPU 16MHz). Problem znalazłem po tym jak utworzyłem nowy projekt (i zapomniałem podać ścieżki do bibliotek) i ku mojemu zaskoczeniu program mający ten sam kod działał w różny sposób :)

    Co mnie zastanawia - skąd teraz kompilator wie, gdzie znajdują się pliki nagłówkowe? - zmienna systemowa %path% nie zawiera ścieżki do folderu "C:\WinAVR-20070525\avr\include".

    Poniżej okienko, o które chodzi (po wyczyszczeniu listy program zaczął działać):
    [c]Atmega16 - funkcje z delay.h

    Pozdr
REKLAMA