Forum: Mikrocontroller und Digitale Elektronik Wie löst der Interupt in dem Programm aus?


von Daniel F. (danielf)


Angehängte Dateien:

Lesenswert?

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

von Jochen R. (josch90)


Lesenswert?

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ß

von Frankl (Gast)


Lesenswert?

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.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von Daniel F. (danielf)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?

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.

von MarioT (Gast)


Lesenswert?

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

von Daniel F. (danielf)


Lesenswert?

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

von Uwe (Gast)


Lesenswert?

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

von Udo R. S. (Gast)


Lesenswert?

@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.

von Michael U. (amiga)


Lesenswert?

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

von Daniel F. (danielf)


Lesenswert?

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

von Stefan B. (stefan) Benutzerseite


Lesenswert?


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
Noch kein Account? Hier anmelden.