while_keypressed mit avr assembler...(at tiny 2313) ??

OP #218354
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
Persönliche Seite #218355
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
Gast #218357
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
Gast #218358
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.
OP #218359
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...
Gast #218360
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.
Gast #218362
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.
#218366
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...
OP #218367
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren