Archiv verlassen und diese Seite im Standarddesign anzeigen : Verbesserung!!!???!!!
Hi Leute.... :)
Hab mir mal ne 3*4 Tastatur an den µC (AT89C52) geklemmt und ein kleines Progi geschrieben. Da ich ziemlich neu auf diesem Gebiet bin ist mein Progi möglicherweise ziemlich primitiv. Würde mich echt freuen wenn ihr mir einige Verbesserungvorschläge machen würdet.
#include <AT89X52.H>
#include <STDIO.H>
sbit Led = P3^7; // Led zur Kontrolle
void wait(unsigned int msec) //Warteschleife
{
unsigned char i,j;
for(msec;msec!=0;msec--)
for(i=0;i<90;i++)
for(j=0;j<2;j++);
}
void main(void)
{
unsigned char tast;
while(1)
{
P2=0x7f; // LOW Aktiv
P2&=0x6f; // Abfrage der ersten Spalte (3,6,9,#)
tast=P2;
switch(tast) // Tastatur 3,6,9,#
{
case 0x6e: //3
Led=0;
wait(200);
Led=1;
wait(200);
break;
case 0x6d: //6
Led=0;
wait(500);
Led=1;
wait(500);
break;
case 0x6b: //9
Led=0;
wait(800);
Led=1;
wait(800);
break;
case 0x67: //#
Led=0;
wait(500);
Led=1;
wait(500);
break;
}
P2=0x7f; // LOW Aktiv
P2&=0x5f; // Abfrage der zweiten Spalte (2,5,8,0)
tast=P2;
switch(tast) // Tastatur 2,5,8,0
{
case 0x5e: //2
Led=0;
wait(200);
Led=1;
wait(200);
break;
case 0x5d: //5
Led=0;
wait(500);
Led=1;
wait(500);
break;
case 0x5b: //8
Led=0;
wait(800);
Led=1;
wait(800);
break;
case 0x57: //0
Led=0;
wait(500);
Led=1;
wait(500);
break;
}
P2=0x7f; // LOW Aktiv
P2&=0x3f; // Abfrage der dritten Spalte (1,4,7,*)
tast=P2;
switch(tast) // Tastatur 1,4,7,*
{
case 0x3e: //1
Led=0;
wait(200);
Led=1;
wait(200);
break;
case 0x3d: //4
Led=0;
wait(500);
Led=1;
wait(500);
break;
case 0x3b: //7
Led=0;
wait(800);
Led=1;
wait(800);
break;
case 0x37: //*
Led=0;
wait(500);
Led=1;
wait(500);
break;
}
} //while ende
} //main ende
Die LED routine habe ich nur zur Kontrolle eingeführt. Die wird später wieder gelöscht.
Eine Frage hätt ich da noch. Wie kann ich nun eigentlich nen CODE eingeben und überprüfen. z.B.: 2112
Wie könnte ich diesen eingeben und vor allem auf die Reihenfolge der eingegebenen Zahlen überprüfen??
Danke schon mal an dieser Stelle :)
Mfg Cri :)
Peter Dannegger
20.02.2006, 14:28
Hier mal meine Version:
http://home.tiscali.de/peterd/appl/soft/keyscan/index.htm
Peter
was ist das P3 |= BIN8(1,0,1,0,1,0,0,0); für ein Befehl?? woher nimmst du den?? Aus der types.h<TYPES.H>???
Kannst du mir vielleicht sagen wie ich den Code in der richtigen Reihenfolge einlesen und überprüfen kann?? Mir fällt einfach nichts ein!!!
mfg Cri
Hi,
der µC klimpert dauernd auf der Tastatur und verbraucht dadurch mehr Strom, der dann durch EMV Störungen abgestrahlt wird. intelligenter ist es, alle Spalten zu aktivieren und dann gelegentlich zu prüfen ob eine der Zeilen sich meldet. Das kann man sogar per Interrupt machen oder zumindest zwischendurch in einem Progr ammablauf, der irgendwas abarbeitet.
Wird festgestellt, dass etwas gedrückt wurde, so braucht man nur die Spalten abschalten und die gekitzelte Zeile aktivieren. Schon kann man durch Abfragen der Spalte die gedrückte Taste feststellen. Vor abfragen der Spalte noch kurz warten (10ms), dann prellt die Taste auch nicht mehr und es wird garantiert festgestellt, welche Taste gedrückt ist. Und selbst wenn nicht ist es egal, der Anwender soll die Taste ja drücken und nicht anhauchen. Wartet man jetzt, bis die Spalte aufhört zu "leuchten", dann wird ein einmaliger Tastendruck auch nur ein einziges mal gewertet.
Um eine Tastenkombo auszuwerten, legt man ein Array an, das genau so lang ist wie der Code. Jeder tastendruck wird da drin gespeichert. jedes mal, wenn eine Taste eingegeben wurde, wird diese im Array auf der nächsten freien Position gespeichert. Ist das Array voll, oder es dauert viel zu lange, wird das Array gelöscht damit der Code erneut eingetastet werden kann. Wenn das Array voll ist wird vor dem löschen natürlich geprüft, ob der Code korrekt ist. Bei wenigen Stellen reicht eine simple if kontruktion.
Gruß
Elmar
dein tipp hört sich echt gut an aber ich kann mir echt kein Program vorstellen indem ich ohne switch- bzw. if -Abfrage auskomme. Das mit dem Abfragen mach ich doch eigentlich. Die Zeilen sind auh "1" und die Spalten werden nacheinander auf "0" gesetzt. Wird nun eine Zeile gedrückt so wird der dementsrechende Port pin ebenfalls auf "0" gesetzt (P2&=0x6e; P2&=0x5f; P2&=0x3f) und somit habe ich die "Koordinaten" der gedrückten Taste.
Könntest du mir nur nen kleinen Denkanstoss geben. Ich kann mir einfach nicht vorstellen wie ich es anders bewerkstelligen soll. Schön wärs wenn ich das Program erheblich minimieren könnte da es doch ziemlich groß geworden ist.
Danke schon mal
Mfg Cri
Peter Dannegger
22.02.2006, 09:13
was ist das P3 |= BIN8(1,0,1,0,1,0,0,0); für ein Befehl?? woher nimmst du den?? Aus der types.h<types.h>???
Das ist ein Macro, welches die einzelnen Ziffern als Binärwert interpretiert (C kann keine Binärschreibweise).
</types.h>
Kannst du mir vielleicht sagen wie ich den Code in der richtigen Reihenfolge einlesen und überprüfen kann?? Mir fällt einfach nichts ein!!!
Was meinst du damit ?
Du kriegst einen Code beim Drücken und einen anderen beim Loslassen. Welchen Code Du für welche Taste kriegst, legst Du in der Tabelle keytab[] fest.
Peter
Hi,
dur brauchst gar nicht zyklisch abfragen. Einfach alle Spalten auf 0 setzen und alle Zeilen auf 1 setzen. Das bleibt dann permanent. Zwischendruch brauchst Du nur fragen, ob eine der Zeilen auf 0 gesetzt wurde. Wenn Du 8 Zeilen - also einen ganzen Port - hast, dann fragst Du einfach
if(Zeilen!=255)
Damit stellst Du fest, ob überhaupt eine Taste gedrückt wird, ohne dass Du ständig Leitungen setzen und löschen mußt. Der µC behält seine volle Rechenleistung bis auf gelegentliches abfragen ob was gedrückt wurde. Und dafür brauchst Du keine Leitungen schalten. Wenn was gedrückt wurde, so kennst Du ja schon die Zeile. Einfach diese Zeile aktivieren (durch invertieren des Wertes, den Du bereits abgefragt hast und setzen des portes mit dem invertierten Wert)
und dann gucken welche Spalte dabei raus kommt. So mußt Du nur drei mal was schalten um die gedrückte Taste abzufragen. Das spart Strom, rechenleistung und reduziert die EMV Störungen.
Gruß
Elmar
Peter Dannegger
22.02.2006, 11:22
Damit stellst Du fest, ob überhaupt eine Taste gedrückt wird, ohne dass Du ständig Leitungen setzen und löschen mußt. Der µC behält seine volle Rechenleistung bis auf gelegentliches abfragen ob was gedrückt wurde.
Die behält er auch so. Alle 50ms mal 12 Tasten abzufragen, kostet höchsten im Promillebereich CPU-Zeit.
Dafür ist das Programm einfacher und kürzer ohne diesen extra Code und es wird auch das Loslassen zuverlässig erkannt und entprellt.
Und eine Änderung des Stromverbrauchs wirst Du auch erst in der 5. Stelle nach dem Komma sehen, wenn überhaupt.
Wozu also extra Code verschwenden, wenn es nichts bringt ?
Peter
Hi,
das verschwendet keinen Code.
Spaltzen setzen
gelegentliches abfragen ob Anwender was gedrückt hat.
Wenn ja Unterprogramm aufrufen, dass >10ms fürs entprellen wartet und Zeile setzt und Spalte abfragt -> Taste bekannt.
Zeilen wieder löschen und Spalten setzen.
Gegebenenfalls normaler Programmablauf bis Taste wieder losgelassen wird, so wird jeder tastendruck auf bequeme Weise nur ein einziges mal abgefragt, mehrfachauswertung entfällt.
Mehr ist das nicht.
Man braucht noch nicht mal einen Timer fürs polling und behält VOLLE Timingkontrolle im normalen Programmablauf ohne ständig den Timerinterrupt sperren zu müssen weil es gerade Zeitkritisch wird. Die Abfrage ob überhaupt was gedrückt wurde streut man dann beliebig ins Programm, wo es Zeitunkritisch ist. Hauptsache das wird etwa jede halbe Sekunde gemacht.
Ich halte das für bequem, Pflegeleicht und effizient. Auch verhindert das, dass die leitungen der Tastatur ständig geschaltet werden und dadurch zu Sendern werden. Nur wenn man eine Taste drückt wird drei mal was pro Taste geschaltet. In EMV Empfindlicher Umgebung (Meßlabor, vielleicht sogar Tastatur auf empfindlichem Meßgerät) ist das äußerst hilfreich. Vor allem stört sich das Gerät nicht selber, weil es genau festlegt, wann abgefragt wird und das dann außerhalb einer Messung. Der tastendruck wird komplett ohne Störungen zu verursachen registriert. Welche taste das war natürlich erst durch dreimaliges Umschalten von Leitungen. Eine Not-Aus bzw. Abbruchtaste setzt man ja nicht in eine Matrix. Die hängt man separat, am besten an einen Interruptpin.
Gruß
Elmar
if(Zeilen!=255)
hi,
kannst auch noch die Leitungen 'ver_unden' und damit noch zusaetzlich auf e. IRQ-Eingang der cpu gehen. Nur alle halbe s abzufragen ist vielleicht nicht so komfortabel, mit IRQ "spurt" die Taste sofort ;)
P.S.:
was ich noch sagen wollte: der Titel diese Threads ist 'saumaessig', eigentlich sollte man darauf gar nicht antworten...
Hi,
er so viel "Dampf" braucht, nimmt eine PC Tastatur. Wer drückt denn schon schneller als eine halbe Sekunde auf ner Gummitastatur? Man kann ja die Zeit beliebig anpassen, aber eine halbe Sekunde langt doch völlig für mal eben was eintasten.
Wenn man viel und schnell eigeben muß, dann macht man die Testaufrufe eben öfters. In der Regel langt es aber vor jedem teilprogramm. Kann man wunderbar im "Round Robin" verfahren einflechten (Quasimultitasking). Wenn ein Programmteil länger läuft, kann man da mitten drin auch nach der Tastatur gucken.
Gruß
Elmar
Peter Dannegger
22.02.2006, 17:04
Wenn ja Unterprogramm aufrufen, dass >10ms fürs entprellen wartet
Genau das wäre tödlich für meine Programme.
Ich könnte es gar nicht ab, wenn riesige 10ms plötzlich alles stille steht, nur weil ne Taste gedrückt wird. Die 10ms kann man viel nutzbringender verwenden.
Dagegen ist es nicht schlimm, wenn immer regelmäßig die Tastenabfrage durchlaufen wird, denn das kostet nur wenige µs aber keine riesigen 10.000µs.
Man braucht noch nicht mal einen Timer fürs polling und behält VOLLE Timingkontrolle im normalen Programmablauf ohne ständig den Timerinterrupt sperren zu müssen weil es gerade Zeitkritisch wird.
Ne, von Interrupt sperren halte ich nun überhaupt nichts.
Wozu denn ?
Und nen Haupttimerinterrupt braucht man eh immer, da kann man doch die Tastenabfrage bequem mit reinstellen.
Die Abfrage ob überhaupt was gedrückt wurde streut man dann beliebig ins Programm
Davon halte ich auch nichts. Und von beliebig erst recht nichts, alles muß seinen richtigen Platz haben.
Ich mache es nur einmal und dann will ich mich nicht mehr drum kümmern müssen.
Auch verhindert das, dass die leitungen der Tastatur ständig geschaltet werden und dadurch zu Sendern werden.
Das könnte rein theoretisch ein Aspekt sein. Ist mir in der Praxis allerdings bisher nicht aufgefallen. Die Pins sind eigentlich sehr hochohmig und ich ziehe auch keine superlangen Strippen bis zu den Tasten.
Und gegen die Störungen der Multiplextakte der Anzeigen (LCD, LED, VFD) fallen sie eh weit hinten runter, die sind um Größenordnungen höher.
Peter
Hi,
man kann den Aufruf auch per Timer erledigen. Und das warten bedeutet ja nicht zwangsläufig NOP. Normalerweise rufe ich das mindestens 4x je Sekunde auf, wenn der Feststellt, dass eine taste gedrückt ist gibt es ein return und beim nächsten mal guckt er dann. Daher die halbe Sekunde maximum die zum Tastenerkennen benötigt wird.
Und da ich normalerweise Multitasking benutze (Round Robin), wenn Eingaben "Im Hintergrund" passieren sollen, so lässt sich das leicht einbauen. Nur in extremfällen, wo was intensiv und lange gemacht wird, dann stecke ich da Zwischenaufrufe rein. Das sind aber nur ausnahmen.
Gruß
Elmar
Powered by vBulletin® Version 4.1.12 Copyright ©2012 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.