Arduino UNO Unterbrechungstimer

Der Timer ist eine Funktion, die in jeden Mikrocontroller integriert ist und bestimmte Funktionen in Bezug auf den Ablauf der Zeit hat. Die Timer-Funktion eines Mikrocontrollers lässt sich so erklären, dass der Timer bestimmt, wann das Programm ausgeführt wird und wann es gestoppt wird. Der Timer auf einem Mikrocontroller besteht aus mehreren Registern, deren Werte automatisch ab- und zunehmen. Auf dem Arduino UNO gibt es zwei Arten von Timern, nämlich einen Timer mit 8-Bit-Auflösung und einen Timer mit 16-Bit-Auflösung. FS Tech wird jedoch nicht näher auf diesen Timer eingehen, da wir uns in dieser Anleitung darauf konzentrieren, wie Sie den Timer auf dem Arduino UNO ausführen und einstellen.

Warum Interrupt Timer verwenden

Das Einstellen des Timers auf dem Mikrocontroller ermöglicht es uns, Programme zu ganz bestimmten Zeiten in bestimmten Zeitintervallen in einer Art Multitasking auszuführen. Wie wir wissen, führt der Arduino ein Programm in einer Schleife aus, indem er die Funktion void loop(void) {} in der Reihenfolge ausführt, in der sie geschrieben wurde, aber es wird sehr schwierig sein, die Zeit der in dieser Funktion enthaltenen Ereignisse zu bestimmen. Dies geschieht, weil einige Befehle sehr schnell und andere Befehle sehr langsam ausgeführt werden. Dies wird durch die Anzahl der ausgeführten Programme und bedingte Anweisungen wie if, while, do while oder for loop bestimmt. Der Timer, der auf der Arduino loop()-Funktion läuft, ist aufgrund der vielen in der Arduino-Bibliothek enthaltenen Funktionen sehr schwer vorherzusagen.

Der Interrupt Timer auf dem Mikrocontroller ermöglicht es Ihnen, die Laufzeit der loop()-Funktion in präzisen Zeitintervallen zu steuern. Wenn der Interrupt Timer ausgeführt wird, stoppt dies die Laufzeit in der loop()-Funktion und lässt eine Reihe von separaten Programmen laufen, die auf einem Timer außerhalb der loop()-Funktion laufen und den Timer zurückgeben, um die loop()-Funktion erneut laufen zu lassen, nachdem ein anderer Timer die Ausführung des Programms beendet hat.

Der Betrieb eines Interrupt-Timers bietet Ihnen u.a. folgende Vorteile:

  • Misst eingehende Signale in gleichmäßigen Abständen
  • Berechnet die Zeit zwischen zwei Programmen
  • Sendet und erzeugt Signale auf bestimmten Frequenzen
  • Eingehende serielle Daten regelmäßig prüfen
  • Zwei Programme gleichzeitig ausführen (Multitasking)
  • Und viele mehr

Prescaler und Berechnung von Timer-Werten

Arduino UNO hat drei Timer, Timer-0, Timer-1 und Timer-3. Jeder Timer auf dem Arduino Uno hat eine Zeiteinstellung, die mit jeder Zeitperiode zunimmt, bis ein bestimmter Wert erreicht ist, der in einem Register gespeichert ist und jedes Mal zurückgesetzt wird, wenn der Zeitwert erreicht ist. Und dieser Zyklus wird fortgesetzt, wenn der Arduino eingeschaltet ist. Der Timer-Wert hängt davon ab, wie groß die Timer-Adressbits sind. Ein Timer mit einem Wert von 8 Bits hat beispielsweise einen Wertebereich von 0-255 und ein Timer mit einer Auflösung von 16 Bits hat einen Wertebereich von 0-65535.

Um einen Timer zu berechnen, können wir eine Berechnung verwenden, die Prescaler genannt wird. Diese Berechnung kann mit der folgenden Gleichung geschrieben werden.

TimerGeschwindigkeit(Hz) = ArduinoClockSpeed(16MHz) / Vorteiler

Prescaler-Wert an Prescaler-Adresse

