Forum: Mikrocontroller und Digitale Elektronik ATmega8 Timer1 + INT0 ==> Interrupt Conflict


von Philipp (Gast)


Lesenswert?

Hallo zusammen,

ich bin gerade dabei eine Uhr zu bauen, die bei einem Druck auf den 
Taster stehen bleibt. Der Taster ist an INT0 angeschlossen, er soll ein 
Interrupt auslösen.

Wenn ich das ganze jetzt compilen möchte, zeigt mir AVR Studio einen 
Fehler an der mit "#" markierten Stelle an.
error: Overlap in .cseg: addr=0x6 conflicts with 0x6:0x7

Kann mir vielleicht jemand sagen, was ich falsch gemacht habe?


.org 0x0000
        rjmp main        ; Reset Handler
.org OC1Aaddr
        rjmp Overflow  ; 16 Bit Timer Overflow Handler
.org INT0addr
         rjmp Stopp


main:

ldi temp, LOW (RAMEND)  ; Stack initialisieren
out SPL, temp

ldi temp, HIGH (RAMEND)
out SPH, temp

ldi temp, high (25000-1)  ; Überlauf Nach 25000 Takten
out OCR1AH, temp

ldi temp, low (25000-1)
out OCR1AL, temp

ldi temp, 0b00001011  ; CTC Modus aktivieren
out TCCR1B, temp    ; Prescaler 64 (250KHZ)

ldi temp, 0b00010000  ; Interrupt on Compare
out TIMSK, temp

ldi temp, 0b00000000??  ; Taster Pins als Eingang
out DDRD, temp

ldi temp, 0b00000010  ; Interrupt bei steigender Flanke
out MCUCR, temp

ldi temp, 0b01000000  ; Interrupt auf Port INT0 (PB2)
out GICR, temp

von Tim (Gast)


Lesenswert?

Ich bezweifle das die Reihenfolge
1
.org 0x0000
2
        rjmp main        ; Reset Handler
3
.org OC1Aaddr
4
        rjmp Overflow  ; 16 Bit Timer Overflow Handler
5
.org INT0addr
6
         rjmp Stopp
die gleiche ist wie im Datasheet.
Demnach macht dein Code folgendes:
Du schreibst an Adresse OC1Aaddr etwas(rjmp Overflow), springst dann
davor (.org INT0addr) und füllst ab da weiter. Somit überschreib der
folgenden Code "rjmp Overflow". Freundlicher meckert dein
Assembler das an.

Also Sortiere das entsprechend den Adressen oder lege eine
Vollständige Interrupt Vektor Tabelle an.

von Philipp (Gast)


Lesenswert?

Ok, jetzt funktioniert es. Ich dachte, dass der Compiler die 
Interruptvektoren im Assembler Programmcode selbst an die richtige 
Stelle setzt.
Da habe ich wohl falsch gedacht.

vielen Dank

von mmerten (Gast)


Lesenswert?

Ein .org INT_VECTORS_SIZE nach der Interrupt-Sprüngen reicht auch.

von Michael U. (amiga)


Lesenswert?

Hallo,

das wird der Assembler kaum können.

Die .org Anweisung sagt im ja nur, daß er jetzt ab der beim .org 
abgegebenen Adresse damit weitermachen soll. den folgenden Code im Flash 
abzulegen.

.org 0x0000 sagt also: schreiben den
        rjmp main        ; Reset Handler ab Adresse 0x0000
.org OC1Aaddr sagt dem Präprozessor, daß er den Wert für OC1Aaddr 
einsetzen soll. Das ist in der m8def.inc definiert, für den Mega8 also

.equ        OC1Aaddr=$006        ; Output Compare1A Interrupt Vector 
Address

        rjmp Overflow  wird also ab 0x006 abgelegt

.org INT0addr ist mit
.equ        INT0addr=$001        ; External Interrupt0 Vector Address

         rjmp Stopp wird also ab 0x001 abgelegt.

Da der rjmp Stopp 1 Word belegt, zeigt der interne Zeiger für den 
Assembler jetzt auf 0x002

Dorthin beginnt der Assembler jetzt Deine main zu übersetzen und fällt 
auf die Nase, wenn er bei 0x006 merkt, daß er da schon was 
hingeschrieben hat...

Um sowas muß man sich als ASM Programmierer selbst kümmern. :-)

Wenn man da nicht öfter drüber fallen will, geht z.B. sowas:

hinter den Vectoren einen passenden .org einfügen, da hat Atmel schon 
mitgedacht. In den aktuellen includes der AVR findet man am Schluß

.equ        INT_VECTORS_SIZE        = 19        ; size in words

.orq INT_VECTORS_SIZE
setzt also den Zeiger passend auf das erste Word hinter die 
Vectortabelle.

Gruß aus Berlin
Michael

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.