Hallo Leute,
ich habe vor in einer LED Matrix über einen Taster mehrere Programme zu
steuern, sodass bei nedem Taster betätigen das nächte Programm
aufgerufen wird. Ich arbeite mit einem µC der 8051-Familie.
Jetzt habe ich folgendes Problem, wenn der Controller momentan dabei
ist, ein "Bild" in der Matrix dazustellen, kann er ja nicht gleichzeitig
die Eingabe des Tasters kontrollieren (oder doch)?
Jetzt wollte ich Fragen, wie das am besten realisieren kann.
Hat jemand ein paar gute Ideen?
Hier der code: Währen er LED1 Darstellt, soll die Taster Eingabe
kontrolliert werden, sodass man damit auch mitten im PRogramm von LED1,
das Programm LED2(noch nicht vorhanden)
ansteuern kann.
Hey,
Danke für die Antwort,
aber genau auf die Antwort habe ich nicht gehofft. Habe es leider
vergessen zu schreiben. So geht es ist mir klar, aber es ist ja keine
schöne Lösung und ich hoffe man kann es auhc irgendwie anders machen.
Lg Jonas
Socke schrieb:> Jetzt habe ich folgendes Problem, wenn der Controller momentan dabei> ist, ein "Bild" in der Matrix dazustellen, kann er ja nicht gleichzeitig> die Eingabe des Tasters kontrollieren (oder doch)?
Klar: das was du in "Warte" machst, ist vergeudete Rechenzeit. Mach doch
statt zu warten eine Tastenabfrage. Dann kannst du während eines
Wartezyklus die Taste zigtausendmal abfragen. Und dann ein Flag setzen
und sofort zurückspringen in das "Hauptprogramm", und dort dann auf
dieses Flag reagieren...
Sinnvollerweise machst du dir aber mal besser Gedanken zur Programmieren
in Schleifen und Zustandsautomaten. Das hört sich kompliziert an, ist
aber der einzig sinnvolle Weg, kompliziertere Programme aufzusetzen. In
deinem Fall ginge das etwa so:
Eine Hauptschleife wird mit maximaler Geschwindigkeit durchlaufen und
fragt die Taste ab. Wenn ein bestoimmte Zeit erreicht ist, wird das
nächste Bitmuster dargestellt und weiter gehts in der Hauptschleife:
Da Dir etwas Grundlagenwissen fehlt schau Dir mal das Thema Timer an.
Damit kannst Du soetwas unproblematisch lösen und hast zusätzlich nicht
unnötig Zeit in Deinen Delays verschwendet.
PS: Im Timer nur den Tastereingang abfragen und wenn gedrückt wurde
einfach ein Flag setzten welches Du in Deiner Main verarbeitest. Siehe
hierzu auch Tastenentprellung mit Timer.
http://www.mikrocontroller.net/articles/8051_Timer_0/1
Hallo,
Danke für die ganzen Antworten, ich werde mich am Wochende dann nochmal
dran setzten.
Ich sollte mich glaube ich sowieso mal etwas mehr mit den ganzen Flags
auseinander setzen, so kann man sicherlich einiges Einfacher machen auf
dauer.
Mit dem Timer habe ich mich bis jetzt auch noch nicht beschäftigt, werde
es zu diesem Thema dann mal machen.
Im Prinzip wollte ich nur erstmal wissen, ob es überhaupt so möglich
ist, wie ich mir das gedacht habe.
Das Programm war auch erstmal nur ein Beispiel, aber ihr habt mir schon
sehr geholfen. Mit den Stichworten werde ich wohl was hinbekommen, ein
bisschen möchte man ja auch selber machen, sonst fehlt ja der
Lerneffekt.
Vielen Dank nochmal an alle.
Lg Socke
Du kannst das auch ohne Timer machen, allerdings musst Du dann Deine
Warteschleifen anders gestallten. z.B. könntest Du bei jedem Main
Durchlauf eine Variable um 1 erhöhen und z.B. die entsprechende LED bei
Zählerstand X ein oder ausschalten. Allerdings hast Du wenn Du das so
machen würdest keine feste Zeit da die Mainschleife ja dynamisch Zeit
braucht. Wenn es allerdings Zeitunkritisch ist, Sprich egal ist ob es
nun 400ms oder 500ms sind dann könnte man das über den Zähler machen :)
Aber Grundsätzlich sollte man an so "unsinnigen" Code garnicht erst
denken da er schlicht weg mehr als Schlecht wäre.
mfg xerox
Stefan Wagner schrieb:> Da Dir etwas Grundlagenwissen fehlt schau Dir mal das Thema Timer> an.> Damit kannst Du soetwas unproblematisch lösen und hast zusätzlich nicht> unnötig Zeit in Deinen Delays verschwendet.>> PS: Im Timer nur den Tastereingang abfragen und wenn gedrückt wurde> einfach ein Flag setzten welches Du in Deiner Main verarbeitest. Siehe> hierzu auch Tastenentprellung mit Timer.>> http://www.mikrocontroller.net/articles/8051_Timer_0/1
Leider sind in dem Link die meisten Beispiele nur in C dargestellt, da
ich aber assembler als anfänger sehr sinnvoll empfinde, wird es die
Sache nicht erleichtern, dennoch werde ich es mal versuchen, bei
konkreten Fragen melde ich mich einfach mal.
Vielen Dank
Lg Socke
Socke schrieb:> da> ich aber assembler als anfänger sehr sinnvoll empfinde
Da bin ich und viele andere aber anderer Meinung.
Das führt aber dann wieder zur Diskussion über die "bessere"
Programmiersprache, also lassen wir das.
Die Lösung für dein Problem nennt sich Interrupt.
Also deine externe Beschaltung so aufbauen das jeder Taster einen
Interrupt auslösen kann. Entweder jeder einen eigene ( falls du genug
Interrupteingänge hast) oder die über eine "wired OR" zusammengefasst
auf einen Interrupt Pin.
Damit kannst du Interrupt jeweils deinen Tastendruck erkennnen.
Ralph schrieb:> Die Lösung für dein Problem nennt sich Interrupt.> Also deine externe Beschaltung so aufbauen das jeder Taster einen> Interrupt auslösen kann.
Das ist Murksprogrammierung. Einen Interrupt für einen stinknormalen
Taster brauche ich nur, wenn ich den Controller schlafen lege. In einem
normalen Programm sollte man Interrupts für den normalen Programmablauf
vermeiden wie der Teufel das Weihwasser. Denn ein Interrupt ist genau
das, was der Name vermittelt: eine Unterbrechung (also auch Störung) des
normalen Programmablaufs. Mit nur einer halben Minute Nachdenken fallen
mir da gleich ein paar potentielle Probleme ein.
Für alle normalen Fälle wurde das Stichwort schon genannt:
Zustandsautomat, Finite State Machine FSM, Schrittkette usw.
Nur so lassen sich wirklich überschaubare, wartbare und erweiterbare
Programme abbilden. Denn dann ist jedesmal der selbe Ablauf:
1. Ports und Daten einlesen
2. Neue Zustände und Ergebnisse berechnen
3. Ausgänge schreiben
4. weiter bei 1.
Und das Ganze so oft wie möglich pro Sekunde.
Das ist das SPS-Schema, das unbestritten weltweit problemlos
funktioniert. Und die einzig interessante Zahl bei der SPS ist die
Zykluszeit.
Lothar Miller schrieb:> 1. Ports und Daten einlesen> 2. Neue Zustände und Ergebnisse berechnen> 3. Ausgänge schreiben> 4. weiter bei 1.> Und das Ganze so oft wie möglich pro Sekunde.
nunja, es ist eben nicht alles eine SPS.
Eine SPS kommt in Probleme mit Events die innerhalb der Zykluszeit
stattfinden.
Oder im besonderen wenn innerhalb der Zykluszeit ein Event mehrfach
auftritt.
Sowas lässt sich nur mit zusätzlichen Hardwarepuffern abfangen, oder
halt über Eventtrigger ( Interrupt)
Das Grundschema 1 bis 4 passt schon, dazu ist es zu generisch.
Aber gleich alle Interrupts zu verteufeln ist auch nicht der Sinnvolle
weg.
Wenn das Hauptprogramm durch Interrupts in Probleme kommt, ist da in der
grundsätzlichen Auslegung aber etwas sehr schief gegangen.
Ist klar wenn die Zykluszeit zb 1msec ist und die Abarbeitung bereits
998 µsec benötigt ist da keine Luft für Interrupt. Sollte mir allerdings
mal jemand ein solches System mit dieser Auslegung verkaufen wollen darf
er gleich wieder nach Hause gehen, mit seinem System.
Ich würde für mich selbst das ganze über eine Timebase Interrupt lösen
in dem alle Eingänge gelesen und gepuffert werden.
Aber das möchte ich einem Anfänger in Assembler nun nicht wirklich
raten.
Er wird mit Assembler an sich schon genug beschäftigt sein um sich dazu
auch noch über besonders elegante und wiederverwendbare Lösungen
Gedanken zu machen. Das kommt später.......
Socke schrieb:> Findet ihr C als anfänger sinnvoller?
Ja !!
Um die ganzen Details die einem der Compiler abnimmt kann man sich
später kümmern. Daraus wird dann Assembler.
Hallo
ich habe nochmal eine Frage, und zwar habe ich jetzt scho etwas mit den
Interupts herumgespielt.
Allerdings wollte ich jetzt mit dem gleichen Interrupt zwei Programme
nacheinander Starten. Sprich wird der Taster einmal gedrückt, startet
das erste rogramm, drückt man den Taster erneunt, startet das zweite
Programm.
Jedoch habe ich das Problem, dass das Programm direkt startet bzw, das
er direkt ohne betätigen des tasters den Interupt aufruft. Man kann ihn
jedoch nicht weiterschalten.
Hier mein code, hoffe ihr versteht mich:
Socke schrieb:> Man kann ihn jedoch nicht weiterschalten.
Das kann ja auch nicht gehen, denn Du verlässt die Interrupt-Routine ja
nicht und bleibst ewig in der Endlosschleife LED1 oder LED2.
Solange "reti" nicht ausgeführt wird, ist der Interrupt gesperrt und die
Interuptroutine mit der Tastenabfrage wird nicht mehr aufgerufen.
Ein Interrupt-Enable alleine hilft da aber auch nicht, weil sonst der
Stack überläuft (das "ret" von "reti" fehlt dann).
Gruß Dietrich
Du hadt recht st7mmt, dann klapptdas ja gar nicht so wie ich mir das
gedacht habe.
Aber wieso startet der Interrupt dann direkt, ohne tastereingabe?
Lg Socke
Socke schrieb:> Findet ihr C als anfänger sinnvoller?
Für den 8051 auf gar keinen Fall!
Den kann man so wundervoll in ASM programmieren. Er wurde sogar dafür
entwickelt.
Versuch mal den Timerinterrupt zu verstehen:
1 Timer initialisieren
2 Interrupts einschalten
3 Aufgabe A im Hauptprogramm erledigen
4 Aufgabe B im Timerinterrupt erledigen
Wenn Du Beispiele benötigst, sag bescheid.
Gruß
Jobst
Hi,
ja danke, aber ich würde ja gerne 10 Programme mit einem Taster
nacheinander aufrufen | also bei jedem Taster klick soll das nächste
kommen.
Und das dann egal, wann der Taster betätigt wird deswegen ja mit den
Interrupt.
Lg Socke
Socke schrieb:> Hi,>> ja danke, aber ich würde ja gerne 10 Programme mit einem Taster> nacheinander aufrufen | also bei jedem Taster klick soll das nächste> kommen.> Und das dann egal, wann der Taster betätigt wird deswegen ja mit den> Interrupt.>> Lg Socke
Das geht in Richtung Multitasking mit dem Taster als Trigger für den
Taskwechsel.
Dafür gibt es µC die aufgrund ihrer Architektur besser geeignet sind als
die kleinen 8Bitter.
Oder ist mit "Programme" nur ein unterschiedliches Blinkverhalten der
LED's gemeint ?
In dem Fall würde ich das anderes aufsetzen.
* eine 2 Dimensionale Tabelle aufsetzen
* pro Spalte ein Blinkprogramm
* pro Zeile eine LED Anweisung
Mit dem Programmablauf zeilenweise durch die Spalte laufen.
Bei Tastendruck die Spalte wechseln.
Aber das ganze ins Assembler? naja es geht aber muss man sich das
wirklich antun ?
Wenn man Autofahren lernt geht es auch nur um die Bedienung der Pedale,
Schalter, Lenkrad und so weiter.
Niemand wird in der Fahrschule lernen wie die Einspritzanlage
eingestellt werden muss damit man Losfahren kann.
Hey Ralph
gute Antwort, danke.
Wieder ein neues Thema jetzt muss ich mich wohl auch noch mit Tabellen
auseinander setzen
zur Zeit habe ich nur einen AT 89S8253 zur Verfügung .
Eventuell Werde ich mich auch mal in C einlesen. Man kann doch auch in C
fertige Assembler codes laden Oder?
Vielleicht bringt der Weihnachtsmann auch einen Arduino ;-)
Danke nochmal
Lg Socke
Was willst du bei dem Ding mit C?
Dein Interrupt macht nichts weiter, als in einem Register einen Wert zu
hinterlegen.
Und den wertet dein Hauptprogramm aus.
Wenn du anfängst, dann nimm nicht so einen Oldtimer. Geh gleich auf AVR.
Ich glaub, für deinen AT 89S8253 gibt es einen Pin-compatiblen Ersatz
von den AVR.
Michael_ schrieb:> Wenn du anfängst, dann nimm nicht so einen Oldtimer.
Die Schule bestimmt leider, was wir verwenden.
Also unten steht der neue code. Ich setzte jetzt jedes mal wenn bei
Tasterbetätigung mit dem Interrupt ein Register +1 und vergleiche es
dann in jedem Programm, jedoch funltioniert aus irgendeinem Grund auch
das nicht so ganz korrekt. Liegt es vielleicht daran, dass man den
Taster zu lange betätigt und er dann dierekt das Register +3 nimmt?
'Vielleicht findet ihr ja einen Fehler.
Werde mich in naher zukunft jedoch Trotzdem noch mit dem Timer Interrupt
und Tabellen auseinander setzten :)
Danke nochmal an Alle bis jetzt.
Socke schrieb:> Liegt es vielleicht daran, dass man den> Taster zu lange betätigt und er dann dierekt das Register +3 nimmt?
Das wird wohl eher das Tastenprellen sein.
Hier muss also noch eine Entprellen des Tasters dazukommen.
Das kann per hardware gemacht werden. ZB ein Tiefpass mit Schmitttrigger
zwischen Taster und µC Eingang.
Oder es kann per software gemacht werden.
Dazu gibt es aber auch schon genug Beiträge hier im Forum zum Nachlesen.
Das Problem tritt aber auch auf, wenn ich nur kurz die beiden Drähte
ajeinanderhalte, ohne Taster.
Also les ich mir das mit den Tasterprellen mal durch und sonst muss ich
das noch irgendwie auch anders lösen.
Danke
Lg Socke
Socke schrieb:> Das Problem tritt aber auch auf, wenn ich nur kurz die beiden Drähte> ajeinanderhalte, ohne Taster.
Das ist ja noch schlechter als ein Taster ...
Das prellt erst recht ... so richtig :-D
Gruß
Jobst
So ich habe mir jetzt mal das entprellen von peter danegger angeschaut
und versucht zu verstehen und umgeschrieben auf die passenden befehle
für meinen uC, jedoch nicht läuft da noch so einiges nicht rund. Er sagt
doch er hat es für 8051 geschrieben, aber wieso kann mein controller mit
den befehelen or and und eor oder com so gar nichts anfangen?
Vielleicht erschließt sich mir auch morgen der sinn des codes komplett
und ich kann ihn anders schreiben, so easy ist der ja gar nicht.
Hat jemand noch andere möglichkeiten, für die entprellung in assembler
bei den 8051ern?
Schönen abend noch
Lg Socke
Socke schrieb:> Die Schule bestimmt leider, was wir verwenden.
Dann lies dir die bereitgestellten Unterlagen durch oder du hast
geschlafen.
Socke schrieb:> zur Zeit habe ich nur einen AT 89S8253 zur Verfügung . Ich glaub, dafür gibt es
einen pinkompatiblen Ersatz als AVR.
Wenn du privat Interesse hast, dann mach damit weiter.
Naja, der 8051 wird häufig schlechter gemacht, als er ist. Sollte es
keinen triftigen Grund geben, die Architektur zu wechseln, kann man gut
dabei bleiben, immerhin ist er Industriestandard. Und es gibt sehr
viele, sehr unterschiedliche Derivate - vor allem von verschiedenen
Herstellern. Und es wird ihn in 30 Jahren auch noch geben.
Warum der TO davon weg bewegt werden soll ist mir nicht klar.
Gruß
Jobst
Socke schrieb:> Vielleicht erschließt sich mir auch morgen der sinn des codes komplett> und ich kann ihn anders schreibenBeitrag "Tasten entprellen Bulletproof.asm"Socke schrieb:> aber wieso kann mein controller mit> den befehelen or and und eor oder com so gar nichts anfangen?
Peter hat den Code für AVR geschrieben. Das Original ist vermutlich vom
8051