Forum: Mikrocontroller und Digitale Elektronik ATmega32 Interupt Problem


von FireFly (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

programmiere seit kurzem den ATmega32 (habe bereits C167 programmiert) 
und hab folgendes Problem:

Ich will zwei Stepper zyklisch laufen lassen (Treiberstufe aus L297/L298 
wie hier schon des öfteren besprochen) und will dazu mit dem Timer1 
Compare Interupt das Enable Signal der beiden Treiberstufen toggeln.

Ich habe mir die einzelnen Config Register aus dem Datenblatt 
zusammengebaut, aber ich komme mit der Interupt Behandlung nicht ganz 
klar (zumindest denke ich dass das Problem hier liegt).

Ich habe den Code hinten angefügt, wäre super wenn jemand mal einen 
kurzen blick darauf werfen würde um mir bei meinem Denkfehler 
weiterzuhelfen.

Anmerkungen zum Code:
Timer0 erzeugt den Takt für Stepper 1
Timer2 erzeugt den Takt für Stepper 2
Timer1 erzeugt Interupt

Fragen:
- Stimmt das TIMSK Register?
- Stimmt die Verzweigung im Interupt Vektor?
- Muss ich mich um das TIFR Register kümmern? (Hab das Datenblatt so 
interpretiert, dass hier nur Flags angezeigt werden wenn ein Interupt 
wirklich auftritt)


Vielen Dank erstmal

von johnny.m (Gast)


Lesenswert?

Zunächst mal ist Deine Interrupt-Vektortabelle falsch. Bei allen AVRs 
mit mehr als 8 KB Flash sind die Interrupt-Vektoren zwei Worte breit 
(also 32 Bit). Da rjmp und reti je nur 16 Bit haben, stimmen die 
Adressen nicht mehr. Am besten übernimmst Du die Vektortabelle aus dem 
Datenblatt. Die sollte nämlich stimmen. Ansonsten anstatt "reti" ein 
"nop reti" schreiben und statt "rjmp" "jmp" benutzen.

von Dieter Werner (Gast)


Lesenswert?

Ich programmiere zwar keine ATmega, aber wenn ich mich richtig an andere 
Beiträge in diesem Forum erinnere, liegen die Interrupt Vektoren im 
2-Wort Abstand.
RJMP und RETI belegen aber nur jeweils ein Befehlswort.

Es hat sich auch als brauchbar herausgestellt, alle unbenutzten Int's 
auf einen error handler springen zu lassen.

von johnny.m (Gast)


Lesenswert?

> - Stimmt die Verzweigung im Interupt Vektor?
Ob sie "stimmt", kann ich nicht sagen. Man kann es aber so machen. 
Wichtig ist, dass ein reti das ganze beendet, und das ist schließlich 
gegeben.

von johnny.m (Gast)


Lesenswert?

> - Muss ich mich um das TIFR Register kümmern?
Nein, wenn Du die Interrupts aktiviert und auch den Rest korrekt 
konfiguriert hast, dann werden die Interrupt-Flags beim Einsprung in den 
Interrupt-Vektor automatisch gelöscht.

von Michael U. (Gast)


Lesenswert?

Hallo,

meine Variante (ohne Error-Handler) ohne ständige Rechnerei:
1
.include "m8def.inc"
2
3
;********** Verktor-Liste ***********
4
5
.CSEG
6
  rjmp  Reset
7
8
.ORG    OVF0addr
9
  rjmp  irq_1ms
10
11
;******* Programm-Beginn ************
12
13
;************************************
14
;  Initialisierungsroutine
15
;************************************
16
17
.ORG    INT_VECTORS_SIZE
18
19
; Hardware initialisieren
20
21
Reset:
22
  ldi  TEMP_A,low(RAMEND)          ; Stack an das interne Ram-Ende
23
  out  SPL,TEMP_A
24
  ldi  TEMP_A,high(RAMEND)
25
  out  SPH,TEMP_A

Erspart Rechnerei...

Gruß aus Berlin
Michael

von FireFly (Gast)


Lesenswert?

Vielen Dank an alle!

Problem war wohl, dass ich mir eine fertige Int-Vector Tabelle eines 
kleineren megas geholt, und die zusätzlichen Ints des 32er (zB INT2) 
einfach dazwischen geschrieben habe (zwar eigentlich nach Datenblatt, 
aber da wird das Problem wohl wie erwähnt mit der relativen Adressierung 
zusammenhängen).

Mit .org's an die jeweilige Stelle wie von Michael vorgeschlagen 
funktioniert die Sache jetzt!

Nebenbei: Das AVR-Studio meckert die Konstante INT_VECTORS_SIZE an!? 
aber mit .org $02A klappts

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.