Forum: Mikrocontroller und Digitale Elektronik ATmega32 Interrupt fehlerhaft


von Mathias D. (pfmd86)


Lesenswert?

Hallo,
ich will bei einem Overflow von Timer0 einen Interrupt auslösen. 
Blöderweise springt der im Programm aber an die falsche Stelle. 
Eigentlich sollte er bei Overflow doch zum TIM0_OVF springen. In echt 
landet er aber auf dem letzen reti deer Interrupttabelle. Kann mir 
jemand sagen warum?
1
.include "m32def.inc"
2
.def  temp = r16
3
.def  leds = r18
4
5
jmp   RESET     ; Reset Handler
6
reti          ; IRQ0 Handler
7
reti          ; IRQ1 Handler
8
reti          ; IRQ2 Handler
9
reti          ; Timer2 Compare Handler
10
reti          ; Timer2 Overflow Handler
11
reti          ; Timer1 Capture Handler
12
reti          ; Timer1 CompareA Handler
13
reti          ; Timer1 CompareB Handler
14
reti          ; Timer1 Overflow Handler
15
reti          ; Timer0 Compare Handler
16
jmp   TIM0_OVF   ; Timer0 Overflow Handler
17
reti          ; SPI Transfer Complete Handler
18
reti          ; USART RX Complete Handler
19
reti          ; UDR Empty Handler
20
reti          ; USART TX Complete Handler
21
reti          ; ADC Conversion Complete Handler
22
reti          ; EEPROM Ready Handler
23
reti          ; Analog Comparator Handler
24
reti         ; Two-wire Serial Interface Handler
25
reti          ; Store Program Memory Ready Handler
26
27
28
RESET:
29
  ldi temp, HIGH(RAMEND)   ;Initialisierung Stackpointer
30
  out SPH,temp
31
  ldi  temp, LOW(RAMEND)
32
  out SPL, temp
33
34
  ldi temp, 0xff      ;PortB als Ausgang definieren
35
  out DDRB, temp
36
  
37
  ldi temp, 0b00000001
38
  out TIMSK, temp
39
  ldi temp, 0b00000001  ;Timer Teiler 1024
40
  out TCCR0, temp
41
    
42
  sei            ;Interrupt freigeben
43
44
  ldi leds,0xff
45
  out PORTB,leds
46
47
  jmp mainloop
48
49
mainloop:
50
51
  jmp mainloop
52
53
54
TIM0_OVF:
55
  dec leds
56
  out PORTB, leds
57
  reti

von spess53 (Gast)


Lesenswert?

Hi

Deine Interruptvektortabelle ist falsch. 'reti' belegt nur 1 Word. Beim 
ATMega32 werden aber an jeder Stelle 2 Word (jmp xyz) erwartet. Mach 
einfach nach jedem reti noch ein nop.

MfG Spess

von Mathias D. (pfmd86)


Lesenswert?

spess53 schrieb:
> Hi
>
> Deine Interruptvektortabelle ist falsch. 'reti' belegt nur 1 Word. Beim
> ATMega32 werden aber an jeder Stelle 2 Word (jmp xyz) erwartet. Mach
> einfach nach jedem reti noch ein nop.
>
> MfG Spess

 Super... und schon geht das...
Ist das generell so beim ATMega32?

Wenn ich aber im Programm nur einen Zyklus warten will kann ich doch ein 
einzelnes "nop" setzen oder? Also ich will den Hintergrund verstehen und 
nicht nur abschreiben.

von spess53 (Gast)


Lesenswert?

Hi

>Ist das generell so beim ATMega32?

Gilt für alle AVRs mit Flash >=16k

>Wenn ich aber im Programm nur einen Zyklus warten will kann ich doch ein
>einzelnes "nop" setzen oder? Also ich will den Hintergrund verstehen und
>nicht nur abschreiben.

Im dem Fall nicht. Da wird einfach der Abstand der RETIs um ein Word 
vergrößert.

MfG Spess

von Lueger (Gast)


Lesenswert?

Große AVR haben einen Adressraum, der mit relativen Sprungbefehlen nicht 
mehr ganz zugänglich ist. Bei diesen hat die Sprungliste Einträge mit 
jeweils zwei Worten Länge. Etwa so:

   jmp Main ; Reset, Sprung zur Initiierung
   jmp Int0Sr ; Externer Interrupt an INT0, Sprung zur Service-Routine
   reti ; Irgendein anderer Interrupt, nicht benutzt
   nop
   jmp IntTc0OvflwSr ; Überlauf Timer 0, Behandlungsroutine
   reti ; Irgendwelche anderen Interrupts, nicht benutzt
   nop
   reti ; Und noch mehr Interrupts, auch nicht benutzt
   nop

Bei Ein-Wort-Einträgen (z.B. RETI) sind die NOP-Instruktionen eingefügt, 
um ein weiteres Wort zu ergänzen, damit die Adressierung der 
nachfolgenden Sprungziel-Einträge wieder stimmt.

siehe http://www.avr-asm-tutorial.net/avr_de/interrupts/int_vektor.html

von Lueger (Gast)


Lesenswert?

Mit dem AVR Studio Simulator siehst du das sofort...

von Fabian (Gast)


Lesenswert?

Nimm statt des Reti lieber ein

jmp  UnhandledInterruptHandler

Dann siehst Du wenigstens gleich, wenn ein Interrupt auslöst, mit dem Du 
nicht rechnest.

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.