Forum: Mikrocontroller und Digitale Elektronik assembler interrupt aktivieren


von Fabian S. (fabian727)


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

von troll (Gast)


Lesenswert?

Du musst noch ein Interrupt Enable für den Timer setzen. Guck in die 
Register Description vom Timer. Iirc TIMSK oder so.

von Fabian S. (fabian727)


Lesenswert?

das hab ich jetzt noch eingefügt:
ldi r16, 0x02
out TIMSK, r16


SUPER HILFE, DANKESCHÖN, jetzt kanns weiter gehen

von troll (Gast)


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.

von Fabian S. (fabian727)


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

von Spess53 (Gast)


Lesenswert?

Hi

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

Welcher, Int0 oder PCINT?

MfG Spess

von Fabian S. (fabian727)


Lesenswert?

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

Heißt das, dass es zwei "Interruptarten" gibt?
INT0 (auf einem festgelegten PIN) und PCINT? der auf einem kompletten 
Port geschaltet werden kann?

von Spess53 (Gast)


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

von Fabian S. (fabian727)


Lesenswert?

ok danke.

Das ist jetzt schlecht, da ich einen falschen PIN mit dem Taster belegt 
habe um das Interrupt abzurufen. Gibt es sonst noch eine Möglichkeit 
eine low->high oder high->low Flanke abzufragen?

von Spess53 (Gast)


Lesenswert?

Hi

> Gibt es sonst noch eine Möglichkeit eine low->high oder high->low Flanke 
>abzufragen?

Einfach im Interrupt abfragen, ob der Pin High oder Low ist.

MfG Spess

von Fabian S. (fabian727)


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

von Spess53 (Gast)


Lesenswert?

Hi

>Gibt es irgendwelche leichte Schleifen o.ä. die man ins Programm
>reinkopieren kann?

Einfach in einem Timerinterrupt den Pin abfragen.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Tasten

Da hast du gleich die für Tasten notwendige Entprellung.

>Ich schreibe in assemblersprache

Ich auch.

MfG

von Fabian S. (fabian727)


Angehängte Dateien:

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

von Fabian S. (fabian727)


Lesenswert?

achja die Frage:

was sagt diese Fehlermeldung aus?
Bzw. wie kann ich sie korrigieren?

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.