www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik while_keypressed mit avr assembler...(at tiny 2313) ??


Autor: Tilman W. (tilman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schönen guten Abend... Für den Experten womöglich ein eher einfaches
Problem, für mich im Moment eine harte Nuss: Wie kann ich mit Assembler
eine Funktion hinbekommen, die eine LED solange leuchten lässt, wie eine
entsprechende Taste gedrückt ist...und zwar über UART ? Im Moment habe
ich folgenden Code:

.include        "tn2313def.inc"

    USART_Init:
  ;Set baud rate
  ldi  r16,4000000/(9600*16)-1 ;set baud rate
  out UBRRL,r16
  ;Enable receiver & transmitter
  ldi r16,(1<<RXEN)|(1<<TXEN)
  out UCSRB, r16
  ;Set frame format: 8 data, 2 stop bits
  ldi r16, (1<<USBS)|(3<<UCSZ0)
  out UCSRC, r16

serin:  sbis ucsra,7
        rjmp serin

  in r16,udr
  out DDRB,r16
  rjmp serin

Bei Tastendruck (am Laptop-mit Hyperterminal)werden die entsprechenden
LEDs aktiviert...ok, was aber muss ich tun, damit bei loslassen der
Taste wieder alle ausgehen...ich kriegs nicht hin...
Danke & Gruss, Tilman

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich würde es so lösen, du wislt ja solange eine Taste gedrückt wird
das etwas passiert.

Dan machs so: Merk dir in einer Variablen welche Taste gedrück ist,
sagen wir mal r18
in r16 ist deine "neue gedrückte Taste"

dann einfach:

cp r18, r16 ;Prüfen ob beide Gleich sind
bneq Ledaus ;Wenn ungelich wurde die Taste losgelassen oder eine andere
gedrückt
(Hier Code um die benötigte LED anzuschalten)
jmp serin
Ledaus:
(Code um benötigte LED anzuschalten)
jmp serin

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vor dem lezten jmp serin, natürlich noch ein
mov r18, r16 ;Die neue Taste in r18 für erneuten durchlauf

Autor: Mario Richter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich glaube, er will die LED bereits dann ausschalten, wenn man eine
Taste auch nur loslässt. Oder ?

Das ist nicht ganz so einfach, weil das Terminal ja nicht mitteilt,
wann eine Taste losgelassen wird, sondern nur, wenn eine gedrückt wird.
Einzige Möglichkeit, die ich sehe, ist über die Wiederholrate: wenn man
länger auf einer Taste bleibt, wird das Zeichen ja nach kurzer Zeit
mehrfach ausgegeben. Man könnte also eine Abfrage machen, die nach
einiger Zeit ohne erneutes Eintreffen des Zeichens über die USART die
LED wieder ausschaltet. Nachteil: deutliche Verzögerung.

Einfacher wäre es, eine Taste zum Einschalten und eine andere zum
Ausschalten der LED zu benutzen.

(Oder natürlich du nimmst nicht das Terminal, sondern schreibst dir ein
Windows-Programm, dass beim Drücken und Loslassen der Taste
entsprechende Nachrichten lossendet ...)

Grüße, Mario

Autor: thkais (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder man macht eine "Toggle"-Funktion. Einmal drücken = an, nochmal
drücken = aus usw.
Oder eine alte PC-Tastatur direkt an den µC anschließen, die teilt über
die Codes nämlich mit, wann die Taste gedrückt und wann sie wieder
losgelassen wird.

Autor: Tilman W. (tilman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute !
Vielen Dank für Eure Antworten. Nun ja, Laeubis Lösung habe ich
ausprobiert. Die Folge war zwar prinzipiell richtig - die LEDs gehen
bei Tastendruck an - und dann wieder aus, wenn ich die Taste loslasse,
jedoch flackern sie wie verrückt...
Marios...ja, die Idee ist Gold, ein eigenes Programm (anstelle von
Hyperterminal) zu schreiben...in C# etwa gibts ja fertige Befehle wie
while_KeyPressed...und sobald man dann loslässt wird ein Befehl
geschickt, der alle LEDs wieder ausschaltet. Trotzdem...das kann doch
nicht sein, dass wir das nicht auch so hinkriegen...
Ich habe jetzt mal folgendes gemacht: Den internen Oszi auf 8 MHz
hochgestellt...mit folgendem Code funktionierts zwar, aber auch nur mit
einer Delay-Funktion, so dass zwischen Ein- und Ausschalten so ca. eine
halbe Sekunde Zeit ist. Ich will aber, dass das Zack-zack geht... Taste
gedrück: LED an...Taste halten...LED bleibt an...Taste loslassen...LED
aus...


.include        "tn2313def.inc"

    USART_Init:
  ;Set baud rate
  ldi  r16,8000000/(9600*16)-1 ;set baud rate
  out UBRRL,r16
  ;Enable receiver & transmitter
  ldi r16,(1<<RXEN)|(1<<TXEN)
  out UCSRB, r16
  ;Set frame format: 8 data, 2 stop bits
  ldi r16, (1<<USBS)|(3<<UCSZ0)
  out UCSRC, r16
    sbi ucsrb,rxcie

default:  ldi r16,0b10101010
      out DDRB,r16
      sbis ucsra,7    ;Wenn Daten im RX Buffer, dann weiter zu serin2
      rjmp default
                   ;if UART Receive Complete bit is clear
serin2:  in r16,udr
    out DDRB,r16
    cbi ucsra,7
    rcall dly
    sbis ucsra,7
    rjmp default
    rjmp serin2


dly:
dec r17
brne dly
dec r18
brne dly
ret



Irgendwie muss das gehen !
Das Bit7 von UCSRA wird halt nur gesetzt, wenn auch ein ganzes Zeichen
im RCX Register angekommen ist und dann wird es erst wieder gesetzt,
wenn ein neues Zeichen ankommt...irgendwie ist mir das selbst noch
nicht genau klar...

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich will aber, dass das Zack-zack geht... Taste
> gedrück: LED an...Taste halten...LED bleibt an...Taste
> loslassen...LED aus...

....

> Irgendwie muss das gehen !

Klar geht das irgendwie, aber halt nicht mit einem normalen
Terminalprogramm, da das dir eben nicht mitteilt, wann eine Taste
losgelassen wurde.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
klar geht das Zackzack... mach einfach nen Timerint und wenn innerhalb
von 100ms keien gleicher Buchstabe angekomemn ist.. -> LED aus

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, die erste Wiederholung wird normalerweise um mehr als 100ms
verzögert, und die Verzögerungszeiten können konfiguriert werden. Wenn
da einer 150ms eingestellt hat, geht's nicht mehr.
Außerdem ist es natürlich Definitionssache, ob das als "Zackzack"
bezeichnet werden kann. Zum Testen von Reaktionszeiten wäre es wohl
inakzeptabel.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
klar dan nimmt ma halt 200ms oder sowas in der Art, aber das sidn Zeiten
die man nicht durch Schnelles drücken machen kann, sonder nur wenn man
gedrückt läßt,
 und bei nem Reaktiosntest nimmt man für gewöhnlich ein Toggelmodus,
Taster 1 Startet, es kommt das Signal, am drückt Taster 2 udn hat die
Reaktiosnzeit.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die über das Betriebssystem ausgewertete Computertastatur ist für diesen
Zweck ungeeignet. Denn zwischen dem ersten Zeichen und der ersten
Wiederholung ist eine Pause, erst danach folgen die Zeichen direkt
hintereinander.

...

Autor: Tilman W. (tilman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich schreibe gerade ein eigenes Terminalprogramm in C#. Müsste heute
abend oder so fertig sein. Ich verwette 100 Ampere-Stunden, dass es
dann geht !
Grüße, Tilman

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber sicher ist das machbar, nur nicht mit einem
Standard-Terminal-Programm. In QBASIC habe ich das vor Jahren schon
gemacht. Ist z.B. Bestandteil des Simulationsmodus der Steuerung für
die ATV-Relaisstation DB0WTB.

In C/C++ kann ich es aber nicht, dazu ist mir C zu fremd...
Viel Erfolg...

Bit- & Bytebruch...
...HanneS...

Autor: Tilman W. (tilman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem mit Hyperterminal ist, wie Du es ja genau gesagt hast, dass
das Betriebssystem eine gedrückte Taste nicht immer als gedrückt
identifiziert, sondern zwischen dem ersten Drücken und einem
permanenten Signal zuerst noch eine Pause von ca. 250ms setzt.
Vielleicht kann man dieses ja irgendwo ändern.
In C gibts es die Methoden, bzw. Funktionen "KeyPress", "KeyDown"
und "KeyUp". Somit kann jeder Status immer eindeutig erkannt und
entsprechend verarbeitet werden. Damit funktioniert es jetzt !
Danke für alle Tips und: Gruuß !
Tilman

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Völlig korrekt. Aber diese Pause ist norwendig, ohne sie könnte man
keine Texte vernünftig eintippen, denn die Tasten würden dann prellen
und jedes Zeichen mehrfach eingeben...

...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.