For noget tid siden offentliggjorde vi mere information om millis() funktion de ArduinoNu vil vi dykke dybere ned i Arduino timer, for at komme i gang med denne funktion til funktionen, skal du forstå, hvordan dette kort administrerer tid med MCU'en, såvel som andre funktioner ud over millis().
Hvad er Arduino Timer?
El Arduino timer eller timer, er en funktion implementeret af hardware (i mikrocontrolleren, ved hjælp af kvartskrystallen, der genererer clock-impulserne og som indstiller "rytmen", uden behov for ekstern hardware eller IC'er 555), der tillader styring af midlertidige hændelser takket være ure indre. For eksempel at få en opgave til at ske med intervaller, lave præcise tidsmålinger osv. uafhængigt af skitsekoden.
Forestil dig, at du bruger delay() funktion, vil dette blokere udførelse på Arduino MCU, indtil den angivne tid udløber, og derefter fortsætte med programmet, men timeren vil ikke blokere. Det vil være timing, da MCU fortsætter med at udføre andre instruktioner samtidigt. Det er den store fordel.
Timeren er relateret til afbrydelser af Arduino, da de vil blive udført gennem dem for at deltage i en bestemt opgave. Med andre ord er Arduino Timer en funktion, der udløses på et bestemt tidspunkt, der udfører en afbrydelsesfunktion. Derfor er det også vigtigt at kende til disse afbrydelser.
Tilstande
Arduino Timer har 2 driftstilstande, at kunne bruge det i:
- PWM signal: Du kan styre Arduino-stifter (~).
- CTC (Ryd timer ved sammenligningsmatch): tæller tiden inde i en tæller, og når den når den værdi, der er angivet i et register over timerne, udføres afbrydelsen.
Hvor mange timere har den? Typer af timere
Der 3 timere på pladerne Arduino UNO, selvom der kan være mere på andre topplader:
- timer 0: 8-bit, kan tælle fra 0 til 255 (256 mulige værdier). Bruges af funktioner som delay(), millis() og micros(). Dets modifikation anbefales ikke for ikke at ændre programmerne.
- timer 1: lig med Timer 0. Bruges af Servo-biblioteket i UNO (Timer 5 for MEGA).
- timer 2: 16-bit, og kan variere fra 0 til 65.525 (65.536 mulige værdier). Brugt til tone()-funktionen, hvis den ikke bruges, kan den frit bruges til din applikation.
- Timer 3, 4, 5 (kun på Arduino MEGA): alle 16-bit.
Hvordan virker Arduino Timer?
Til arbejde med en Arduino Timer, er det vigtigt at vide, hvordan alt dette fungerer elektronisk i MCU'en på dette udviklingskort:
- Urfrekvens: er antallet af cyklusser i sekundet, som den er i stand til at udvikle, i tilfældet med Arduino er det 16 Mhz, eller hvad der er det samme, ursignalet svinger 16.000.000 gange på et sekund (cyklusser).
- periodo: er repræsenteret ved T, og måles i sekunder, og er det omvendte af cyklusserne. For eksempel, T=1/C, hvilket ville resultere i 1/16000000 = 0.0000000625, den tid det ville tage for hver cyklus at fuldføre. Og frekvensen er den omvendte af perioden, så f = 1/T.
- cyklus: er hver af de gentagelser af signalet, der forekommer pr. tidsenhed. På Arduino ville det være 16M på et sekund. Eller hvad er det samme, i dette tilfælde, når 16 millioner cyklusser er gået, er der gået et sekund. Derfor kan en cyklus siges at tage 625 ns.
- kanten af et signal: Ursignaler er firkantede, og kanterne kan være stigende eller faldende. En kant er den rette linje af signalet, når det skifter fra:
- 0 (lav) til 1 (høj): stigende kant.
- 1 (høj) til 0 (lav): faldende kant.
Kanter er vigtige, fordi Arduino-timere måler cyklusser fra signalkanter. A) Ja contadoren den øges med hver cyklus, og når den når registerværdien, udføres afbrydelsen.
Derfor, når du først ved dette, hvis du har 16Mhz på Arduino MCU, og der bruges en 8-bit timer, kan det siges, at interrupts vil forekomme hver 16. μs (256/16000000) eller 4 ms for 16-bit (65536/16000000). Derfor, hvis du indstiller 16-bit tællerregisteret til maksimum, med værdien 65535, vil afbrydelsen forekomme ved 4 ms for at udføre den opgave, det er.
Når tælleren når den maksimalt mulige værdi, den vender tilbage til 0 igen. Det vil sige, at der opstår et overløb, og det vil tælle tilbage fra begyndelsen.
For at styre stigningshastigheden af timeren kan du også bruge en præscaler, som tager værdierne 1, 8, 64, 256 og 1024 og ændrer timingen sådan:
Timerhastighed (Hz) = Urfrekvens for Arduino / Prescaler
Hvis det er 1, vil forskaleren øges til 16 Mhz, hvis det er 8 til 2 Mhz, hvis det er 64 til 250 kHz, og så videre. Husk, at der vil være en timertællertilstandskomparator til at sammenligne værdien af tælleren og forskaleren, indtil de er ens, og derefter udføre en handling. Så, afbrydelsesfrekvens er givet ved formlen:
Interrupt Speed (Hz) = Arduino / Prescaler Clock Frequency (komparatorregisterværdi + 1)
Det må vi heldigvis ikke ændre poster af Arduino Timers, da det vil blive taget hånd om af de biblioteker, som vi bruger i koden. Men hvis de ikke bruges, skal de konfigureres.
Eksempler i Arduino IDE
For at forstå alt dette lidt bedre, viser jeg her to skitsekoder til Arduino IDE, som du kan komme til at opleve brugen af timere med. Den første er kode, der vil blinke en LED forbundet til Arduino pin 8 hvert sekund:
#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 }
Programmer blinkende eller blinkende LED, som i det foregående tilfælde hvert sekund, men denne gang ved at bruge CTC dvs. sammenligning:
#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 }køb en tallerken Arduino UNO rev3