-
Früher gab es mal einen Witz: Der Professor gibt den Studenten auf, das Telefonbuch auswendig zu lernen. Fragen die Studenten: "bis wann", waren's Mediziner, fragen sie "wozu", waren es Physiker.
Zwischenzeitlich muss man diesen Witz erklären.
Der Erfolg der Prozessoren liegt natürlich darin, dass die Lehre nicht mehr frei ist, sondern auf die Wirtschaft ausgerichtet. Aber man muss nicht alles mit und mit sich machen lassen.
-
@ Felix
zur Auslösung des Interrupt müsste die Matrix als ganzes betrachtet werden (Alle Matrixeingänge high, Ausgänge zusammenfassen zum Int) und sobald der Interrupt ausgelöst wird Zeilen- oder Spaltenweise, dadurch fällt der Pegel am Interrupteingang wieder. Sobald die ISR durchlaufen ist, würde diese wieder aufgerufen, da ich ja länger (als die ISR braucht) auf die Taste drücke. es wäre bestimmt ein gewisser (Löt-) Aufwand, den Interrupt weiterhin hoch zu halten. Die Timermethode ist wohl am geschicktesten.
PS:Teile hab ich bestellt, kann bald losgehen... O:)
-
Stimmt glaub doch nicht, was ich gesagt habe. Wenn der Int-Eingang wieder auf high ist, bevor die ISR zuende ist, löst ja der Interrupt nicht mehr aus.
-
Es ist ja nicht so, als hätte ich nicht selbst schon Interrupts gequält. Und dann beißen die halt zurück. Und so sieht eine Problemlösung in SPIN aus, die mit 8 Pins 16 Tasten und Dioden bedient. Das ist eben genau der Punkt: eine Stunde Lebenszeit ist nicht mit Geld aufzuwiegen. Und wenn dann mal so nebenbei noch ein VGA-Monitor, eine Tastatur und eine Maus, inklusive Kopfhöhrer und Mikrofon von einem Chip gemanaged wird, dann ist das eben mehr wert als 3 Euro. Man kauft sich ja ein Auto auch nicht zum Fahren, sondern als zweite Haut.
Code:
''*****************************
''* IOMatrix 0.0 *
''* (C) 2007 Nascma GmbH *
''*****************************
{{ Dieses Programm bearbeitet 16 Taster und 16 Leuchtdioden in einer Matrixschaltung.
Es werden 4+4 Pins benötigt zum Treiben von Reihen und Kolonnen. Die Dioden sind von
den Reihen zu den Kolonnen geschaltet, die Schalter sind mit Widerständen 1 K in Serie
parallel zu den Dioden geschaltet. Die Reihen sind mit Widerständen 10 K nach Masse
gelegt.
Die beiden Gruppen der Pins müssen zu je 4 aufeinanderfolgen.
Die Eingänge sind entprellt.
Die Schalter werden gescannt und das Ergebnis erhöht (gedrückt) oder erniedrigt (offen)
die Variable Button (Intervallgrenzen 0 - Entprellwert). Erreicht die Variable einen
Grenzwert, wird geprüft, ob sich sich verändert hat (ButtonStatus). Falls ja, wird der
Status aktualisiert und ein Trigger ausgelöst (ButtonTrigger). Der Trigger wird
durch die verarbeitende Routine quittiert.
Die Ausgänge repräsentieren den Wert der Variablen LEDStatus.
}}
CON
_clkmode = xtal1+pll16x
_clkfreq = 80_000_000
RowD = 0
RowC = 1
RowB = 2
RowA = 3
Col4 = 4
Col3 = 5
Col2 = 6
Col1 = 7
Deboun = 2 ' Zählerstand fürs Entprellen
VAR
long vga_status 'status: off/visible/invisible read-only (21 contiguous longs)
byte Button[16]
byte ButSta[16]
byte ButTog[16]
byte LEDSta[16]
OBJ
vga : "vga"
PUB begin | Index, RowIdx, ColIdx
bytefill (@Button, 0, 64)
dira[Col4..Col1]~~ 'Spalten sind immer Ausgänge
outa[Col4..Col1]~~ 'Spalten sind immer Ausgänge
' dira[8]~~ 'Trigger nur zum testen!
repeat ' Eine Schleife auf ewig
' outa[8] := 1 nur zum Testen, Oszi Trigger
' waitcnt(clkfreq/5000 + cnt) '1 ms warte
' outa[8] := 0
Index := 0 ' Index geht von 0 bis 15
repeat RowIdx from RowA to RowD ' Für die 4 Zeilen, = PinNummer
repeat ColIdx from Col1 to Col4 ' Für die 4 Spalten, = PinNummer
' Taster testen
dira[ColIdx]~~
outa[ColIdx]~~ ' Ausgang setzen
dira[RowIdx]~ ' Die Reihe wird gelesen
' waitcnt(400 + cnt) 'Minimales Warten
if ina [RowIdx] ' Schalter ist geschlossen!
Button[Index] := 0 #> Button[Index] - 1
' LEDSta[Index] := LEDSta[Index] ^ %1
else ' Schalter ist offen!
Button[Index] := Deboun <# Button[Index] + 1
case Button[Index]
0:
if ButSta[Index] == 1
ButTog [Index] := 1
ButSta[Index] := 0
Deboun:
if ButSta[Index] == 0
ButTog [Index] := 1
ButSta[Index] := 1
' LEDStatus togglen
if ButTog[Index] == 1
ButTog[Index] := 0
if ButSta[Index]
LEDSta[Index] := LEDSta[Index] ^ %1
' LED schalten
dira[RowIdx]~~
outa[ColIdx] := LEDSta[Index] 'Ausgang setzen LOW
outa[RowIdx] := !LEDSta[Index]
waitcnt(clkfreq/1000 + cnt) '1 ms warte
outa[RowIdx] := 0
dira[ColIdx]~
Index ++
-
Der Code ist natürlich etwas tricky, da die Pins als Eingänge und Ausgänge genutzt werden. Aber doch noch ganz überschaubar.
-
ja, das ist eine gute Idee. Wenn ich das Programm richtig verstanden habe, werden die Taster in Sperrrichtung der LEDs abgefragt. Allerdings sind 8 Pins ja auch nicht wenig. Für mein Matrix(2x8)-Tastenfeld verwende ich einen 3zu8 Decoder, dann brauche ich noch 2 Eingänge, insgesamt also 5 Pins. Mir scheint, dass sich manche (Mikrocontrollerprogger) nicht recht an Hardware "trauen" und alles über Softwarelösungen machen möchten. Ich kann bei meinem Projekt nicht so verschwenderisch sein (mit den I/O-Pins).
Die Zeit seh ich nicht so als Problem (auch wenn ich gerade wenig davon habe), der Weg ist schließlich das Ziel. Und jedes Problem hilft einem, ein späteres viell. von vornherein zu umgehen.
Gibt es auch schon ein On-Controller-Compiler, wenn du schon Monitor, Maus, Tastatur... hast. *späßle
-
@ErNa
Das Problem lässt sich nicht nur mit Spin, sondern mit so ziemlich jeder Programmiersprache schnell und einfach lösen...
jetzt mal abgesehen von Sprachen wie Whitespace oder Brainfuck, aber damit ist nichtmal hello world einfach ;)
@Din1234
Es hindert dich Niemand daran den verwendeten Interrupt in der ISR (also nachdem die erste Flanke erkannt wurde) abzuschalten, und ihn erst in der Timer ISR (nach der vollständigen Auswertung inkl. Entprellung) wieder zu aktivieren.
Es gibt immer mehrere Wege zum Ziel
-
Natürlich. Aber es gibt so einen schönen Effekt: das Programm läuft full speed und immer, also keine ISR und damit auch keine Timingprobleme. Das ist der Vorteil von Multicore
-
@ErNa
Ich glaub wir drehen uns hier im Kreis
-
klar, das ist eben der Unterschied zu Multitasking oder Interrupt, da ist das eine Sünde, hier Vergnügen. PS: Wenn man Pins zählt, dann muss man sich klarmachen, dass in Mux natürlich ein zweites Gehäuse ist, und wenn man schon rechnet, dann richtig. Denn ein zweites Gehäuse ist recht viel teurer. ;-)