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

[Atmega8][C] Obmierzanie czasu z dokładnością do 0.1ms

ullman 23 Cze 2010 18:05 1451 8
REKLAMA
  • #1 8223194
    ullman
    Poziom 11  
    Posty: 74
    Ocena: 3
    Witam,
    Chciałbym opóźnić załączenia urządzenia o 69800us (wartość zapisana w zmiennej)
    Jak to zrobić z dokładnością do 0.1ms? Rozwiązanie za pomocą pętli for i delay_us odpada bo wprowadzi to dodatkowe błędy związane z wykonaniem pętli for (3 takty zegara). Podzielenie wartości przez 1000 też nie wiele da bo otrzymam 69ms Proszę o rade:)
  • REKLAMA
  • #2 8223273
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2203
    Nie przesadzaj, z jakim zegarem taktujesz procesor? Jeśli nawet tylko 1MHz, to 3 takty to zaledwie 3mikros. A jak potrzebujesz super dokładność to użyj timera i wyjścia OCx. Możesz zaprogramować zmianę jego stanu z dokładnością do taktu zegara z uwzględnieniem preskalera timera.
  • #3 8223348
    ullman
    Poziom 11  
    Posty: 74
    Ocena: 3
    3 us* 69800 = 209,4ms wiec jest to znacząca różnica. Jak za pomocą timera rozumiem poprzez porównanie tego czasu z aktualną zawartością liczka timera?
  • REKLAMA
  • #4 8223423
    tadzik85
    Poziom 38  
    Posty: 3404
    Pomógł: 415
    Ocena: 16
    Jakim cudem mnożysz ten czas razy 3? a licznikiem bardzo dużo dokładniej zmierzysz ten czas. ustawiasz wartość początkowa preskaler i czekasz az się przepelni
  • #5 8223553
    ullman
    Poziom 11  
    Posty: 74
    Ocena: 3
    Mnożę ten czas razy 3 bo 3us trwa wykonie pętli for, a pętla for będzie wykonywana 69800 bo for (i=0, i<69800, i++) delay_us(1) end
  • REKLAMA
  • #6 8223554
    janbernat
    Poziom 38  
    Posty: 3954
    Pomógł: 468
    Ocena: 51
    Np. tak:
    Ustawiasz zegar na 1Mhz
    W main() ustawiasz:
    Zezwolenie na obsługę przerwań
    Zezwolenie na obsługę przerwań od Timer0 (albo Timer2)
    Prescaler na 1
    Sprawdzenie jakiejś flagi
    A w obsłudze przerwania ovf od Timer0 (albo 2):
    Do rejestru Timer0 (albo 2)
    wpisujesz 156.
    Wtedy przerwanie występuje co 0.1ms i ustawi jakąś flagę.
    Wtedy w main() decydujesz co zrobić.
  • REKLAMA
  • #7 8226696
    gaskoin
    Poziom 38  
    Posty: 4159
    Pomógł: 436
    Ocena: 102
    btw czemu się tak upierasz przy tym, aby funkcje delay wywoływać z parametrem 1, można tam wpisać dowolna liczbę typu double

    więc czemu nie

    _delay_ms(t/1000.0) ?
  • #8 8228926
    rpal
    Poziom 27  
    Posty: 1502
    Pomógł: 72
    Ocena: 49
    janbernat napisał:
    Np. tak:
    Ustawiasz zegar na 1Mhz
    W main() ustawiasz:
    Zezwolenie na obsługę przerwań
    Zezwolenie na obsługę przerwań od Timer0 (albo Timer2)
    Prescaler na 1
    Sprawdzenie jakiejś flagi
    A w obsłudze przerwania ovf od Timer0 (albo 2):
    Do rejestru Timer0 (albo 2)
    wpisujesz 156.
    Wtedy przerwanie występuje co 0.1ms i ustawi jakąś flagę.
    Wtedy w main() decydujesz co zrobić.

    nie zgodzę się z kolegą bo o czymś kolega zapomniał. Opóźnienie ma być o 69800us czyli po wykonaniu 698 razy obsługi przerwania w.w. Timera. Na moje oko zdecydowanie lepiej jest w epilogu programu zdefiniować wszystko co trzeba dla wybranego licznika, potem włączyć zezwolenie na wykonywanie przerwania co 0,1ms z ta tylko różnicą że obsługa przerwania powiększa zmienną globalną (od zera do 698) i z chwilą przekroczenia tej wartości , w obsłudze przerwania należy ustawić flagę dla głównego programu. Tego moim zdaniem zabrakło w tym algorytmie. Z kolei główny program wchodzi w pętlę do czasu ustawienia flagi. Dalej musi nastąpić wyłaczenie Timera aż do następnej okazji. Z tego co napisałeś program główny musiałby sam już zadbać aby co 0,1ms powiększać jakąś zmienna a po co skor omoże to załatwić jeszcze obsługa przerwania Timera?
  • #9 8229533
    janbernat
    Poziom 38  
    Posty: 3954
    Pomógł: 468
    Ocena: 51
    Co do inkrementowania zmiennej , ustawiania flagi po osiągnięciu zadanej wartości- pewnie że może być w przerwaniu.
    Zależy od wymagań- albo minimalizujemy czas obsługi przerwania a część decyzyjną dajemy w głównej pętli- albo nie zależy nam bardzo na czasie obsługi przerwania i całą procedurę dajemy w przerwaniu.

Podsumowanie tematu

✨ Użytkownik poszukuje sposobu na opóźnienie załączenia urządzenia o 69800us z dokładnością do 0.1ms, unikając błędów związanych z pętlą for i funkcją delay_us. Odpowiedzi sugerują wykorzystanie timerów, takich jak Timer0 lub Timer2, z odpowiednim ustawieniem preskalera i obsługą przerwań. Proponowane rozwiązania obejmują ustawienie flagi w obsłudze przerwania oraz inkrementację zmiennej globalnej, co pozwala na precyzyjne odmierzenie czasu. Dyskusja podkreśla znaczenie minimalizacji czasu obsługi przerwania oraz możliwości wykorzystania funkcji delay z parametrem typu double.
Wygenerowane przez model językowy.
REKLAMA