Präsentation herunterladen
Die Präsentation wird geladen. Bitte warten
1
Interrupts (http://nongnu
Interrupts erlauben die Unterbrechung des laufenden Prozesses auf Grund einer Interruptbedingung Der laufende (Maschinen-)Befehl wird fertig ausgeführt Aus der Interruptvektortabelle wird die Interruptserviceroutine (ISR) ausgewählt und aktiviert Während der ISR sind die Interrupts gesperrt (automatisches cli) unterbrechbare ISR werden mit ISR(XXX_vect, ISR_NOBLOCK){} vereinbart, man soll nicht einfach sei() in der ISR verwenden sollen zwei ISR den selben Code benutzen, so dies, wie folgt möglich: ISR(INT0_vect) { // Code to handle the event. } ISR(INT1_vect, ISR_ALIASOF(INT0_vect));
2
Interruptgesteuerte Programme
Interrupts erlauben Initialisierung externes Ereignis Interruptserviceroutine reti ISR(Vectorname) /* vormals: SIGNAL(siglabel) dabei Vectorname != siglabel ! */ { /* Interrupt Code */ } 3 Voraussetzungen: - globale Freigabe (sei: set enable interrupts) - Freigabe/Konfiguration des konkreten Interrupts/Interruptbedingung - Eintreten des externen Ereignisses 2
3
#include <avr/interrupt.h> //...
/* vormals: SIGNAL(siglabel) dabei Vectorname != siglabel ! */ ISR(Vectorname) { /* Interrupt Code */ } Tabellen->PORTS sehr schöne Zusammenstellung Wichtige Programmierkonstrukte: #include <avr/interrupt.h> sei(); //set enable Interrupts cli(); //clear enable Interrupts Interruptserviceroutine Variablen, die von ISR und anderen Funktionen benutzt werden, als volatile kennzeichnen. ISR(__vector_default) als Standard Interrupt handler anstelle Reset Steuerregister je nach Interrupt setzen Für INT0/INT1: MCUCR Bits 0..3 setzen (Bitangaben beziehen sich auf Atmega8! ) GICR INT0/INT1 erlauben (Bits 6,7) GIFR Interrupt Flag (Bits 6,7) 3
4
4
5
5
7
#include <avr/io.h>
#include <avr/pgmspace.h> #include <util/delay.h> #include <avr/interrupt.h> #define keypress_dly 100 // delay in ms #define key_mask 0x0c // PIND2 (INT0) & PIND3 (INT1) typedef unsigned char BYTE; typedef unsigned short WORD; /* * delay in ms */ void delay_ms(WORD ms){ for(ms /= 10; ms > 0; ms--) _delay_ms(10); } /* External Interrupt 0 */ ISR(INT0_vect){ /* Global interrupts are disabled */ . . .
8
/* External Interrupt Request 1 */
ISR(INT1_vect){ } int main(){ // DDRB fuer LEDs konfigurieren DDRB = 1 << PIN0 | 1 << PIN1 | 1 << PIN2 | 1 << PIN3; // 1 - for output; 0 - for input // Taste // DDRD2 & DDRD3 sollte 0 (also input) sein. // Init of external interrupts INT0 and INT1 MCUCR |=(1<<ISC01); // Fallende Flanke MCUCR |=(1<<ISC11); GICR = (1<<INT0) |(1<<INT1); // External Interrupt Request 0 and 1 Enable // Oder, GICR und GIMSK bezeichen das selbe Gräteregister GIMSK= (1<<INT0) |(1<<INT1); // External Interrupt Request 0 and 1 Enable sei(); // Global enable interrupts /* loop forever, the interrupts are doing the rest */ while(1); return 0;
9
main: ldi r16,0xff out DDRB,r16 ;//DDRB 0x17 ldi r16,0xf ; alle Leds ein out PORTB,r16 ; : Input, 1: Output ldi r16,0xf3 out DDRD,r16 ldi r16,(1<<INT0)|(1<<INT1) ; Interrupts erlauben Int0 und INT1 out GIMSK,r16 ldi r16,0xa ; 1010 Flanke a:fallende ; ldi r16,0xf ; Flanke f: steigende ; fallend: Taste gedrückt, steigend: Taste los out MCUCR,r16 sei rcall waitabit rcall waitabit eor r1,r1 ; R1:=0 out PORTB,r1 ; Ausgabe auf Leds loop: rjmp loop ; leere mainloop /* configs for io.h */ #define __SFR_OFFSET 0 #define _VECTOR(N) __vector_ ## N #include <avr/io.h> //#define mp r16 // oder r16 #define outerwait r17 // r17 #define innerwait r18 // r18 .global main 9
10
// Interruptvectoren .global INT0_vect INT0_vect: .global INT1_vect INT1_vect: cli ; Taste gedrueckt inc r1 ; Zaehlen out PORTB,r1; Ausgabe auf Leds l2: rcall waitabit in r16,PIND andi r16,(1<<PIND2)|(1<<PIND3) cpi r16,(1<<PIND2)|(1<<PIND3) brne l2 ; Taste wieder los sei reti waitabit: ; Takte = sec ldi outerwait,0xff ; waitouterloop: ldi innerwait,0xFF ; waitinnerloop: subi innerwait,0x01 ; brne waitinnerloop ; subi outerwait,0x01 ; brne waitouterloop ; ret
11
Die Timer Timer sind sehr komplizierte Gebilde
Die Timer 0,1 und 2 unterscheiden sich in der Verarbeitungsbreite und Funktionalität Für spezielle Anwendungen oder im Fehlerfall ist das manual zu konsultieren
12
Timer das Atmega8 Timer sind Zähler, die nebenläufig zur CPU arbeiten
Timer beginnen bei 0 oder einem einstellbaren Wert (Bottom) Verarbeitungsbreite bestimmt den Wert Top, nach Erreichen von Top erfolgt der Überlauf 3 Arten von Interrupts können generiert werden Int bei Überlauf Int bei Capture Event (ext. an ICPn oder Analogcomp.) Int bei Compare Event
13
Timer 0 Aufwärszähler (8 bit) Anfangswert in TCNT0 einstellen
Source einstellen in TCCR0: Aus Systemtakt Externer Impuls an T0 Interrupt bei Überlauf
14
Timer 0 (Register) http://www. avr-asm-tutorial
Timer 0 (Register) Nicht in allen Dingen ganz aktuell, aber sehr brauchbar
15
Timer 1 (16 bit) Aufwärtszähler/(Abwärtszähler) Int bei Überlauf,
CaptureEvent an Pin ICP1(PB0) ICR Compare A, Compare B (OCR1AL/H, OCR1BL/H) Anfangswert in TCNT1 einstellen Mehrere Controllregister TCCR1A, TCCR1B, Quelle einstellen in TCCR1B Externer Eingang über T1-PD5 Systemtakt über Vorteiler 2 (PWM) Ausgänge
16
Port Funktion Port-Adresse RAM-Adresse TCCR1A Timer/Counter 1 Control Register A 0x2F 0x4F 7 6 5 4 3 2 1 COM1A1 COM1A0 COM1B1 COM1B0 FCO1A FCO1B WGM11 WGM10 Bit Name Bedeutung Möglichkeiten 7 COM1A1 Compare Ausgang A 00: OC1A/B nicht verbunden 01: OC1A/B wechselt Polarität 10: OC1A/B auf Null setzen 11: OC1A/B auf Eins setzen 6 COM1A0 5 COM1B1 Compare Ausgang B 4 COM1B0 3 FOC1A Force output compare match A Ausgang wird entspr. Konfiguration geschaltet, Interrupt wird nicht erzeugt 2 FOC1B Force output compare match B 1..0 WGM11 WGM10 (PWM10 PWM11) Pulsweitengenerator 00: PWM aus 01: 8-Bit PWM 10: 9-Bit PWM 11: 10-Bit PWM
19
Schreiben von 16bit Timer Registern in Assembler ist die Reihenfolge zu beachten
; Write :r16 into TCNT1 ldi r19,hi8(0x ) ldi r18,lo8(0x ) out TCNT1H,r19 out TCNT1L,r18 ; Read TCNT1 into r17:r16 in r16,TCNT1L in r17,TCNT1H
20
Für asynchrone Taktung
Timer 2 (8 bit) Auf-/(Abwärts-)zähler (8 bit) Int bei Überlauf, Compare Steuerregister TCCR2 und ASSR Anfangswert in TCNT2 einstellen Vergleichswert in OCR2 1 PWM Ausgang Externer Clockeingang, für kHz Uhrenquarz, Steuerung über ASSR, für sleep (Power save mode) von Bedeutung Für asynchrone Taktung Mit Uhrenquarz
21
Port Funktion Port-Adresse RAM-Adresse TCCR2 Timer/Counter 2 Control Register 0x25 0x45 7 6 5 4 3 2 1 FOC2 WGM20 COM21 COM20 WGM21 CS22 CS21 CS20 Bit Name Bedeutung Möglichkeiten 7 FOC2 1:→compare match, Int wird nicht erzeugt (PB1: 1) 0: default 6 WGM20 1: PWM / 0: Normal mode 5 COM21 Configure OC2 00: OC2 off 01: toggle OC2 bei compare match 4 COM20 10: clear OC2 bei compare match 11: set OC2 on compare match 3 WGM21 1: clear Timer on compare match 2..0 CS22..CS20 Taktauswahl 000: Zähler anhalten 001: Clock 010: Clock / 8 011: Clock / 32 100: Clock / 64 101: Clock / 128 110: Clock / 256 111: Clock / 1024
22
Port Funktion Port-Adresse RAM-Adresse TIMSK Timer Interrupt Maskenregister 0x39 0x59 Interruptsteuerung für alle 3 Timer immer komplett beschreiben 7 6 5 4 3 2 1 OCIE2 TOIC2 TICIE1 OCIE1A OCIE1B TOIE1 - TOIE0 Bit Name Bedeutung Möglichkeiten 7 OCIE2 Timer/Counter 2 Vergleichszahl A Interrupt 0: Kein Int bei Überlauf 1: Int bei Überlauf 6 TOIE2 Timer/Counter 2 Überlauf-Interrupt 5 TICIE1 Timer/Counter 1 Capture-Ereignis Interrupt 0: Kein Int bei Capture 1: Int bei Capture 4 OCIE1A Timer/Counter 1 Vergleichszahl A Interrupt 0: Kein Int bei Erreichen Stand A 1: Int bei Erreichen Stand in A 3 OCIE1B Timer/Counter 1 Vergleichszahl B Interrupt 0: Kein Int bei Erreichen Stand B 1: Int bei Erreichen Stand in B 2 TOIE1 Timer/Counter 1 Überlauf-Interrupt 1 - TOIE0 Timer/Counter 0 Überlauf-Interrupt
23
Enegiesparende Sleep-modi
Bei Interruptgesteuerten Programmen, verbringt die CPU den größten Teil der Laufzeit in einer, oft leeren Schleife. Dabei verbraucht der Prozessor soviel Energie, wie bei jeder anderen Arbeit auch. Energie kann wirksam gespart werden, in dem die CPU in einen energiesparenden Modus geht, an Stelle in einer idle loop zu verharren. Durch einen Interrupt wird sie wieder geweckt.
24
/* loop forever, the interrupts are doing the rest */
{ //set_sleep_mode(SLEEP_MODE_IDLE); // geht immer //nachfolgende Sleep-modes erwachen nur bei LevelInt //ISC01, ISC00 bzw ISC11, ISC10 zurücksetzen (0) //Interrupt bei Low-Pegel am Eingang //set_sleep_mode(SLEEP_MODE_PWR_DOWN); //set_sleep_mode(SLEEP_MODE_STANDBY); //set_sleep_mode(SLEEP_MODE_PWR_SAVE); // s.o. //set_sleep_mode(SLEEP_MODE_EXT_STANDBY); //s.o. sleep_enable(); sei(); sleep_cpu(); sleep_disable(); }
25
Sleepmodes – Überblick http://www. mikrocontroller
27
Timer1Off(); OCR2 = 0; // Dummyzugriff while((ASSR & (1<< OCR2UB))); // Warte auf das Ende des Zugriffs TIMSK=(1<<TOIE2); rf12_stoprx(); set_sleep_mode(SLEEP_MODE_PWR_SAVE); sleep_enable(); sei(); sleep_cpu(); sleep_disable(); // initTimer1(); in ISR(TIMER2_OVF_vect) // und TIMSK komplett neu beschreiben“ (AVR/Funk/rfm12ds /TIMER2)
28
watchdogtimer Timer bis max. 2 Sekunden Zähldauer
Bewirkt automatisch reset bei Nulldurchgang #include <avr/wdt.h> wdt_enable(WDTO_1S); wdt_disable(); wdt_reset(); Manual s. 43
Ähnliche Präsentationen
© 2025 SlidePlayer.org Inc.
All rights reserved.