hallo Irgendwie kann ich dei Funktion des Programs nicht nachvollziehen wie bekomm ich das Programm dazu bei auslösen von int0 ext_int0 zu durchlaufen? Codeteile wo ext_int0 drin vorkommen : .org 0x00 rjmp reset ; Main Program rjmp ext_INT0 ; External Interrupt 0 Service ; rjmp T0_ovl ; Timer 0 Overflow Service ; rjmp AnComp ; Analog Comparator Service ............. ext_INT0: in SREGcopy,SREG ; save SREG in tempINT,PIND ; read Wiagand inputs andi tempINT,0b00000011 ; extract Data_1 and Data_0 lines cpi tempINT,0x00 ; Data_1Data_0=00? breq extERROR ; error - both lines can't be low ............ extERROR: out SREG,SREGcopy ; restore SREG reti Ganzer Programmcode im anhang. Das Program war für einen AT1200 gedacht und soll jetzt auf einen Tiny2313 laufen. gruß daniel
Eigendlich ganz einfach, wenn ein Interrupt kommt, lässt er deinen Programm-Counter auf eine definierte Stelle springen, im fall vom INT0 auf 0x0001. Auf dieser adresse steht rjmp ext_INT0, also springt dein programm zu ext_INT0. Im Datenblatt ist beschrieben bei welchem Interrupt dein Controller zu welcher Adresse Springt. Vector No. Program Address Source Interrupt Definition 1 0x0000 RESET External Pin, Power-on Reset, Brown-out Reset, and Watchdog Reset 2 0x0001 INT0 External Interrupt Request 0 3 0x0002 INT1 External Interrupt Request 1 4 0x0003 TIMER1 CAPT Timer/Counter1 Capture Event 5 0x0004 TIMER1 COMPA Timer/Counter1 Compare Match A 6 0x0005 TIMER1 OVF Timer/Counter1 Overflow 7 0x0006 TIMER0 OVF Timer/Counter0 Overflow 8 0x0007 USART0, RX USART0, Rx Complete 9 0x0008 USART0, UDRE USART0 Data Register Empty 10 0x0009 USART0, TX USART0, Tx Complete 11 0x000A ANALOG COMP Analog Comparator 12 0x000B PCINT Pin Change Interrupt 13 0x000C TIMER1 COMPB Timer/Counter1 Compare Match B 14 0x000D TIMER0 COMPA Timer/Counter0 Compare Match A 15 0x000E TIMER0 COMPB Timer/Counter0 Compare Match B 16 0x000F USI START USI Start Condition 17 0x0010 USI OVERFLOW USI Overflow 18 0x0011 EE READY EEPROM Ready 19 0x0012 WDT OVERFLOW Watchdog Timer Overflow Gruß
Nach auslösen des Ext_Into springt das Program nach rjmp ext_into und findet seine neue Sprungadresse in der Konstanten ext_into und springt dort hin, anschließend wird der Interrupt mit dem reti abgeschlossen und das Programm springt dort hin (PC+1) wo es vor der Unterbrechung war.
In den Codestücken mit dem ......... muss eine Initialisierung bestimmter Register sein, die dafür sorgt, dass der AVR für INT0 empfänglich wird. Und eine globale Freischaltung der Interrupts an sich. Wenn von aussen die Bedingung für einen INT0 anliegt, springt der AVR über die Zeile rjmp ext_INT0 in die Funktion ab ext_INT0: und führt diese bis zum RETI aus. In dem ...... Teil auch eine Initialisierung anderer Interrupts, deren Einsprungpunkte in die Behandlungsfunktionen jedoch in deinem Codestück auskommentiert sind. Das führt zum "Absturz" (Reset), wenn diese Interrupts auftreten.
Hallo Danke jetzt versteh ich auf wie das Funktioniert, war mir vorher nicht klar, ich kann an die stelle "rjmp ext_INT0" einen belibigen Strungpunkt setzen und sobald der interuppt ausgelöst wird springt es dahin. wenn ich das simikolon in der Zeile darunter wegnehme sprint das programm wenn int1 auselöst wird nach T0_ovl? gleich werden sicherlich noch fragen kommen. gruß daniel
Die Zeilen mit dem RJMP am Programmanfang bilden eine sog. Interruptvektortabelle. Jede Position steht für einen bestimmten Interrupt. Wenn du die Position nicht richtig verwendest (Datenblatt!), werden die falschen oder keine Interruptbehandlungsfunktion angesprungen und der AVR macht einen Fehler oder einen Reset.
rjmp RESET ;External Pin, Power-on Reset, Brown-out Reset, and Watchdog Reset rjmp ext_INT0 ;External Interrupt Request 0 reti ;rjmp ext_INT1 ;External Interrupt Request 1 reti ;rjmp TIMER1_CAPT ;Timer/Counter1 Capture Event reti ;rjmp TIMER1_COMPA ;Timer/Counter1 Compare Match A reti ;rjmp TIMER1_OVF ;Timer/Counter1 Overflow reti ;rjmp TIMER0_OVF ;Timer/Counter0 Overflow reti ;rjmp USART0_RX ;USART0, Rx Complete reti ;rjmp USART0_UDRE ;USART0 Data Register Empty reti ;rjmp USART0_TX ;USART0, Tx Complete reti ;rjmp ANALOG;COMP ;Analog Comparator reti ;rjmp PCINT ;Pin Change Interrupt reti ;rjmp TIMER1_COMPB ;Timer/Counter1 Compare Match B reti ;rjmp TIMER0_COMPA ;Timer/Counter0 Compare Match A reti ;rjmp TIMER0_COMPB ;Timer/Counter0 Compare Match B reti ;rjmp USI_START ;USI Start Condition reti ;rjmp USI_OVERFLOW ;USI Overflow reti ;rjmp EE_READY ;EEPROM Ready reti ;rjmp WDT_OVERFLOW ;Watchdog Timer Overflow RESET: sei ;Interrupt einschalten ;################################################# Ich habe mir die Interruptvektortabelle so in meinen Code geschrieben und ändere ihn je nach dem was ich brauche. (Ich hoffe er Stimmt so für den Tiny2313) Dann mußt Du noch den INT0 initialisieren: z.B. für Atmega8: ; INT0 initialisieren ; ldi temp,(1<<ISC01)|(1<<ISC00); INT0 konfigurieren (steigende Flanke) ; ldi temp,(1<<ISC01)|(0<<ISC00); INT0 konfigurieren (fallende Flanke) ldi temp,(0<<ISC01)|(1<<ISC00); INT0 konfigurieren (steigende und fallende Flanke) out MCUCR, temp ldi temp, (1<<INT0) ; INT0 aktivieren out GICR, temp
hallo ich habe mir jetzt passend zu controller eine Tabelle an den anfang gesetzt: org 0x00 rjmp reset ; Main Program rjmp ext_INT0 ; External Interrupt 0 Service rjmp nix rjmp nix rjmp nix rjmp nix rjmp T0_ovl ; Timer 0 Overflow Service rjmp nix rjmp nix rjmp nix rjmp nix rjmp nix rjmp nix rjmp nix rjmp nix rjmp nix rjmp nix rjmp nix rjmp nix ..... nix: reti so solle das doch funktionieren? gruß daniel
Hi! >Das Program war für einen AT1200 gedacht und soll jetzt auf einen >Tiny2313 laufen. Achtung, beim Tiny2313 Stackinit nicht vergessen! Viel Erfolg, Uwe
@Daniel
>nix: reti
im Prinzip schon mal nicht schlecht. Aber ohne jetzt die AT Prozessoren
zu kennen: Oft sperrt der Prozessor zu Beginn eines Interrupthandlings
alle weiterern Interrupts und man muss am Ende seiner
Interruptverarbeitung dafür Sorge tragen die Interruptverarbeitung
wieder freizugeben. Das fehlt mit hier aber wie gesagt ich kenn die
ATMELS jetzt nicht wirklich, vieleicht macht das ja der reti schon.
Hallo, Daniel Ff schrieb: > hallo > ich habe mir jetzt passend zu controller eine Tabelle an den anfang > gesetzt: > org 0x00 > rjmp reset ; Main Program > rjmp ext_INT0 ; External Interrupt 0 Service > rjmp nix > rjmp nix > rjmp nix > rjmp nix > rjmp T0_ovl ; Timer 0 Overflow Service > rjmp nix > rjmp nix > rjmp nix > rjmp nix > rjmp nix > rjmp nix > rjmp nix > rjmp nix > rjmp nix > rjmp nix > rjmp nix > rjmp nix > ..... > > nix: reti > > > so solle das doch funktionieren? Prinzipiell ja. Atmel hat in den Include-Dateien dafür Labels definiert. Wenn man diese benutzt, hat man 2 Vorteile: man muß nicht auf die Reihenfolge achten und man muß nicht alle eintragen. Als Beispiel 8hier nicht vom 2313, ist aber letztlich egal: .CSEG rjmp Reset .ORG OC2addr rjmp irq_1ms .ORG ICP1addr rjmp irq_capture .ORG OVF0addr rjmp irq_overflow ;****************************** Programm-Beginn ********************** .ORG INT_VECTORS_SIZE Reset: Das Label INT_VECTORS_SIZE zeigt immer direkt hinter die Interruptvectortabelle, dort beginnt dann das eigentlich Programm. Erleichtert auch den Wechsel auf einen anderen AVR, da werden dann vielleicht die Namen angemault, die kann man aber schnell anpassen, das abzählen der Adressen ist da umständlicher und fehlerträchig. Gruß aus Berlin Michael
Danke schonmal. werde ich gleich mal versuchen so umzubauen, was ist " Stackinit". hat dieser fehler vielleicht damit zu tun: AVR Simulator: Uninitialized stack pointer used at 0x0077 AVR Simulator: Excessive stack overflow, stop sim AVR Simulator: Uninitialized stack pointer used at 0x00a9 gruß daniel
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.