Πριν από λίγο καιρό δημοσιεύσαμε περισσότερες πληροφορίες για το συνάρτηση millis(). de ArduinoΤώρα θα εμβαθύνουμε στο Χρονοδιακόπτης Arduino, για να ξεκινήσετε με αυτήν τη δυνατότητα για τη δυνατότητα, κατανοήστε πώς αυτή η πλακέτα διαχειρίζεται το χρόνο με το MCU, καθώς και άλλες λειτουργίες πέρα από το millis().
Τι είναι το χρονόμετρο Arduino;
El Χρονόμετρο Arduino ή χρονόμετρο, είναι μια λειτουργία που υλοποιείται από υλικό (στον μικροελεγκτή, με τη βοήθεια του κρυστάλλου χαλαζία που παράγει τους παλμούς του ρολογιού και που ρυθμίζει τον "ρυθμό", χωρίς την ανάγκη εξωτερικού υλικού ή IC 555) που επιτρέπει τον έλεγχο προσωρινών συμβάντων χάρη στα ρολόγια εσωτερικός. Για παράδειγμα, η εκτέλεση μιας εργασίας κατά διαστήματα, η πραγματοποίηση ακριβών μετρήσεων χρόνου κ.λπ., ανεξάρτητα από τον κώδικα του σκίτσου.
Φανταστείτε ότι χρησιμοποιείτε το συνάρτηση delay()., αυτό θα μπλοκάρει την εκτέλεση στο Arduino MCU μέχρι να παρέλθει ο καθορισμένος χρόνος και στη συνέχεια θα συνεχιστεί με το πρόγραμμα, αλλά το χρονόμετρο δεν θα μπλοκάρει. Θα είναι χρονισμός καθώς το MCU συνεχίζει να εκτελεί άλλες εντολές ταυτόχρονα. Αυτό είναι το μεγάλο πλεονέκτημα.
Το χρονόμετρο σχετίζεται με διακοπές του Arduino, αφού θα εκτελεστούν μέσω αυτών για να παρακολουθήσουν κάποια συγκεκριμένη εργασία. Με άλλα λόγια, το Arduino Timer είναι μια συνάρτηση που ενεργοποιείται σε μια συγκεκριμένη στιγμή, εκτελώντας μια λειτουργία διακοπής. Γι' αυτό είναι επίσης σημαντικό να γνωρίζετε αυτές τις διακοπές.
Λειτουργίες
Το Arduino Timer έχει 2 τρόποι λειτουργίας, να μπορείτε να το χρησιμοποιήσετε σε:
- Σήμα PWM: Μπορείτε να ελέγξετε το Καρφίτσες Arduino (~).
- CTC (Διαγραφή χρονοδιακόπτη κατά τη σύγκριση αντιστοίχισης): μετρά τον χρόνο μέσα σε έναν μετρητή και όταν φτάσει στην τιμή που καθορίζεται σε έναν καταχωρητή των χρονομετρητών, εκτελείται η διακοπή.
Πόσα χρονόμετρα έχει; Τύποι χρονομέτρων
εκεί 3 χρονόμετρα στα πιάτα Arduino UNO, αν και μπορεί να υπάρχουν περισσότερα σε άλλες πλάκες κορυφής:
- Χρονόμετρο 0: 8-bit, μπορεί να μετρήσει από 0 έως 255 (256 πιθανές τιμές). Χρησιμοποιείται από συναρτήσεις όπως delay(), millis() και micros(). Δεν συνιστάται η τροποποίησή του για να μην αλλοιωθούν τα προγράμματα.
- Χρονόμετρο 1: ίσο με Timer 0. Χρησιμοποιείται από τη βιβλιοθήκη Servo στο UNO (Timer 5 για MEGA).
- Χρονόμετρο 2: 16-bit και μπορεί να κυμαίνεται από 0 έως 65.525 (65.536 πιθανές τιμές). Χρησιμοποιείται για τη συνάρτηση tone(), εάν δεν χρησιμοποιείται, μπορεί να χρησιμοποιηθεί ελεύθερα για την εφαρμογή σας.
- Χρονοδιακόπτης 3, 4, 5 (μόνο στο Arduino MEGA): όλα 16-bit.
Πώς λειτουργεί το Arduino Timer;
Να εργαστείτε με ένα χρονόμετρο Arduino, είναι ζωτικής σημασίας να γνωρίζουμε πώς όλα αυτά λειτουργούν ηλεκτρονικά στο MCU αυτού του συμβουλίου ανάπτυξης:
- Συχνότητα ρολογιού: είναι ο αριθμός των κύκλων ανά δευτερόλεπτο που μπορεί να αναπτύξει, στην περίπτωση του Arduino είναι 16 Mhz, ή το ίδιο, το σήμα ρολογιού ταλαντώνεται 16.000.000 φορές το δευτερόλεπτο (κύκλοι).
- Περίοδος: αντιπροσωπεύεται από το T και μετριέται σε δευτερόλεπτα και είναι το αντίστροφο των κύκλων. Για παράδειγμα, T=1/C, που θα είχε ως αποτέλεσμα 1/16000000 = 0.0000000625, ο χρόνος που θα χρειαζόταν για να ολοκληρωθεί κάθε κύκλος. Και η συχνότητα είναι το αντίστροφο της περιόδου, άρα f = 1/T.
- Κύκλος: είναι κάθε μία από τις επαναλήψεις του σήματος που συμβαίνει ανά μονάδα χρόνου. Στο Arduino θα ήταν 16M σε ένα δευτερόλεπτο. Ή τι είναι το ίδιο, σε αυτή την περίπτωση, όταν έχουν περάσει 16 εκατομμύρια κύκλοι, έχει περάσει ένα δευτερόλεπτο. Επομένως, ένας κύκλος μπορεί να ειπωθεί ότι διαρκεί 625 ns.
- άκρη ενός σήματος: Τα σήματα ρολογιού είναι τετράγωνα και οι άκρες μπορεί να ανεβαίνουν ή να πέφτουν. Μια άκρη είναι η ευθεία γραμμή του σήματος όταν αλλάζει από:
- 0 (χαμηλό) έως 1 (υψηλό): ανερχόμενη άκρη.
- 1 (υψηλό) έως 0 (χαμηλό): πτωτικό άκρο.
Οι άκρες είναι σημαντικές επειδή τα χρονόμετρα Arduino μετρούν τους κύκλους από τις άκρες του σήματος. Α) Ναι ο κοντάδος αυξάνεται με κάθε κύκλο και όταν φτάσει στην τιμή καταχωρητή, εκτελείται η διακοπή.
Επομένως, μόλις το μάθετε αυτό, εάν το έχετε 16Mhz στο Arduino MCU, και χρησιμοποιείται ένας χρονοδιακόπτης 8-bit, μπορεί να ειπωθεί ότι οι διακοπές θα συμβαίνουν κάθε 16 μs (256/16000000) ή 4 ms για 16-bit (65536/16000000). Επομένως, εάν ορίσετε τον καταχωρητή μετρητή 16 bit στο μέγιστο, με την τιμή 65535, τότε η διακοπή θα συμβεί στα 4 ms για να εκτελέσει οποιαδήποτε εργασία είναι.
Όταν ο μετρητής φτάσει στη μέγιστη δυνατή τιμή, θα επιστρέψει ξανά στο 0. Δηλαδή γίνεται υπερχείλιση και θα μετρήσει αντίστροφα από την αρχή.
Για να ελέγξετε τον ρυθμό αύξησης του χρονοδιακόπτη μπορείτε επίσης να χρησιμοποιήσετε ένα prescaler, το οποίο παίρνει τιμές 1, 8, 64, 256 και 1024 και αλλάζει το χρονισμό ως εξής:
Ταχύτητα χρονοδιακόπτη (Hz) = Συχνότητα ρολογιού του Arduino / Prescaler
Αν είναι 1 ο προκλιμακωτής ο ελεγκτής θα αυξηθεί στα 16 Mhz, αν είναι 8 στα 2 Mhz, αν είναι 64 στα 250 kHz, και ούτω καθεξής. Θυμηθείτε ότι θα υπάρχει ένας συγκριτής κατάστασης μετρητή χρονοδιακόπτη για να συγκρίνετε την τιμή του μετρητή και του προκλιμακωτή μέχρι να εξισωθούν και στη συνέχεια να εκτελέσετε μια ενέργεια. Ετσι, συχνότητα διακοπής δίνεται από τον τύπο:
Ταχύτητα διακοπής (Hz) = Συχνότητα ρολογιού Arduino / Prescaler (τιμή εγγραφής σύγκρισης + 1)
Ευτυχώς, δεν πρέπει τροποποιήσετε τις εγγραφές των Arduino Timers, αφού θα το φροντίσουν οι βιβλιοθήκες που χρησιμοποιούμε στον κώδικα. Αλλά εάν δεν χρησιμοποιούνται, θα πρέπει να ρυθμιστούν.
Παραδείγματα στο Arduino IDE
Για να τα καταλάβετε όλα αυτά λίγο καλύτερα, εδώ δείχνω δύο σκίτσους για το Arduino IDE με τους οποίους μπορείτε να γνωρίσετε τη χρήση χρονομέτρων. Ο πρώτος είναι κωδικός που θα αναβοσβήνει κάθε δευτερόλεπτο μια λυχνία LED που είναι συνδεδεμένη με τον ακροδέκτη Arduino 8:
#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 }
Προγραμματίστε το να αναβοσβήνει ή να αναβοσβήνει το LED, όπως στην προηγούμενη περίπτωση κάθε δευτερόλεπτο, αλλά αυτή τη φορά χρησιμοποιώντας CTC δηλαδή σύγκριση:
#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 }
Περισσότερα για τον προγραμματισμό Arduino
αγοράστε ένα πιάτο Arduino UNO Αναθ. 3