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().
Wskaźnik
Co to jest 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.
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
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?
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:
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
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