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