Die obige Tabelle zeigt den Wert des Vorteilers bei jeder Vorteileradresse, so dass die Gleichung für den Timer-Berechnungswert mit der folgenden Gleichung geschrieben werden kann.

InterruptFrequency(Hz) = ArduinoClockSpeed(16MHz) / ((Vorteiler * (compareMatchRegister + 1))

+1 durch den Vergleich von übereinstimmenden Registerwerten mit dem Index 0.

Wenn Sie also einen Prescaler-Wert benötigen, kann die Gleichung entsprechend der folgenden Gleichung geschrieben werden.

CompareMatchRegister = 16MHz / (Vorteiler * GewünschteInterruptFrequenz) - 1

Und denken Sie daran, dass bei der Verwendung von Timer-0 und Timer-2 der Wert kleiner als 256 und bei der Verwendung von Timer-1 der Wert kleiner als 65536 sein muss. 

Verwendung von Timer-Interrupts zur Ausführung von Multitasking-Programmen

Timer-0 2KHz

				
					void setup(void) {
	cli();
	TCCR0A = 0;
	TCCR0B = 0;
	TCNT0 = 0;
	OCR0A = 124;
	TCCR0A |= (1<<WGM01);
	TCCR0B |= (1<<CS01) | (1<<CS00);
	TIMSK0 |= (1<<OCIE0A);
	sei();
}
				
			

TCCR0A = 0; TCCR0B, TCNT0 = 0; bedeutet, dass der Zeitwert auf 0 gesetzt wird.

OCR0A setzt das Vergleichsregister für 2KHz-Schritte (16*10^6)/(2000*64)-1

WGM01 CTC einschalten

CS01 & CS00 setzen CS01 & CS00 Bits für 64 Vorteiler

TIMSK0 aktiviert Timer-Vergleichsinterrupt

Timer-1 1Hz

				
					void setup(void) {
	cli();
	TCCR1A = 0;
	TCCR1B = 0;
	TCNT1 = 0;
	OCR1A = 15624;
	TCCR1B |= (1<<WGM12);
	TCCR1B |= (1<>CS10);
	TIMSK1 |= (1<<OCIE1A);
	sei();
}
				
			

TCCR1A = 0; TCCR1B, TCNT1 = 0; bedeutet, dass der Zeitwert auf 0 gesetzt wird.

OCR1A setzt Vergleichsregister für 1Hz-Schritte (16*10^6)/(1*1024)-1

WGM12 schaltet CTC ein

CS10 & CS12 setzen CS10 & CS12 Bits für 1024 Prescaler

TIMSK1 aktiviert Timer-Vergleichsinterrupt

Timer-2 8KHz

				
					void setup(void) {
	cli();
	TCCR2A = 0;
	TCCR2B = 0;
	TCNT2 = 0;
	OCR2A = 249;
	TCCR2A |= (1<<WGM21);
	TCCR2B |= (1<<CS21);
	TIMSK2 |= (1<<OCIE2A);
	sei();
}
				
			

TCCR2A = 0; TCCR2B, TCNT2 = 0; bedeutet, dass der Zeitwert auf 0 gesetzt wird.

OCR2A setzt Vergleichsregister für 8KHz-Schritte (16*10^6)/(8000*8)-1

WGM21 schaltet CTC ein

CS21 setzen CS21 Bits für 8 Vorteiler

TIMSK1 aktiviert Timer-Vergleichsinterrupt

Perhatikan bagaimana ke tiga Timer diatur, misalnya untuk mengaktifkan mode CTC

TCCR0A |= (1 << WGM01); // für Timer 0

TCCR1B |= (1 << WGM12); // für Timer 1

TCCR2A |= (1 << WGM21); // für Timer 2

Dan perhatikan nilai prescaler yang diatur sesuai pada tabel diatas.

TCCR1B |= (1 << CS11); // 8 Vorskalierer für Timer 1 

TCCR2B |= (1 << CS22); // 64 Vorteiler für Timer 2

TCCR0B |= (1 << CS02) | (1 << CS00); // 1024 Vorteiler für Timer 0

Der Befehl, den Sie während dieser Timer-Unterbrechung ausführen möchten, ist in der Arduino-Skizze wie folgt zusammengefasst, außerhalb der Funktionen void setup(void) und void loop(void), und auch Beispiele für jeden Timer erklärt.

ISR(TIMER0_COMPA_vect) {

// für Timer 0

}

ISR(TIMER1_COMPA_vect) {

// für Timer 1

}

ISR(TIMER2_COMPA_vect) {

// für Timer 2

}

Arduino Programmbeispiel zum Aktivieren eines Timers

Beispiel für Timer-0 2KHz

				
					void setup(void) {
	pinMode(11, OUTPUT);
	
	cli();
	TCCR0A = 0;
	TCCR0B = 0;
	TCNT0 = 0;
	OCR0A = 124;
	TCCR0A |= (1<<WGM01);
	TCCR0B |= (1<<CS01) | (1<<CS00);
	TIMSK0 |= (1<<OCIE0A);
	sei();
}
void loop(void) {
	// etwas tun ohne delay()
}
ISR(TIMER0_COMPA_vect) {
	static boolean toggle = true;
	toggle = !toggle;
	digitalWrite(11, toggle ? HIGH : LOW);
}
				
			

Beispiel für Timer-1 1Hz

				
					void setup(void) {
	pinMode(11, OUTPUT);
	
	cli();
	TCCR1A = 0;
	TCCR1B = 0;
	TCNT1 = 0;
	OCR1A = 15624;
	TCCR1B |= (1<<WGM12);
	TCCR1B |= (1<>CS10);
	TIMSK1 |= (1<<OCIE1A);
	sei();
}
void loop(void) {
	// etwas tun ohne delay()
}
ISR(TIMER1_COMPA_vect) {
	static boolean toggle = true;
	toggle = !toggle;
	digitalWrite(11, toggle ? HIGH : LOW);
}
				
			

Beispiel für Timer-2 8KHz

				
					void setup(void) {
	pinMode(11, OUTPUT);
	
	cli();
	TCCR2A = 0;
	TCCR2B = 0;
	TCNT2 = 0;
	OCR2A = 249;
	TCCR2A |= (1<<WGM21);
	TCCR2B |= (1<<CS21);
	TIMSK2 |= (1<<OCIE2A);
	sei();
}
void loop(void) {
	// etwas tun ohne delay()
}
ISR(TIMER1_COMPA_vect) {
	static boolean toggle = true;
	toggle = !toggle;
	digitalWrite(11, toggle ? HIGH : LOW);
}
				
			

Ende

Aus den drei Beispielen für Timer-Programme geht hervor, dass es nicht empfehlenswert ist, die delay()-Funktion zu verwenden, wenn der Timer-Interrupt aktiviert ist, da sie alle Timer-Aktivitäten auf dem Mikrocontroller stören kann, insbesondere wenn der Wert der delay()-Funktion den Vorteiler-Wert des Timer-Interrupts übersteigt und wenn Ihr Programm die Verwendung der delay()-Funktion erzwingt, dann verwenden Sie die millis()- oder macros()-Funktion auf Ihrem Arduino. Wenn der Wert der delay()-Funktion jedoch nicht den Wert des Vorteilsgebers überschreitet, dann kann es vielleicht ein wenig tolerierbar sein, aber auch das ist keine gute Wahl, und wenn Sie die millis()-Funktion oder macros()-Funktion nicht verstehen, können wir das ein anderes Mal besprechen.

Und ein kleiner Zusatz, den ich vielleicht vergessen habe zu erklären, ist die Funktion cli() und die Funktion sei().

Die Funktion cli() wird verwendet, um Timer-Interrupts zu deaktivieren

Die Funktion sei() wird verwendet, um den Timer-Interrupt zu aktivieren

Vielleicht ist das alles, was wir mit Ihnen teilen können, danke.

Mit freundlichen Grüßen.

Verwandte Blogs

Arduino UNO Unterbrechungstimer

Arduino UNO Interrupt Timer Der Timer ist eine Funktion, die in jeden Mikrocontroller eingebaut ist und bestimmte Funktionen in Bezug auf den Ablauf der Zeit hat. Die Timer-Funktion

Mehr lesen "

Wir würden uns freuen, von Ihnen zu hören