Forum: Mikrocontroller und Digitale Elektronik Fehler bei ldi r16, 0b00001111


von Christoph S. (mixer) Benutzerseite


Lesenswert?

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?

von Johannes M. (johnny-m)


Lesenswert?

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.

von Maltem (Gast)


Lesenswert?

Hast du irgendwelche Interrupthandler eingebunden?
Welcher Controller?

Versuch mal, vor die erste Anweisung deines Programmes folgendes zu 
setzen:

.org $002a

von Christoph S. (mixer) Benutzerseite


Lesenswert?

Hallo,

Danke für den tip. Hab die .org vom timer falsch geschrieben!

MFG

von Johannes M. (johnny-m)


Lesenswert?

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.

von Christoph S. (mixer) Benutzerseite


Lesenswert?

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!

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Welche Fehlermeldungen bekommst du denn?

von Johannes M. (johnny-m)


Lesenswert?

Am Besten die Tabelle aus dem zum Controller gehörigen Datenblatt 
übernehmen. Dann knallts auch nicht wegen jmp oder rjmp...

von Karl H. (kbuchegg)


Lesenswert?

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!

von Karl H. (kbuchegg)


Lesenswert?

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.

von Christoph S. (mixer) Benutzerseite


Lesenswert?

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

von Maltem (Gast)


Lesenswert?

Datenblatt Seite 47.

ale rjmps (bis auf die benötigten) durch RETI ersetzen

von Karl H. (kbuchegg)


Lesenswert?

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.

von Michael U. (amiga)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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 :-)

von Wolfram Q. (quehl)


Lesenswert?

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