Forum: Mikrocontroller und Digitale Elektronik Overlap in .seg ... -Assembler-


von Maxim (Gast)


Lesenswert?

Was bedeutet der Fehler? Ich vermute, das hat was mit Interruptvektoren 
zu tun.

Hier das Programm:


.include "m8def.inc"

.def tmp1 = R16

  ldi tmp1,HIGH(RAMEND)
  out SPH,tmp1
  ldi tmp1,LOW(RAMEND)
  out SPL,tmp1

.equ MPORT = PORTC
.equ IN1 = PC0
.equ IN2 = PC1
.equ IN3 = PC2
.equ IN4 = PC3
.equ ENA = PC4
.equ ENB = PC5

reset:
  ldi tmp1, 0xFF
  out DDRC, tmp1

  cbi DDRD, PD2  //Taster1, ENon
  cbi DDRD, PD3  //Taster2, ENoff
  sbi DDRD, PD5  //Led1
  sbi DDRD, PD6  //Led2, EN Status

  sbi PORTD, PD6
  cbi MPORT, ENA
  cbi MPORT, ENB

  ldi tmp1, (1<<WGM21)|(1<<CS22)|(1<<CS21)|(1<<CS20)    //CTC Modus
  out TCCR2, tmp1

  ldi tmp1, (1<<OCIE2)  //CTC Interrupt enable
  out TIMSK, tmp1

  ldi tmp1, 0xF0
  out OCR2, tmp1

  rjmp main


.org OC2addr  //Compare Match Interrupt
  rjmp match

main:
  sbic PIND, PD2  //Taster abfrage
  rcall ENon
  sbic PIND, PD3
  rcall ENoff



  rjmp main

match:
  sbis PIND, PD5
  rjmp LED1on
  sbic PIND, PD5
  rjmp LED1off

  LED1on:
    sbi PORTD, PD5
    reti

  LED1off
    cbi PORTD, PD5
    reti

ENon:
  sbi PORTD, PD6
  sbi MPORT, ENA
  sbi MPORT, ENB
  ret

ENoff:
  cbi PORTD, PD6
  cbi MPORT, ENA
  cbi MPORT, ENB
  ret

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Die Interuptvektoren muessen vor das eigetliche Hauptprogramm.
Dann gibts auch keine Probleme :)

also

.org 0x00
  rjmp reset
.org OC2addr  //Compare Match Interrupt
  rjmp match

reset:
# der rest deines Programms#

von Michael U. (Gast)


Lesenswert?

Hallo,

zum Verständnis etwas länger:

der Assembler macht genau, was Du ihm sagst.

reset:

  ldi tmp1, 0xFF
  out DDRC, tmp1

usw.

  rjmp main

Da Du ihm nicht sagst, wo er den Kram hinschreiben soll (.org) beginnt 
er bei Adresse 0x0000 und schreibt Deine befehle der Reihe nach rein.

rjmp main landet also irgendwo bei 0x0016 (jetzt nicht genau 
nachgerechnet...), der Zähler zeigt also auf 0x0017

Jetzt kommt Dein

.org OC2addr  //Compare Match Interrupt
  rjmp match

Der Assembler holt sich also den Wert für =C2addr aus m8def.inc und will 
seinen Zähler auf Adresse 0x0003 setzen und...

wundert sich sehr, weil da schon
  cbi DDRD, PD2
steht und teilt Dir genau dieses mit.

Theoretisch kann man die Vektorliste auch ans Programm-Ende schreiben 
mit

.org INT_VECTORS_SIZE

reset:
  ldi tmp1, 0xFF
  out DDRC, tmp1
usw.
rjmp main

.org 0x0000
  rjmp reset

.org OC2addr  //Compare Match Interrupt
  rjmp match

macht die Sache nur nicht unbedingt übersichtlicher...

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.