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

Implementacja funkcji millis() z Arduino w języku C

03 Lip 2018 23:02 2358 30
Najlepsze odpowiedzi LABEL_AI_GENERATED

Jak zaimplementować własną funkcję millis() w C, używając timera i przerwania co 1 ms?

W C zrób licznik czasu na timerze ustawionym na przerwanie co 1 ms, a w samym ISR tylko inkrementuj globalną zmienną `volatile`; odczyt tej zmiennej w kodzie głównym wykonuj atomowo, np. przez `ATOMIC_BLOCK` lub wyłączenie przerwań na czas odczytu [#17311142][#17314499] Jeśli chcesz zachowanie jak w Arduino, użyj licznika 32-bit i licz się z przepełnieniem po ok. 49,7 dniach; jeśli chcesz praktycznie „bez końca”, użyj 64-bit [#17311261][#17311529] Na AVR domyślnie ISR jest blokujące, więc `ISR_NOBLOCK` zwykle nie jest potrzebne, a do ISR nie wkładaj obsługi LCD ani opóźnień — w wątku to właśnie one powodowały błędy na wyświetlaczu [#17314499][#17316023][#17316043] Do samego odmierzania 1 ms lepiej użyć trybu CTC z przerwaniem co dokładnie 1 ms niż robić okresowe „korekty” licznika [#17311474]
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA
  • #1 17311128
    Konto nie istnieje
    Poziom 1  
  • REKLAMA
  • #2 17311142
    Konto nie istnieje
    Konto nie istnieje  
  • #3 17311242
    Konto nie istnieje
    Poziom 1  
  • #4 17311261
    Konto nie istnieje
    Konto nie istnieje  
  • #5 17311278
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • REKLAMA
  • #7 17311474
    Konto nie istnieje
    Konto nie istnieje  
  • #8 17311515
    Konto nie istnieje
    Poziom 1  
  • #9 17311529
    Konto nie istnieje
    Konto nie istnieje  
  • #10 17312171
    Konto nie istnieje
    Poziom 1  
  • #11 17312177
    Konto nie istnieje
    Konto nie istnieje  
  • #12 17313371
    grko
    Poziom 33  
    Posty: 1386
    Pomógł: 247
    Ocena: 141
    nowyARM napisał:

    PS
    lubię krótkie nazwy. Robię takie coś:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    itd.


    To jest doskonały przykład jak nie powinno się robić krótkich nazw. Użyj chociaż typedf. Poza tym są definicje w stdint, których powinno się używać bo są standardem.
  • #13 17313565
    Konto nie istnieje
    Konto nie istnieje  
  • #14 17313821
    grko
    Poziom 33  
    Posty: 1386
    Pomógł: 247
    Ocena: 141
    @nowyARM No ciekawe gdzie masz te ostrzeżenia o niejawnym rzutowaniu? Ogólnie możesz sobie używać do tworzenia nowych typów preprocesora. Tylko chciałem zaznaczyć, że to nie jest dobra praktyka i kiedyś może Cię spotkać niemiła niespodzianka.
  • #15 17313879
    Konto nie istnieje
    Konto nie istnieje  
  • #16 17313887
    Konto nie istnieje
    Konto nie istnieje  
  • #17 17313902
    JacekCz
    Poziom 42  
    Posty: 8670
    Pomógł: 760
    Ocena: 1464
    grko napisał:
    nowyARM napisał:

    PS
    lubię krótkie nazwy. Robię takie coś:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    itd.


    To jest doskonały przykład jak nie powinno się robić krótkich nazw. Użyj chociaż typedf. Poza tym są definicje w stdint, których powinno się używać bo są standardem.


    Popieram.
    Zawsze sądziłem że najgłupsze są wielonijkowe "algorytmiczne" makra, też by mi do głowy nie przyszło tak krótkie (i małymi literami)
  • #18 17313916
    Konto nie istnieje
    Konto nie istnieje  
  • #19 17313925
    grko
    Poziom 33  
    Posty: 1386
    Pomógł: 247
    Ocena: 141
    nowyARM napisał:
    JacekCz napisał:
    nie przyszło tak krótkie (i małymi literami)

    Jakieś uzasadnienie?


    Może Ty byś najpierw wyjaśnił gdzie niby masz te ostrzeżenia z typedef? Kolejna rzeczą którą mógłbyś nam wyjaśnić byłoby uzasadnienie dlaczego niby używasz tych makrodefinicji zamiast standardowych typow z stdint?
  • #20 17313932
    JacekCz
    Poziom 42  
    Posty: 8670
    Pomógł: 760
    Ocena: 1464
    nowyARM napisał:
    JacekCz napisał:
    nie przyszło tak krótkie (i małymi literami)

    Jakieś uzasadnienie?


    Konwencja panie, konwencja.
    Ja tam pod wiatr nie sikam, i makr małymi literami nie nazywam, ale żyjemy w wolnym społeczeństwie.
  • #21 17313965
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #22 17313989
    grko
    Poziom 33  
    Posty: 1386
    Pomógł: 247
    Ocena: 141
    https://gcc.gnu.org/onlinedocs/cpp/Macros.html

    Obawiam się jednak, że nie masz racji. Możesz sobie tego używać w kodzie dowoli. Nie dziw się jednak, że jak proponujesz komuś tego typu rozwiązanie to spotyka się to z krytyką. I nie czepiam się tutaj nazw. To co zaproponowałeś jest złe bo:
    1. Typ unsigned char to nie zawsze 8 bitów
    2. Typ unsigned int to niz zawsze 16 bitów (w zasadzie bardzo rzadko).
    3. Zaśmiecasz tymi definicjami przestrzeń nazw w swoim projekcie globalnie. Np nie zadeklarujesz zmiennej o nazwie u16 albo u8 bo dostaniesz błąd kompilacji. W przypadku typedefa zadeklarujesz zmienna o takiej nazwie.
    4. Po co to wszystko jak jest stdint.h. Szkoda Ci klawiatury?
  • #23 17314478
    Konto nie istnieje
    Poziom 1  
  • Pomocny post
    #24 17314499
    Konto nie istnieje
    Konto nie istnieje  
  • #25 17314995
    ex-or
    Poziom 28  
    Posty: 785
    Pomógł: 147
    Ocena: 151
    Pixelx napisał:
    Chciałbym to zrealizować prosto tą funkcję do odliczania czasu, najlepiej na zwykłym przerwaniu i timerze. Potrzebuję ją do czujnika Halla ASC712 do pomiaru prądu przemiennego.

    Wątek na forum Kardasia dotyczy właśnie tego?
    No więc Tobie nie jest potrzebne żadne millis, a tym bardziej jakieś 64 bitowe zmienne tylko odmierzanie odcinków czasowych. Nie znam tego czujnika ale szybki skan PDFa ujawnia, że czujnik zapodaje wynik pomiaru jako jakieś tam napięcie na wyjściu. W takim razie potrzebujesz prawdopodobnie odpalić ADC w trybie Free Running, wyniki odbierasz i zapisujesz do bufora/przetwarzasz w przerwaniu od ADC. Lub też wykorzystujesz któryś z timerów do odmierzania czasu i inicjowania konwersji w trybie Single Conv. Pozostaje kwestia synchronizacji konwersji z przejściem przez zero.
    Na jakim µC to ma działać?
  • #26 17315013
    Konto nie istnieje
    Konto nie istnieje  
  • #27 17315994
    Konto nie istnieje
    Poziom 1  
  • #28 17316023
    Konto nie istnieje
    Konto nie istnieje  
  • #29 17316030
    Konto nie istnieje
    Konto nie istnieje  
  • #30 17316040
    Konto nie istnieje
    Poziom 1  

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy implementacji funkcji millis() z Arduino w języku C, która zlicza czas w milisekundach. Uczestnicy forum sugerują użycie przerwań co 1 ms oraz zmiennej 64-bitowej do przechowywania czasu, aby uniknąć problemu przepełnienia. Wskazują na konieczność użycia ATOMIC_BLOCK do zapewnienia atomowego dostępu do zmiennej czasu. Pojawiają się również pytania dotyczące zastosowania funkcji millis() w kontekście pomiaru prądu oraz problemów z wyświetlaniem na LCD, które mogą być spowodowane innymi aktywnymi przerwaniami. Uczestnicy podkreślają znaczenie poprawnej konfiguracji przerwań oraz unikania wywołań funkcji LCD w przerwaniach.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA