Forum: Mikrocontroller und Digitale Elektronik Skyliner mit Mega8 - Int0 Probleme


von Sönkrrr B. (eldelirio)


Lesenswert?

Moin moin,

ich versuche momentan meinen code für einen Skyliner (ähnlich
Propellerclock) zum laufen zu bringen.

Ich will über eine 3x4 Tastatur Buchstaben eingeben und diese in ein
Array speichern.
Dann will ich über einen Reed-Kontakt den Int0 auslösen und damit die
ausgabe der Zeichen aus dem Array starten. (Also ein Int pro
Umdrehung)

Problem:
Mein Code funzt in einer Do Loop ohne Probleme, aber wenn ich ihn in
die ISR von Int= kopiere, geht gar nichts mehr oder nur komische
Zeichen, aber keine Buchstaben.

Frage:
Ist man in der ISR aus bestimmte Zeiten beschränkt oder sollte man es
vermeiden, im Int0 auf ein Array zuzugreifen?

Hier die beiden relevanten Code-Stellen:
(Ist noch alles im Rohbau und optimierungsfähig, also deshalb bitte
nicht meckern!)

---------------------------------------------------------------------
Das Array hat 10 Stellen (1-10), in die Dezimalzahlen eingetragen sind,
die zu Buchstaben gehören:

Stellen_Array(1) = 1     'Steht für ein A
Stellen_Array(1) = 2     'Steht für ein B
        .
        .
        .
---------------------------------------------------------------------
Die ISR des Int0:
IsrInt0:
   For Stelle = 1 To 10
      Call Zeichenausgabe(stellen_array(stelle))
   Next Stelle
   Waitms 200
Return
---------------------------------------------------------------------
Die Ausgabe Sub wurde nach dem Beispiel Bascom - Tabellen von
Roboternetz.de entwickelt:
http://www.roboternetz.de/wissen/index.php/Bascom_Tabellen

Sub Zeichenausgabe(byval Zeichen As Byte)

   Index = Lookdown(zeichen , Mapping , 28)
   Temp = Index - 1
   Temp = Temp * 5
   Portb = Lookup(temp , Patterntab)
   Incr Temp
   Waitms 2                                'Pause zwischen den Spalten

                                           'des 5x8 Buchstabens, die
                                           'angezeigt werden
   Portb = Lookup(temp , Patterntab)
   Incr Temp
   Waitms 2
   Portb = Lookup(temp , Patterntab)
   Incr Temp
   Waitms 2
   Portb = Lookup(temp , Patterntab)
   Incr Temp
   Waitms 2
   Portb = Lookup(temp , Patterntab)
   Incr Temp
   Waitms 2
   Portb = &B11111111                   'Alle LED aus
   Waitms 4                             'Pause zwischen den Zeichen
End Sub
---------------------------------------------------------------------
Mapping:
'-----"A"-"B"-"C"...
  Data 1 , 2 , 3 ,...
---------------------------------------------------------------------
Patterntab:
'A
Data &B00000000 , &B01101111 , &B01101111 , &B01101111 , &B00000000
'B
Data &B00000000 , &B01101110 , &B01101110 , &B01101110 , &B10010001
.
.
.

von Sönkrrr B. (eldelirio)


Lesenswert?

Edit
Die zweite Stelle im Array hat natürlich die Nummer 2 und nicht 1...

---------------------------------------------------------------------
Das Array hat 10 Stellen (1-10), in die Dezimalzahlen eingetragen
sind,
die zu Buchstaben gehören:

Stellen_Array(1) = 1     'Steht für ein A
Stellen_Array(2<----) = 2     'Steht für ein B
        .
        .
        .
---------------------------------------------------------------------

von Hannes L. (hannes)


Lesenswert?

Wartezeiten im Interrupt sind tödlich. Sowas tut man nicht.
Reed-Kontakte prellen, sie rufen den Interrupt also mehrfach auf.

...

von Sönkrrr B. (eldelirio)


Lesenswert?

Ok, sowas in die Richtung wollte ich hören.
Dann wäre meine Schlussfolgerung, dass ich einfach den Int Kram
weglassen und den Pin als Eingang nehme und dann über ein
If PinX = 0 then
meine Ausgabe aufrufe. Ist das besser? Entprellen würde ich dann
natürlich auch noch.

Zu Int nochmal, ich war davon ausgegangen, dass man einen Int nicht
prellen kann, zum einen, weil ich ihn als Low Level definiert habe und
zum anderen, weil er erst die ISR ausführt, bevor er auf irgendwas
anderes reagiert..
Aber ist mein erstes mal mit dem Int, daher kenn ich mich da noch nicht
so aus..
Danke soweit.

von Hannes L. (hannes)


Lesenswert?

> ... dass man einen Int nicht prellen kann, ...

Bei Auftreten eines Int-auslösenden Ereignisses wird dessen
Interrupt-Flag im Interrupt-Flagregister per Hardware gesetzt. Beim
Aufruf der ISR über den Interrupt-Vektor (Sprungtabelle) wird (von der
Hardware) das betreffende Int-Flag wieder gelöscht, zusätzlich wird das
I-Flag im SREG gelöscht und bei Verlassen der ISR wieder gesetzt.

Tritt ein weiteres Interrupt-Ereignis während der Abarbeitung der ISR
auf, dann wird das entsprechende Interrupt-Flag erneut gesetzt.
Daraufhin wird nach Verlassen der ISR sofort ein neuer Interrupt
ausgelöst und die ISR ein zweites mal aufgerufen.

> weil ich ihn als Low Level definiert habe ...

Low-Level-Interrupt ist noch etwas anders. Da das Interrupt-Flag sofort
erneut gesetzt, solange der Low-Pegel anliegt. Ich nutze den
LL-Interrupt daher nur zum Aufwecken des AVRs aus dem Power-Down-Sleep.
Dazu deaktiviere ich den LL-Int sofort nach Aufruf der ISR und schalte
den Sleep-Mode auf Idle zurück. Dann werden die Taster im Timer-Int
entprellt.

Meine Ausführungen beziehen sich auf das direkte Ansprechen der
Hardware mit Assembler. Ein AVR kann nur Maschinensprache, auch C-Code
wird letztendlich in Maschinencode übersetzt, der 1:1 ASM entspricht.

...

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.