Problem mit Timer-Interrupt (Assembler, AVR Studio)

OP #1205287
Lesenswert?

Hallo!

Ich versuche gerade mein erstes Programm komplett in Assembler zu 
schreiben. Fehler gibts beim Build schon mal nicht - freut mich. Aber 
beim Simulieren gibts ein Problem mit dem Timer-Interrupt.

Es werden zunächst ganz normal die Einzelschritte bis zur loop-Schleife 
gemacht - aber wenn der Timer-Interrupt auslöst springt das Programm zum 
ersten Befehl nach dem Label "main" und nicht zu "timer0_overflow".

Irgendwie finde ich nicht heraus, warum da so ist - habe auch schon 
einiges aus dem Netz probiert - immer der gleiche Fehler...

Wer kann mir da weiterhelfen?

Gruß

Jens
1
.include "2313def.inc"
2

3
;----------------------------------------------------
4
 
5
.def temp = R16
6
.def PWMcnt = R17
7
.def PWMwert = R18
8
.def Spalte = R19
9

10
;----------------------------------------------------
11

12
.equ F_CPU = 20000000
13
.equ RCK = PB4
14
.equ SCK = PB7
15
.equ SERI = PB5
16
.equ POE = PB3
17
.equ SCL = PB3
18

19
;----------------------------------------------------
20

21
.dseg                        ;Beginn Datensegment
22
Spalten:  .BYTE 14                ;14 Bytes für Spalte 1
23

24
.cseg                        ;Beginn Programmsegment
25

26
;----------------------------------------------------
27
 
28
.org 0x0000
29
  rjmp   main                            ;Reset Handler
30
.org OVF0addr*2
31
  rjmp   timer0_overflow                 ;Timer Overflow Handler
32

33
;----------------------------------------------------
34
 
35
main:
36
    ldi    temp, RAMEND                 ;Stackpointer initialisieren
37
    out    SPL, temp
38

39
    ldi    temp, 0b00000001                ;CS00 setzen: Teiler 1
40
    out    TCCR0, temp
41

42
    ldi    temp, 0b00000001                ;TOIE0: Interrupt bei Timer Overflow
43
    out    TIMSK, temp
44

45
  ldi    PWMcnt, 0                ;PWM-Counter auf 0 setzen
46
  ldi    Spalte, 1                ;mit Spalte 1 anfangen
47

48
     cbi    PORTB, POE                              ;Schieberegister "aktivieren"
49

50
    sei                        ;Interrupts aktivieren
51

52
;----------------------------------------------------
53

54
loop:
55
  rjmp   loop
56

57
;----------------------------------------------------
58

59
timer0_overflow:                              ;Timer 0 Overflow Handler
60

61
  reti
Gast #1205304
Lesenswert?

Kann ja nich sein. Lad mal die Include-Datei in nen Editor und guck Dir 
an, welcher Wert OVF0addr darin zugewiesen ist. Dann vergleichen mit der 
Interrupttabelle im Datenblatt (des richtigen Controllers).
OP #1205310
Lesenswert?

Für OVF0addr steht 0x0006 drin - stimmt mit dem Datenblatt überein. 
kommt aber bei 0x000D raus. Richtige Sprungmarke wäre bei 0x003E...

@flätz:

Glaube ich nicht, dass mir der Debugger das "verheimlicht", denn von der 
Taktanzahl her springt der direkt an diese Stelle. Da würde sich mehr 
ändern, da einiges im Int-Handler abgearbeitet wird (geposteter 
Quelltext ist gekürzt). Außerdem sollte der doch beim reti wieder in die 
loop springen - nicht ein ganzes Stück drüber...
Gast #1205316
Lesenswert?

> Außerdem sollte der doch beim reti wieder in die
> loop springen - nicht ein ganzes Stück drüber...

ja, stimmt.
Einfach mal die Sprungtabelle ausführlich hinschreiben?

rjmp main
nop
nop
nop
nop
nop
rjmp timer0_overflow
Gast #1205327
Lesenswert?

Wo springt er hin, wenn Du das als Sprungtabelle verwendest?

.ORG 0
rjmp   main    //0
reti       // 1
reti       // 2
reti       // 3
reti       // 4
reti       // 5
reti       // 6
reti       // 7
reti       // 8
reti       // 9
reti       // 10
reti       // 11
reti       // 12
reti       // 13
reti       // 14
reti       // 15
reti       // 16
reti       // 17
reti       // 18
reti       // 19
reti       // 20
reti       // 21
reti       // 22
reti       // 23
reti       // 24
reti       // 25
reti       // 26
reti       // 27
reti       // 28
reti       // 29
reti       // 30
Gast #1205335
Lesenswert?

>dann stimmt wohl was mit der Initialisierung des Timers nicht

Mit Verlaub - sowas notiert man auch nicht so...

>ldi   temp, 0b00000001        ;TOIE0: Interrupt bei Timer Overflow

...sondern so:

ldi   temp, 0<<OCIE2 | 0<<TOIE2 | 0<<TICIE1 | 0<<OCIE1A | 0<<OCIE1B | 
0<<TOIE1 | 0 | 0<<TOIE0

-----------------
(kopiert aus ner Datei für den ATmega8, also nicht ungeprüft 
übernehmen!)
OP #1205336
Lesenswert?

So, ich habe jetzt die Zeilen
1
    ldi    temp, 0b00000001   ;CS00 setzen: Teiler 1
2
    out    TCCR0, temp
3

4
    ldi    temp, 0b00000001  ;TOIE0: Interrupt bei Timer Overflow
5
    out    TIMSK, temp

ausgetauscht durch
1
    ldi    temp, (1<<CS00)     ;CS00 setzen: Teiler 1
2
    out    TCCR0, temp
3

4
    ldi    temp, (1<<TOIE0)    ;TOIE0: Interrupt bei Timer Overflow
5
    out    TIMSK, temp

und jetzt gehts auch ;)
OP #1205338
Lesenswert?

Da hatten wir jetzt wohl auch die gleiche Idee ;) Die Initialisierung 
stammt aus dem Tutorial "AVR-Tutorial: PWM" hier auf der Seite... mit 
hatte es so auch nicht gefallen - so wie es jetzt ist, ist es auch viel 
übersichtlicher.

So, Problem ist also gelöst. Vielen Dank für die Hilfe ;)

Gruß

Jens

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren