-
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. ;-)
-
das hab ich jetzt nicht ganz verstanden. was braucht ein neues Gehäuse? Der Decoder? Der kostet 15ct + 5ct Sockel + 6cm^2 Platine. Das Problem ist nicht dieses Tastenfeld mit von-mir-aus 8 benötigten Pins, sondern alles in allem. Für jede Weiche brache ich 2 Ausgänge, für die LED-Statusanzeige nochmals jeweils 2. Bei 25 Weichen sind das schon 100 Ausgänge (Zahlen nur als Rechenbeispiel). da hilft dann auch kein Multicore.
Ich sag auch nicht, dass ich die beste Lösung habe, ist halt eine.
grüße
-
Nichts gegen die Lösung, erlaube nur, dass ich ein solches Projekt "integral" betrachte, wegen mir auch transgalaktisch oder über den Wolken schwebend. Jede Stunde kostet Zeit und Zeit ist irgendwo Geld, auch wenn man einem Hobby nachgeht. Und es ist eben einfach schön, wenn man alles mit einem Werkzeug, mit einer Systematik erschlagen kann. Das erlauben die modernen Mikrocontroller sehr weitgehend. Am Ende steht aber doch irgendwo ein Stecker, ein Schalter, ein Magnet oder sonst was. Mit verteilten Prozessoren arbeiten ist eine sehr interessante Sache, die sozusagen auf Augenhöhe mit den Forschern von Begeisterten betrieben werden kann, denn die Forschung ist auch noch nicht so richtig durch. So wie früher die Radioamateure den Rundfunk beflügelt hatten.
-
Hallo ErNa,
sag uns doch mal, was du mit dem Propeller schon gemacht hast. Es ist doch nicht alles auf das Ergebnis ausgerichtet. Wenn du so genau auf die Zeit achten würdest, hättest du einiges wohl gar nicht gemacht, wegrationalisiert. Das wichtigste ist doch, dass man Probleme löst. Das macht doch Freude. Dich lockt der Multicore. Mich auch, aber momentan geht es mir nur um die Steuerung. Warum soll man mit Assembler programmieren, wenn man doch mit einer hohen Sprache effizienter sein kann? Ich glaube, gerade für Mikrocontroller im (gemäßigten)Hobbybereich ist das ideal, weil man damit doch tiefer drin steckt. Dich begeistert der Propeller ja auch gerade deshalb, weil du den Ablauf selbst bestimmen kannst und die Cogs verwaltest, und nicht weil du einfach nur weißt, dass 8 Stück zusammenarbeiten.
Lange Rede kurzer Sinn: Am Schluß muss es funktionieren und darf nicht frustrieren. Ich glaube, dass der AtMega dafür geeignet ist. Ob ich den einen oder anderen Controller nehme, ist letztlich nur eine Entscheidung, die zwar Konsequenzen hat, aber weder positive noch negative.
-
Erfahrung ist durch nichts zu ersetzen außer durch Erfahrung. Ich habe meinen erste 8080 noch mit 1000 DM bezahlt, und war stolz wie ein Wutz mit drei Ohren, dass ich den Hex-code eintippen konnte in den Monitor, das war so was wie das Bios.
Dann habe ich mit z80 und einer selbst gebauten Interruptkarte mehrere Messwerte erfasst, zwei Bildschirme bearbeitet und auf Disketten die Daten physisch weggeschrieben auf Spur und Sektor. Der Witz war: das z80 programm hatte nur interruptroutinen, kein "Hauptprogramm". Wenn eine Routine eine andere starten wollte, hat sie eine über einen Multiplexer ein Signal ausgegeben, das von einen Demultiplexer wieder eingelesen wurde. Und dann kommt MSDos und man erzählt den Leuten, ein Programmaufruf über eine bestimmte Adresse wäre ein Softwareinterrupt!
Dann gab es einen Transputer mit OCCAM als Programmiersprache mit Sprachelementen zur Synchronisation paralleler Prozesse. Das hat man dann auch wieder mit C kaputtprogrammiert, indem man Sockets machen musste für Funktionen, die eigentlich in der originalen Sprache elementar waren! Ich bin einfach der Meinung, dass es sehr viel Blendwerk gibt und dass dieses die eigentlichen Prinzipien einer guten Soft- und Hardware verdeckt. Und der Propeller ist hier eine Offenbarung, auch wenn er Schwächen hat. Vom Standpunkt der "Alten" ist eigentlich jeder Controller eine Offenbarung, denn zum Preis einer Schachtel Zigaretten bekommt man etwas, für das man früher eine Urlaubsreise einsetzten musste. Ok, genug gejammert! :-({|= :-b :wink:
-
Sodele, jetzt bin ich einen Schritt weiter! Nach einigen Unwegbarkeiten funktioniert die Tastenfeldabfrage einigermaßen, bis jetzt kann ich nur unterschiedliche Tasten nacheinander Drücken und manchmal 'rutscht' ein falscher Wert mit rein. Ein LCDisplay hab ich auch zum Laufen gekriegt! Manche Fehler, die ich gemacht hab, waren echt ärgerlich! Und weitere folgen noch...
-
Ich möchte eine größere Menge Binärwerte in den Programmspeicher schreiben, gibt es dafür eine einfache Möglichkeit? Bis jetzt öffne ich die hex-Datei mit Ponyprog, speichere sie binär ab, und setze dann mit Hilfe eines kleinen Programms meine Binärwerte an das Ende des Programmcodes. Da müsste es doch eine [edit:] einfachere Möglichkeit geben!?