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

Częstotliwość kwarcu a funkcja _delay_ms( );

beznadziejny_elektronik 21 Wrz 2010 23:10 2887 12
  • #1 8536647
    beznadziejny_elektronik
    Poziom 10  
    Cze! Mam takie pytanko:

    Mam programik na atmega16, który oparty jest na funkcji _delay_ms( ); Chce dodać do układu zewnętrzny kwarc 12MHz. Ustawiam więc sobie fusebity: CKSEL3..1 = "111" oraz CKOPT= "0". Potem w programie zmieniam linijkę:
    #define F_CPU 1000000L na #define F_CPU 12000000L.

    Ale gdy odpalę program po tych zmianach, to układ zachowuje się inaczej, tak jakby ta funkcja _delay_ms( ); działała inaczej gdy jest 1MHz a inaczej gdy jest 12MHz.

    Oszukałem się trochu i nigdzie nie mogę znaleźć odpowiedzi na to pytanie. Gdzieś coś robię źle.

    Pozdrawiam i z góry dziękuję za pomoc!
  • #2 8536724
    janbernat
    Poziom 38  
    Project->configuration options->frequency
  • #3 8536809
    riddyk
    Poziom 20  
    Zmień jeszcze w makefile.

    #define F_CPU 1000000L na #define F_CPU 12000000L

    W dodatku nie napisałeś z jakiego środowiska i kompilatora używasz.

    Dłuższe czasy możesz sprawdzić na karcie dźwiękowej ustawiając pin na 0->1->0. W celu weryfikacji.

    Dodatkowo funkcja delay nie jest precyzyjna i może mieć kilka % błędu.

    Dalej sprawdź czy kwarc jest uruchomiony z poprawnymi dla niego fuse bitami.
  • #4 8537917
    beznadziejny_elektronik
    Poziom 10  
    Okay. Wielkie dzięki za odpowiedzi. Zrobiłem jeszcze tę zmianę w MFile jak pisaliście ( dokładnie tam było:

    #     Typical values are:
    #         F_CPU =  1000000
    #         F_CPU =  1843200
    #         F_CPU =  2000000
    #         F_CPU =  3686400
    #         F_CPU =  4000000
    #         F_CPU =  7372800
    #         F_CPU =  8000000
    #         F_CPU = 11059200
    #         F_CPU = 14745600
    #         F_CPU = 16000000
    #         F_CPU = 18432000
    #         F_CPU = 20000000
    F_CPU = 8000000



    i ja zmieniłem tę ostatnią linijkę na F_CPU = 12000000). Teraz działa. Tylko, że teraz te serwa, które mam podłączone do tej elektroniki, działają jakby na innych zakresach i pewnie wynika to z tej niedokładności funkcji _delay_ms( ); Ale wystarczy po po prostu zrobić jeszcze raz kalibracje będzie okay.

    Jeszcze takie pytanko. Ja zmieniam tam wartości w tej funkcji _delay_ms( ); o 0,02ms czyli o 20us. I czy to nie za mało? Bo w sumie serwa działają w sumie okay. I myślałem żeby użyć funkcji _delay_us( ); ale nie chce mi się z tym kombinować skoro wychodzi mi, że przy 12MHz najwyżej mogę ustawić opóźnienie na 768us / F_CPU(w MHz) co daje mi jakieś chyba 68us. Więc musiałbym troszku pokombinować i nie wiem czy warto się z tym bawić.

    Pozdrawiam i jeszcze raz wielkie dzięki za pomoc!

    [/code]
  • #5 8538085
    mirekk36
    Poziom 42  
    Jeśli piszesz program w AVR Studio to zrób to co plecił janbernat. A jeśli w notatniku to oczywiście wtedy sam dbaj o makefile.

    beznadziejny_elektronik napisał:
    Jeszcze takie pytanko. Ja zmieniam tam wartości w tej funkcji _delay_ms( ); o 0,02ms czyli o 20us. I czy to nie za mało? Bo w sumie serwa działają w sumie okay. I myślałem żeby użyć funkcji _delay_us( ); ale nie chce mi się z tym kombinować skoro wychodzi mi, że przy 12MHz najwyżej mogę ustawić opóźnienie na 768us / F_CPU(w MHz) co daje mi jakieś chyba 68us. Więc musiałbym troszku pokombinować i nie wiem czy warto się z tym bawić.


    I nie opowiadaj więcej albo nie słuchaj takich mega bzdur na temat funkcji _delayms() czy _delau_us(). Skąd ty wytrzaskujesz takie pomysły że maksymalne opóźnienie możesz ustawić na 768us !!! ??? !!! .... a tak niedawno był cały wątek w którym m.in ja obalałem takie durne krążace po niecie opinie o niedokładnościach funckji _delay_xx() o maksymalnych zakresach itp. Weź sobie to poszukaj.... i wiecej nie wracaj do takich dziwnych opinii.

    Skoro sam tworzysz makefile to szukaj jeszcze tam błędu z tą definicją taktowania. Albo weź jakieś porządne środowisko jak AVR Studio czy Eclipse, które za ciebie ładnie i co najważniejsze poprawnie wygeneruje makefile.

    No a to to już jak rozumiem czysta literówka:

    beznadziejny_elektronik napisał:
    0,02ms czyli o 20us.


    bo na końcu nie może być 20us a co najwyżej 20ms.

    Pokaż może schemat tego co wymodziłeś, czy jakąś fotkę jak to wszystko złożyłeś to może uda się coś bardziej konkretnego podpowiedzieć
  • #6 8538241
    janbernat
    Poziom 38  
    _delay() działa bardzo dokładnie.
    Co nie zmienia faktu że używanie tej funkcji przez początkujących powinno być dozwolone tylko pod opieką osób dorosłych z odpowiednimi uprawnieniami.
  • #7 8538269
    mirekk36
    Poziom 42  
    janbernat ---> eeej no nie jest tak źle, ja bym powiedział inaczej. Że funkcje _delay są jak alkohol, każdy może go pić (ich używać) byleby z umiarem, nie zachłystywać się i nie ciągnąć "z gwinta" ;)
  • #8 8538795
    gaskoin
    Poziom 38  
    Jeszcze jedna ważna rzecz - aby funkcja _delay_xx poprawnie działała, należy włączyć optymalizację.
  • #9 8539051
    Andrzej__S
    Poziom 28  
    gaskoin napisał:

    Jeszcze jedna ważna rzecz - aby funkcja _delay_xx poprawnie działała, należy włączyć optymalizację.

    ...i nie korzystać z przerwań.
  • #10 8539319
    beznadziejny_elektronik
    Poziom 10  
    No więc tak:

    Maksymalne opóźnienie: 768us / F_CPU(w MHz) wziąłem stąd: http://mikrokontroler.info/opoznienia-i-ich-dokladnosc-delayh/

    Korzystam z WinAVR20090313. Pytanie gdzie (lub w jaki sposób) włącza się tą optymalizację?

    Dziękuję wszystkim za pomoc i porady. Układ działa tak, jak ma działać. Pozdrawiam!
  • #12 8539440
    mirekk36
    Poziom 42  
    beznadziejny_elektronik -> tak jak pisze janbernat czerp informacje ze źródeł a nie z powielaczy w internecie wprowadzających swoje błędy, chociaż powiem ci szczerze , że na tej stronce też jest to poprawnie opisane więc nie wiem skąd takie wnioski wyciągnąłeś

    Cytat:

    void _delay_us(double _us)
    Funkcja powoduje opóźnienie o _us mikrosekund. Maksymalne generowane opóźnienie wynosi 768us / F_CPU(w MHz). Jeśli podana wartość przekracza dopuszczalne maksimum, automatycznie wywoływana jest funkcja _delay_ms().
    void _delay_ms(double _ms)
    Funkcja powoduje opóźnienie o _ms milisekund. Maksymalne generowane opóźnienie wynosi 262.14ms / F_CPU(w MHz). Jeśli podana wartość przekracza dopuszczalne maksimum, funkcja działa ze zmniejszoną rozdzielczością (0.1ms) generując opóźnienia do 6.5535s niezależnie od częstotliwości pracy mikrokontrolera.


    masz wyraźnie napisane że można z powodzniem stosować większe wartości argumentów dla funkcji tyle, że zmniejszy się nieco dokładność, co jest i tak w ogóle nieznaczące gdy potrzebujesz zrobić sobie opóźnienie trwające wieczność czyli np 1s albo więcej. _delay_ms(1000); .... toż to zawsze dobrze i ładnie działa - a jak ktoś chciałby do mega dokładnego odmierzania tak długich czasów stosować _delay_xx to proponuję poczytać o timerach ;)

    A na koniec dodam, po takie informacje nawet do netu nie musisz sięgać, wystarczy że zajrzysz do opisu funkcji w pliku nagłówkowym delay.h - i masz napisane jota w jotę to samo - hmm no tyle że po angielsku. Tyle że trzeba się postarać żeby tego nie zrozumieć nawet przy słabej angielszczyćnie.
  • #13 8542084
    beznadziejny_elektronik
    Poziom 10  
    mirekk36, Mireczku... dzięki za odpowiedzi i jeszcze jedno... wyluzuj chłopie. Nie denerwuj się, napij się piwka.

    Dziękuję wszystkim za pomoc! (zwłaszcza Mirkowi) Wszystko działa już jak należy. Pozdrawiam!
REKLAMA