assembler interrupt aktivieren

OP #2909522
Lesenswert?

Hi an alle,

ich bin gerade am lernen, wie man Interrupts programmiert. Zumindest am 
versuchen.
 Ich habe ein Programm geschrieben, bei dem die Uhr läuft, und jedesmal 
wenn sie einen Overflow abgibt, soll die "LED-Lichterkette" anders 
leuchten.


Das Programm:

.include "tn2313def.inc"

.org 0x000
  rjmp main
.org OVF0addr    //Interruptaktivierung für Overflow von Clock0
  rjmp clock

main:
sei          //Interrupts aktiviert

ldi r16, 0x00
out DDRD, r16    //DDRD wird Eingang

ldi r16, 0xFF
out DDRB, r16    //DDRB wird Ausgang
out PORTB, r16    //Die Ausgänge werden "Aus-geschaltet"

ldi r16, 0x01
out TCCR0, r16    //Aktivierung der clock0, Prescaler = 1024 Schritte

ldi r18, 0x01
ldi r19, 0xFF

loop:

rjmp loop


clock:

  inc r16
  cpi r16, 0xFF

  brlo next      //branch if lower
    clr r16
    inc r17
    out PORTB, r17

  next:

reti        //Sprung zurück ins Programm, i = Interrupts wieder 
freigeschaltet


Mein Problem ist im Moment, dass aber der Interrupt nicht aktiviert 
wird. Wie mache ich das beim Attiny2313?

Viel dank im voraus für eure Hilfe
Fabi
Gast #2909582
Lesenswert?

Da du noch am Lernen bist gleich gute Angewohnheiten:
Fabian Scheidig schrieb:
> ldi r16, 0x02
> out TIMSK, r16
ist doof. Weil man nämlich erstmal die Zahl in Bits zerlegen muss um zu 
gucken was gesetzt wird.
Besser:
ldi r16, (1<<BIT)

s. auch Bitmanipulation

Und es ist sehr empfehlenswert sich für die Register per .def Namen zu 
definieren, so kann man schnell was tauschen wenn bestimmte Register 
(etwa X/Y/Z oder r0 für mul) für andere Zwecke gebraucht werden.
OP #2910301
Lesenswert?

Hi an alle,

inzwischen bin ich bei einem externen Interrupt angekommen.
Mein Problem ist aber, dass ich bereits meine platine intelligenterweise 
zusammengelötet habe und mein Taster an PIN6 von PORTD liegt.
Der externe Interrupt wird aber standardmäßig an einem anderen PIN 
ausgelöst.

Laut Datasheet von meinem attiny 2313, muss ich im PCMSK (PinChangeMask) 
entsprechend das passende BIT setzen und dort kann dann der Interrupt 
ausgelöst werden.

Mein Programm (zumindest der Teil fürs Einstellen des Interrupts):

ldi r16, (1<<6) | (1<<5)  //6: INT0 enabled, 5: PINchange allowed
out GIMSK, r16

clr r16
ldi r16, (1<<0) | (1<<1)  //0 & 1: bei fallender Flanke wird Interrupt 
ausgelöst
out MCUCR, r16

clr r16
ldi r16, (1<<6)        //PinChangeMask, Pin6 ausgewählt
out PCMSK, r16

sei

Leider aktiviert sich aber der Interrupt nicht. Was fehlt noch? Bzw. was 
mache ich falsch?

Fabi
Gast #2910329
Lesenswert?

Hi

>ich arbeite im moment mit int0 (nur leider am falschen PIN)

Nein. Du hast zwar INT0 auch aktiviert aber du willst PCINT haben. Das 
ist ein anderer Interrupt. INT0 kannst du nicht einfach umleiten. 
Entferne das Gedöhns für Int0.

MfG Spess
OP #2910402
Lesenswert?

Das Problem ist aber inzwischen, dass die Interrupts auf gewissen Pins 
festgelegt sind (zumindest beim Attiny2313 soweit ich das datenblatt 
verstehe)

Mein belegter PIN hat diese Sonderfunktion leider nicht.

Gibt es irgendwelche leichte Schleifen o.ä. die man ins Programm 
reinkopieren kann? Ich schreibe in assemblersprache

thanks
OP #2921018
Lesenswert?

Hi Leute,

ich bin inzwischen bei einem neuen Problem angekommen.
Nachdem ich alles initialisiert habe, komme ich in die Hauptschleife. 
Irgendwann aktiviert sich ein Interrupt und dann fängt das Programm von 
komplett vorne an. D.h. es wird alles wieder initialisiert. Eigentlich.
Ich habe einfach eine Abfrage eingebaut, ob denn nicht der Ausgang 
PORTD, auch Ausgang ist, wenn ja, dann soll er nix mehr initialisieren, 
da ja das schon am Anfang gemacht worden ist.

Allerdings bringt er mir inzwischen einen Fehler:
C:\Users\Fabian\Documents\AVR-Studio\Revolights\Revolights.asm(23): 
error: Overlap in .cseg: addr=0xd conflicts with 0xd:0xe
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren