;******************************************************************************* ;* ;* Titel: Beispiel zur Interrupt-Steuerung (B300_int_example.asm) ;* Datum: 30/12/09 Version: 0.4 (03/01/13) ;* Autor: www.weigu.lu ;* ;* Informationen zur Beschaltung: ;* Prozessor: ATmega32 Quarzfrequenz: 16MHz ;* Eingaenge: entprellter Taster an PORTD2 (INT0) ;* entprellter Taster an PORTD3 (INT1) ;* Ausgaenge: LED an PORTC0 ;* ;* Informationen zur Funktionsweise: ;* ;* Eine steigende Flanke an INT0 soll LED einschalten. ;* Eine fallende Flanke an INT1 soll die LED ausschalten. ;* Im Hauptprogramm blinkt eine LED ;* ;******************************************************************************* ;------------------------------------------------------------------------------- ; Einbinden der controllerspezifischen Definitionsdatei ;------------------------------------------------------------------------------- .NOLIST ;List-Output ausschalten .INCLUDE "m32def.inc" ;AVR-Definitionsdatei einbinden .LIST ;List-Output wieder einschalten ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ; Programmspeicher (FLASH) Programmstart nach RESET ab Adr. 0x0000 ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .CSEG ;was ab hier folgt kommt in den FLASH-Speicher .ORG 0x0000 ;Programm beginnt an der FLASH-Adresse 0x0000 RESET: rjmp INIT ;springe nach INIT (ueberspringe ISR Vektoren) ;------------------------------------------------------------------------------- ; Sprungadressen fuer die Interrupts organisieren (ISR VECTORS) ;------------------------------------------------------------------------------- ; Vektortabelle (im Flash-Speicher) .ORG INT0addr ;interner Vektor für INT0 (alt.: .ORG 0x0002) rjmp ISR_I0 ;Springe zur ISR von INT0 .ORG INT1addr ;interner Vektor für INT1 (alt.: .ORG 0x0004) rjmp ISR_I1 ;Springe zur ISR von INT1 ;------------------------------------------------------------------------------- ; Initialisierungen und eigene Definitionen ;------------------------------------------------------------------------------- .ORG INT_VECTORS_SIZE ;Platz fuer ISR Vektoren lassen INIT: .DEF Zero = r15 ;Register 1 wird zum Rechnen benoetigt clr r15 ;und mit Null belegt .DEF Tmp1 = r16 ;Register 16 dient als erster Zwischenspeicher .DEF Tmp2 = r17 ;Register 17 dient als zweiter Zwischenspeicher .DEF Cnt1 = r18 ;Register 18 dient als Zaehler .DEF WL = r24 ;Register 24 und 25 dienen als universelles .DEF WH = r25 ;Doppelregister W und zur Parameteruebergabe .DEF W = r24 .EQU LEDI = 0 ;LED ISR wird an Pin 0 angeschlossen .EQU LEDM = 1 ;LED MAIN an Pin 1 angeschlossen ;Stapel initialisieren (fuer Unterprogramme bzw. Interrupts) ldi Tmp1,LOW(RAMEND) ;RAMEND (SRAM) ist in der Definitions- out SPL,Tmp1 ;datei festgelegt ldi Tmp1,HIGH(RAMEND) out SPH,Tmp1 ;externe Interrupts initialisieren in Tmp1,MCUCR ;MCU Control Register einlesen andi Tmp1,0b11111011 ;ISC11=1, ISC10=0 => fallende Flanke ori Tmp1,0b00001011 ;ISC01=1, ISC00=1 => steigende Flanke out MCUCR,Tmp1 ;Wert ins MCUCR zurückschreiben in Tmp1,GICR ;General Int. Control Reg. einlesen ori Tmp1,0b11000000 ;INT1=1, INT0=1 => INT0+INT1 aktivieren out GICR,Tmp1 ;GICR setzen ;Port C und Port D konfigurieren cbi DDRD,2 ;INT0 = Eingang cbi DDRD,3 ;INT1 = Eingang sbi DDRC,LEDI ;Richtungsbit fuer LEDI auf Ausgang sbi DDRC,LEDM ;Richtungsbit fuer LEDM auf Ausgang ;globales Interrupt-Flag setzen (Int. erlauben) sei ;------------------------------------------------------------------------------- ; Hauptprogramm ;------------------------------------------------------------------------------- MAIN: sbi PORTC,LEDM ;LED im Sekundentakt toggeln rcall W500MS cbi PORTC,LEDM rcall W500MS rjmp MAIN ;Endlosschleife ;------------------------------------------------------------------------------- ; Unterprogramme und Interrupt-Behandlungsroutinen ;------------------------------------------------------------------------------- ; Interrupt-Behandlungsroutine von INT0 ISR_I0: push r16 ;benutzte Reg. retten (r16 = Zwischenspeicher) in r16,SREG ;Statusregister einlesen push r16 ;Statusregister retten sbi PORTC,LEDI ;LED ein pop r16 ;Werte der geretteten Register wieder- out SREG,r16 ;herstellen pop r16 reti ;Ruecksprung ins Hauptprogramm aus einer ;Interrupt-Behandlungsroutine ; Interrupt-Behandlungsroutine von INT1 ISR_I1: push r16 ;benutzte Reg. retten (r16 = Zwischenspeicher) in r16,SREG ;Statusregister einlesen push r16 ;Statusregister retten cbi PORTC,LEDI ;LED aus pop r16 ;Werte der geretteten Register wieder- out SREG,r16 ;herstellen pop r16 reti ;Ruecksprung ins Hauptprogramm aus einer ;Interrupt-Behandlungsroutine .INCLUDE "lib/SR_TIME_16M.asm" ;Zeitschleifenbibliothek einbinden ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .EXIT ;Ende des Quelltextes