Hallo, wollte gerade ein bisschen programmieren. Bei ldi r16, 0b00001111 out DDRB, r16 bringt er beim assemblieren folgenden Fehler: error: Overlap in .cseg: addr=0x9 conflicts with 0x9:0xa dabei ist im register nichts. was mache ich dabei falsch?
Die Meldung bezieht sich auch nicht auf das Register, sondern auf den Programmspeicher. Wenn Du allerdings nur eine Codezeile zeigst, kann man nur raten, dass Du irgendwo eine .org-Direktive drin hast, deren Adresse mit dem Rest des Programms kollidiert.
Hast du irgendwelche Interrupthandler eingebunden? Welcher Controller? Versuch mal, vor die erste Anweisung deines Programmes folgendes zu setzen: .org $002a
Hallo, Danke für den tip. Hab die .org vom timer falsch geschrieben! MFG
Kleiner Tip: es macht fast immer Sinn, die komplette Interrupt-Vektortabelle einzubauen und in die nicht verwendeten Interrupt-Vektoren ein reti (oder nop reti bei AVRs mit mehr als 8 KiB Flash) reinzuschreiben oder ein (r)jmp zu einer Fehlerbehandlungsroutine. Nur wenn man überhaupt keine Interrupts verwendet, macht es viel Sinn, die Tabelle wegzulassen und direkt im Reset-Vektor mit dem Programm anzufangen.
wie baue ich die ein? Wenn ich die vom tutorial reinschreibe, bringt er nur fehler! eigentlich brauch ich nur den interrupt vom timer0 und vom timer2 beim mega8!
Am Besten die Tabelle aus dem zum Controller gehörigen Datenblatt übernehmen. Dann knallts auch nicht wegen jmp oder rjmp...
Christoph S. wrote: > wie baue ich die ein? > Wenn ich die vom tutorial reinschreibe, bringt er nur fehler! Welche Fehler? > eigentlich brauch ich nur den interrupt vom timer0 und vom timer2 beim > mega8!
Hab nochmal im Tutorial nachgesehen: Klar bringt der dort Fehler. Wenn da steht RJMP SPI_STC und es gibt kein Label SPI_STC im Code, dann ist das ein Fehler. Drum steht aber auch nach dem Code der Satz: Bei unbenutzten Interrupts ist es üblich, statt des Sprungbefehls einfach den Befehl reti reinzuschreiben. Aber im Prinzip hast du recht. Das müsste man mal im Tutorial überarbeiten und eine schöne Interrupttabelle mit .org Anweisungen aufbauen.
undefined symbol: EXT_INT0 und bei allen anderen vektoren auch. Im Datenblatt hab ich auch keine Tabelle gefunden. bräucht eigentlich nur ein .org OVF0addr für den timer2!!! .org OVF2addr geht nicht, da kommt die Fehlermeldung mit den registern! MFG
Datenblatt Seite 47. ale rjmps (bis auf die benötigten) durch RETI ersetzen
So sieht eine saubere Interrupt Tabelle aus:
1 | .include "m8def.inc" |
2 | |
3 | rjmp main |
4 | |
5 | .org INT0addr |
6 | reti ; External Interrupt0 Vector Address |
7 | .org INT1addr |
8 | reti ; External Interrupt1 Vector Address |
9 | .org OC2addr |
10 | reti ; Output Compare2 Interrupt Vector Address |
11 | .org OVF2addr |
12 | reti ; Overflow2 Interrupt Vector Address |
13 | .org ICP1addr |
14 | reti ; Input Capture1 Interrupt Vector Address |
15 | .org OC1Aaddr |
16 | reti ; Output Compare1A Interrupt Vector Address |
17 | .org OC1Baddr |
18 | reti ; Output Compare1B Interrupt Vector Address |
19 | .org OVF1addr |
20 | reti ; Overflow1 Interrupt Vector Address |
21 | .org OVF0addr |
22 | reti ; Overflow0 Interrupt Vector Address |
23 | .org SPIaddr |
24 | reti ; SPI Interrupt Vector Address |
25 | .org URXCaddr |
26 | reti ; USART Receive Complete Interrupt Vector Address |
27 | .org UDREaddr |
28 | reti ; USART Data Register Empty Interrupt Vector Address |
29 | .org UTXCaddr |
30 | reti ; USART Transmit Complete Interrupt Vector Address |
31 | .org ADCCaddr |
32 | reti ; ADC Interrupt Vector Address |
33 | .org ERDYaddr |
34 | reti ; EEPROM Interrupt Vector Address |
35 | .org ACIaddr |
36 | reti ; Analog Comparator Interrupt Vector Address |
37 | .org TWIaddr |
38 | reti ; Irq. vector address for Two-Wire Interface |
39 | .org SPMaddr |
40 | reti ; SPM complete Interrupt Vector Address |
41 | .org SPMRaddr |
42 | reti ; SPM complete Interrupt Vector Address |
43 | |
44 | main: |
45 | ... dein Code hier |
Du möchtest einen Handler für den Overflow Interrupt vom Timer 2 installieren, also tauscht du in der betreffenden Zeile den reti gegen einen Sprung zu deiner Behandlungsroutine.
Hallo, meine persöhnliche Variante:
1 | .include "m8def.inc" |
2 | |
3 | rjmp main |
4 | |
5 | .org INT0addr |
6 | reti ; External Interrupt0 Vector Address |
7 | |
8 | .org OVF0addr |
9 | reti ; Overflow0 Interrupt Vector Address |
10 | ... nur die benötigten Vektoren einfügen |
11 | |
12 | .org INT_VECTORS_SIZE ; ist generell in den includes passend gesetzt |
13 | main: |
14 | ... dein Code hier |
Generell reti bei unbenutzten Vektoren hat den Nachteil, daß sich bestimmte Programmfehler verstecken können. Ein falscher freigegeber IRQ wird sauber mit reti beendet, das eigentlich gewünschte Routine macht aber scheinbar nichts. Ganz gut wäre sicher ein Error-Handler, der bei allen ungenutzten IRQs aufgerufen wird und mault, dazu bin ich aber auch meist zu bequem... Gruß aus Berlin Michael
Karl heinz Buchegger wrote: > So sieht eine saubere Interrupt Tabelle aus: Ja, man kann es so umständlich machen mit viel Schreibarbeit. Und wenn Du nen anderen AVR nimmst, ist die ganze Tabelle vorn Arsch. Man kann es sich aber auch einfach machen mit einem Macro:
1 | .include "m8535def.inc" |
2 | ; |
3 | .macro INTERRUPT |
4 | .set current_pc = PC |
5 | .org @0 ; Vektor-Adresse |
6 | .if FLASHEND > 0x0fff |
7 | jmp current_pc |
8 | .else |
9 | rjmp current_pc ; Sprung zum Handler |
10 | .endif |
11 | .org current_pc ; restore Programmcounter |
12 | .endmacro |
13 | ; |
14 | rjmp main |
15 | .org INT_VECTORS_SIZE ; hinter allen Interruptvektoren |
16 | main: |
17 | nop |
18 | rjmp pc |
19 | ; |
20 | INTERRUPT OVF0addr |
21 | nop ; hier interrupthandler einfügen |
22 | reti |
23 | ; |
24 | INTERRUPT INT0addr |
25 | nop |
26 | reti |
Und wenn man dann z.B. den ATMega8535 durch nen ATmega32 ersetzen will, einfach nur das Include ändern, mehr nicht. Peter
Peter Dannegger wrote: > Karl heinz Buchegger wrote: >> So sieht eine saubere Interrupt Tabelle aus: > > Ja, man kann es so umständlich machen mit viel Schreibarbeit. > > Und wenn Du nen anderen AVR nimmst, ist die ganze Tabelle vorn Arsch. Eben nicht, die Vektoren sind doch alle einzeln mit .org adressiert. Ich habe diese Version jetzt mal ins Tutorial aufgenommen. Der MACRO-Trick ist natürlich auch nicht schlecht.
Peter Dannegger wrote: > Karl heinz Buchegger wrote: >> So sieht eine saubere Interrupt Tabelle aus: > > Ja, man kann es so umständlich machen mit viel Schreibarbeit. > > Und wenn Du nen anderen AVR nimmst, ist die ganze Tabelle vorn Arsch. > > > Man kann es sich aber auch einfach machen mit einem Macro: Und du denkst ein Neuling versteht was da abgeht :-) Ansonsten: nettes Makro. Das ist das Schöne: da lernen die alten Hasen auch noch dazu :-)
wenn man .org ..... und reti in eine Zeile schreibt, ist diese nur noch halb so lang. Und man sieht gleich, welcher Befehl zu welchem Interrupt gehört, ohne 2 Zeilen lesen zu müssen. (ist es die vorherige oder nachfolgende, könnte doch von Anfängern auch mißverstanden werden). mfg
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.