www.mikrocontroller.net

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


Autor: Christoph S. (mixer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Maltem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du irgendwelche Interrupthandler eingebunden?
Welcher Controller?

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

.org $002a

Autor: Christoph S. (mixer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

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

MFG

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christoph S. (mixer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welche Fehlermeldungen bekommst du denn?

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christoph S. (mixer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Maltem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Datenblatt Seite 47.

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So sieht eine saubere Interrupt Tabelle aus:
.include "m8def.inc"

       rjmp main

.org INT0addr
       reti             ; External Interrupt0 Vector Address
.org INT1addr
       reti             ; External Interrupt1 Vector Address
.org OC2addr
       reti             ; Output Compare2 Interrupt Vector Address
.org OVF2addr
       reti             ; Overflow2 Interrupt Vector Address
.org ICP1addr
       reti             ; Input Capture1 Interrupt Vector Address
.org OC1Aaddr
       reti             ; Output Compare1A Interrupt Vector Address
.org OC1Baddr
       reti             ; Output Compare1B Interrupt Vector Address
.org OVF1addr
       reti             ; Overflow1 Interrupt Vector Address
.org OVF0addr
       reti             ; Overflow0 Interrupt Vector Address
.org SPIaddr
       reti             ; SPI Interrupt Vector Address
.org URXCaddr
       reti             ; USART Receive Complete Interrupt Vector Address
.org UDREaddr
       reti             ; USART Data Register Empty Interrupt Vector Address
.org UTXCaddr
       reti             ; USART Transmit Complete Interrupt Vector Address
.org ADCCaddr
       reti             ; ADC Interrupt Vector Address
.org ERDYaddr
       reti             ; EEPROM Interrupt Vector Address
.org ACIaddr
       reti             ; Analog Comparator Interrupt Vector Address
.org TWIaddr
       reti             ; Irq. vector address for Two-Wire Interface
.org SPMaddr
       reti             ; SPM complete Interrupt Vector Address
.org SPMRaddr
       reti             ; SPM complete Interrupt Vector Address

main:
       ... 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.

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

meine persöhnliche Variante:
.include "m8def.inc"

       rjmp main

.org INT0addr
       reti             ; External Interrupt0 Vector Address

.org OVF0addr
       reti             ; Overflow0 Interrupt Vector Address
   ... nur die benötigten Vektoren einfügen

.org INT_VECTORS_SIZE   ; ist generell in den includes passend gesetzt
main:
 ... 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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:
.include "m8535def.inc"
;
.macro  INTERRUPT
        .set    current_pc = PC
        .org    @0                      ; Vektor-Adresse
        .if FLASHEND > 0x0fff
                jmp     current_pc
        .else
                rjmp    current_pc      ; Sprung zum Handler
        .endif
        .org    current_pc              ; restore Programmcounter
.endmacro
;
        rjmp    main
.org    INT_VECTORS_SIZE        ; hinter allen Interruptvektoren
main:
        nop
        rjmp    pc
;
        INTERRUPT OVF0addr
        nop                     ; hier interrupthandler einfügen
        reti
;
        INTERRUPT INT0addr
        nop
        reti

Und wenn man dann z.B. den ATMega8535 durch nen ATmega32 ersetzen will, 
einfach nur das Include ändern, mehr nicht.


Peter

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Wolfram Quehl (quehl)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.