Arduino Timer: baw się z czasem w swoich projektach

Regulator czasowy Arduino UNO

Jakiś czas temu opublikowaliśmy więcej informacji na temat funkcja milis() de ArduinoTeraz zagłębimy się w Zegar Arduino, aby rozpocząć korzystanie z tej funkcji, zrozum, jak ta płyta zarządza czasem z MCU, a także innymi funkcjami poza millis().

Co to jest zegar Arduino?

zegar arduino

El Zegar Arduino lub minutnik, to funkcja realizowana sprzętowo (w mikrokontrolerze za pomocą kryształu kwarcu generującego impulsy zegarowe i ustawiającego „rytm”, bez konieczności stosowania zewnętrznego sprzętu lub układów scalonych 555), która umożliwia sterowanie chwilowymi zdarzeniami dzięki zegarom wewnętrzny. Na przykład wykonywanie zadania w odstępach czasu, wykonywanie dokładnych pomiarów czasu itp., niezależnie od kodu szkicu.

Como Arduino UNO Ma chip MCU, który działa z częstotliwością 16 Mhz, co sekundę można wykonać 16.000.000 16 XNUMX. Instrukcje wymagają do wykonania X cykli, nie wszystkie są wykonywane w tych samych cyklach zegara, na przykład XNUMX-bitowe potrzebują więcej cykli w tej architekturze AVR.

Wyobraź sobie, że używasz funkcja delay(), spowoduje to zablokowanie wykonywania na MCU Arduino do czasu upłynięcia określonego czasu, a następnie kontynuowanie programu, ale zegar nie zostanie zablokowany. Będzie to odliczanie czasu, ponieważ MCU będzie nadal wykonywać jednocześnie inne instrukcje. To jest wielka zaleta.

Zegar jest powiązany z przerwy Arduino, ponieważ będą one wykonywane za ich pośrednictwem w celu wykonania określonego zadania. Innymi słowy, Arduino Timer to funkcja, która jest wyzwalana w określonym czasie, wykonując funkcję przerwania. Dlatego ważne jest, aby wiedzieć o tych przerwach.

Tryby

Arduino Timer ma 2 tryby pracy, będąc w stanie używać go w:

  • Sygnał PWM: Możesz kontrolować Piny Arduino (~).
  • CTC (Wyczyść timer przy porównaniu meczu): zlicza czas wewnątrz licznika i gdy osiągnie wartość określoną w rejestrze timerów, przerwa jest wykonywana.

Ile ma timerów? Rodzaje timerów

Arduino UNO funkcje millis

Tam 3 liczniki na talerzach Arduino UNO, choć na innych płytach górnych może być ich więcej:

  • Zegar 0: 8-bit, może liczyć od 0 do 255 (256 możliwych wartości). Używany przez funkcje takie jak delay(), millis() i micros(). Nie zaleca się jego modyfikacji, aby nie zmieniać programów.
  • Zegar 1: równy Timerowi 0. Używany przez bibliotekę Servo w UNO (Timer 5 dla MEGA).
  • Zegar 2: 16-bitowy i może mieścić się w zakresie od 0 do 65.525 65.536 (XNUMX XNUMX możliwych wartości). Używany w funkcji tone(), jeśli nie jest używany, może być swobodnie używany w twojej aplikacji.
  • Timer 3, 4, 5 (tylko na Arduino MEGA): wszystkie 16-bitowe.

Jak działa Arduino Timer?

timery, timery

Do praca z Arduino Timerem, ważne jest, aby wiedzieć, jak to wszystko działa elektronicznie w MCU tej płyty rozwojowej:

  • Częstotliwość zegara: to liczba cykli na sekundę, którą jest w stanie rozwinąć, w przypadku Arduino jest to 16 Mhz, czyli to samo, sygnał zegara oscyluje 16.000.000 XNUMX XNUMX razy na sekundę (cykle).
  • periodo: jest reprezentowane przez T i jest mierzone w sekundach i jest odwrotnością cykli. Na przykład T=1/C, co dałoby 1/16000000 = 0.0000000625, czas potrzebny na zakończenie każdego cyklu. A częstotliwość jest odwrotnością okresu, więc f = 1/T.
  • Cykl: to każde z powtórzeń sygnału, które występują w jednostce czasu. Na Arduino byłoby to 16M w sekundę. Albo to samo, w tym przypadku, gdy minęło 16 milionów cykli, minęła sekunda. Dlatego można powiedzieć, że jeden cykl trwa 625 ns.
  • krawędź sygnału: Sygnały zegara są kwadratowe, a krawędzie mogą rosnąć lub opadać. Krawędź to prosta linia sygnału, gdy zmienia się z:
    • 0 (niski) do 1 (wysoki): zbocze narastające.
    • 1 (wysoki) do 0 (niski): opadająca krawędź.

Krawędzie są ważne, ponieważ liczniki Arduino mierzą cykle od krawędzi sygnału. A) Tak contador zwiększa się z każdym cyklem i gdy osiągnie wartość rejestru, przerwanie jest wykonywane.

