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

[Atmega 16][C/Eclipse]Opóźnienie 1us

sevotharte 03 Maj 2011 17:20 1637 8
REKLAMA
  • #1 9465772
    sevotharte
    Poziom 10  
    Witam!

    Mam taki problem. potrzebuję zrobić funkcję opóźniającą 1us. To jest łatwe do zrobienia jak mam kwarc 8MHz. Ale ja bym musiał wykorzystać do tego celu 11.0592 MHz. A oto kawałek kodu:

    
    void czekaj_us(uint16_t usekundy)
    {
    	OCR1A = usekundy; 
    	TIFR |=(1<<OCF1A); //TIFR - Timer Interrupt Flag Register. 
    	Timer1_ON; //wlacz Timer1
    	while(!(TIFR&(1<<OCF1A))){}; //podczas gdy warunek nie jest spełniony 
    	Timer1_OFF; //wylacz Timer1
    }
    


    jakby to wykonać na tym kwarcu, który mam? myslalem nad preskalerem 8, ale wtedy otrzymuje około 1.449 us. Chyba, że program przyjmuje w przybliżeniu jako jeden cykl - 1us.

    Pozdrawiam
  • REKLAMA
  • #2 9465790
    misiolowaty
    Poziom 13  
    jeśli nie potrzebujesz bardzo dokładnie tej 1 us, to uzyj biblioteki util/delay.h

    tam jest funkcja

    _delay_us(1)

    gdzie 1 to czas w us, i samo ci wyliczy na podstawie zdeklarowanego na samej gorze kwarcu.
  • REKLAMA
  • #3 9479642
    y0yster
    Poziom 19  
    Możesz również zrobić to w podobny sposób jak masz na myśli.
    Wykorzystaj przerwanie od przepełnienia licznika. Wcześniej jednak musisz wyliczyć odpowiednią wartość rejestru licznika timer1. W ten sposób dobierając inny prescaler możesz uzyskać bliższy wynik do 1us.

    Co do tego co zasugerował przedmówca. Jest to najprostszy sposób dla wywołania opóźnienia. Wiążą się z nim pewne ograniczenia jak np. maksymalna wartość jaką można opóźnić wykonywanie programu (następuje wywołanie funkcji _delay_ms() jeśli wartość jest zbyt duża). Więcej na ten temat możesz przeczytać w kodzie źródłowym tych funkcji, a raczej komentarzach do niej.
  • REKLAMA
  • #4 9479823
    asembler
    Poziom 32  
    A w ogóle da się uzyskać dokładne uS na kwarcu "nierównym" Mhz?
    Bo jeżeli teoretycznie się nie da to żadne bibloiteki nie wyliczą dokładnie.
  • #5 9479856
    y0yster
    Poziom 19  
    Oczywiście, że się da jeśli chodzi o sekundy. Teoretycznie ;). Wystarczy wziąć "nierówny" kwarc.

    Jego wartość powinna dzielić się odpowiednio przez dwa podniesione do odpowiedniej potęgi. Tak aby np. przerwanie przepełnienia od licznika było wywoływane dokładnie co 1 sekundę, albo inną jej część (zdatną do przeprowadzania obliczeń).

    Dla przykładu kwarc 14,7456 MHz da Ci "dokładnie" jedną sekundę dla poniższy ustawień:
    np. licznik timer0 (8-bitowy), prescaler 256.
    Jeśli zliczysz dokładnie 225 przerwań przepełnień licznika, znaczy to, że minęła jedna sekunda.
  • REKLAMA
  • #6 9479857
    Fredy
    Poziom 27  
    Nie da się dokładnie zrobić opóźnienia 1us na tym kwarcu. Błąd będzie mikroskopijny ale będzie.
    Najłatwiej takie opóźnienie zrobić dając 11 nopów.
  • #7 9479873
    asembler
    Poziom 32  
    y0yster napisał:
    Oczywiście, że się da. Teoretycznie ;). Wystarczy wziąć "nierówny" kwarc.

    Jego wartość powinna dzielić się odpowiednio przez dwa podniesione do odpowiedniej potęgi. Tak aby np. przerwanie przepełnienia od licznika było wywoływane dokładnie co 1 sekundę, albo inną jej część (zdatną do przeprowadzania obliczeń).

    Dla przykładu kwarc 14,7456 MHz da Ci "dokładnie" jedną sekundę dla poniższy ustawień:
    np. licznik timer0 (8-bitowy), prescaler 256.
    Jeśli zliczysz dokładnie 225 przerwań przepełnień licznika, znaczy to, że minęła jedna sekunda.

    Mylisz sie tylko milion razy ale to chyba drobiask :-)
    gadamy tu o mikro sekundach a nie o sekundach.
  • #8 9479877
    y0yster
    Poziom 19  
    Fredy napisał:
    Nie da się dokładnie zrobić opóźnienia 1us na tym kwarcu. Błąd będzie mikroskopijny ale będzie.
    Najłatwiej takie opóźnienie zrobić dając 11 nopów.


    Oczywiście dla kwarcu 11.0592 MHz też to zrobisz.

    Wystarczy licznik timer0, prescaler = 64. Po zliczeniu 675 razy będziesz miał 1 sekundę. Ale ta jedna sekunda jest zależna od warunków w jakich przebywa uC itd.


    asembler napisał:

    Mylisz sie tylko milion razy ale to chyba drobiask :-)
    gadamy tu o mikro sekundach a nie o sekundach.


    Co masz na myśli z myleniem się milion razy? Dla jednej us niestety się tego nie zrobi :], ale dla jednej sekundy tak.

    Co do tych mikro sekund. To można wziąć kwarc np. 20MHz i dawać 20 nopów. Wtedy błąd zniknie :). Albo 10MHz i 10 nopów.

    Tylko po co komu odliczać równo po 1us. W jakim celu chcesz to wykorzystać?
  • #9 9479887
    asembler
    Poziom 32  
    Fredy napisał:
    Nie da się dokładnie zrobić opóźnienia 1us na tym kwarcu. Błąd będzie mikroskopijny ale będzie.
    Najłatwiej takie opóźnienie zrobić dając 11 nopów.

    Chyba nanoskopijny :-)
REKLAMA