Dlatego, gdy już to wiesz, jeśli masz 16 MHz na Arduino MCU, a używany jest 8-bitowy Timer, można powiedzieć, że przerwania będą występować co 16 μs (256/16000000) lub 4 ms dla 16-bitów (65536/16000000). Dlatego jeśli ustawisz 16-bitowy rejestr licznika na maksimum, o wartości 65535, to przerwanie nastąpi po 4 ms, aby wykonać jakiekolwiek zadanie.

Gdy licznik osiągnie maksymalną możliwą wartość, ponownie wróci do 0. Oznacza to, że pojawia się przepełnienie, które będzie odliczać od początku.

Aby kontrolować szybkość narastania timera, możesz również użyć preskaler, który przyjmuje wartości 1, 8, 64, 256 i 1024 i zmienia rozrząd tak:

Szybkość timera (Hz) = Częstotliwość zegara Arduino / Preskaler

Jeśli wynosi 1, preskaler kontroler zwiększy się do 16 MHz, jeśli będzie to 8 do 2 MHz, jeśli będzie 64 do 250 kHz i tak dalej. Pamiętaj, że będzie dostępny komparator stanu licznika timera, który porównuje wartości licznika i preskalera, dopóki nie zrównają się, a następnie wykona akcję. Więc, częstotliwość przerywania wyrażona jest wzorem:

+1 wynika z tego, że rejestr licznika jest indeksowany na 0, tj. nie zaczyna zliczać od 1, ale od 0.

Prędkość przerwania (Hz) = Częstotliwość zegara Arduino / Preskalera (wartość rejestru komparatora + 1)

Na szczęście nie możemy modyfikować rekordy Arduino Timers, ponieważ zadbają o to biblioteki, których używamy w kodzie. Ale jeśli nie są używane, należy je skonfigurować.

Przykłady w Arduino IDE

Arduino IDE, typy danych, programowanie

Aby to wszystko trochę lepiej zrozumieć, pokazuję tutaj dwa kody szkicu dla Arduino IDE, dzięki którym można doświadczyć korzystania z timerów. Pierwszy to kod, który co sekundę będzie migać diodą LED podłączoną do pinu 8 Arduino:

#define ledPin 8
void setup()
{
  pinMode(ledPin, OUTPUT);
  // Configurar Timer1
  TCCR1A = 0;                        //Registro control A a 0, pines OC1A y OC1B deshabilitados
  TCCR1B = 0;                        //Limpia el registrador
  TCCR1B |= (1<<CS10)|(1 << CS12);   //Configura prescaler a 1024: CS12 = 1 y CS10 = 1
  TCNT1 = 0xC2F8;                    //Iniciar timer para desbordamiento a 1 segundo
                                     //65536-(16MHz/1024/1Hz - 1) = 49912 = 0xC2F8 en hexadecimal
  
  TIMSK1 |= (1 << TOIE1);           //Habilitar interrupción para Timer1
}
void loop()
{
}
ISR(TIMER1_OVF_vect)                              //Interrupción del TIMER1 
{
  TCNT1 = 0xC2F7;                                 // Reniciar Timer1
  digitalWrite(ledPin, digitalRead(ledPin) ^ 1); //Invierte el estado del LED
}

Zaprogramuj miganie lub miganie diody, tak jak w poprzednim przypadku co sekundę, ale tym razem za pomocą CTC czyli porównanie:

#define ledPin 8
void setup()
{
  pinMode(ledPin, OUTPUT);
  
  // Configuración Timer1
  TCCR1A = 0;                //Registro de control A a 0
  TCCR1B = 0;                //Limpiar registro
  TCNT1  = 0;                //Inicializar el temporizador
  OCR1A = 0x3D08;            //Carga el valor del registro de comparación: 16MHz/1024/1Hz -1 = 15624 = 0X3D08
  TCCR1B |= (1 << WGM12)|(1<<CS10)|(1 << CS12);   //Modo CTC, prescaler de 1024: CS12 = 1 y CS10 = 1  
  TIMSK1 |= (1 << OCIE1A);  //Habilita interrupción por igualdad de comparación
}
void loop()
{
}
ISR(TIMER1_COMPA_vect)          //Interrupción por igualdad de comparación en TIMER1
{
  digitalWrite(ledPin, digitalRead(ledPin) ^ 1);   //Invierte el estado del LED
}

Więcej o programowaniu Arduino

kup talerz Arduino UNO Wersja 3

Bądź pierwszym który skomentuje

Zostaw swój komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

*

*

  1. Odpowiedzialny za dane: Miguel Ángel Gatón
  2. Cel danych: kontrola spamu, zarządzanie komentarzami.
  3. Legitymacja: Twoja zgoda
  4. Przekazywanie danych: Dane nie będą przekazywane stronom trzecim, z wyjątkiem obowiązku prawnego.
  5. Przechowywanie danych: baza danych hostowana przez Occentus Networks (UE)
  6. Prawa: w dowolnym momencie możesz ograniczyć, odzyskać i usunąć swoje dane.