mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Ablösende Tasten


Autor: Felix H. (felixh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich versuche gerade eine Steuerung in C zu schreiben und da sollen sich 
Tasten ablösen.
Das bekomme ich auch hin, jedoch schaffe ich es irgendwie nicht, dass, 
wenn man eine Taste drückt, die schon aktiv ist, diese ausgeht.

arrayindex=0+layer;
multiplexer(0x0C);
                                
I2C8574A(0x7A, out[arrayindex]);
multiplexer(0x08);
zs[arrayindex]=read(0x4B);
if(zs[arrayindex]==0xFE||zs[arrayindex]==0xFD||
   zs[arrayindex]==0xFB||zs[arrayindex]==0xF7||
   zs[arrayindex]==0xEF||zs[arrayindex]==0xDF||
   zs[arrayindex]==0xBF||zs[arrayindex]==0x7F)
  {
out[arrayindex]=zs[arrayindex];                                              
I2C8574A(0x7A, out[arrayindex]);                    
  }

Ich hab es mit allem möglichem versucht kam aber auf keinen grünen 
zweig.

Danke im Vorraus
Felix

: Verschoben durch Moderator
Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wenn du uns jetzt noch verrätst, was die 'sprechenden' Namen zs, 
arrayindex, bzw. die ganzen Hex-Konstanen da für eine Bedeutung haben, 
dann kann man dir vielleicht auch helfen.

Das eine 'ablösende Taste' ein Radio-Button ist, hat mir meine 
Kristallkugel verraten. Zuerst dachte ich, du verlierst die Tastenkappen 
auf deiner Tastatur :-)

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was hat das mit PC-Programmierung zu tun?

Karl Heinz: Deine Kristallkugel ist heute aber besonders gut drauf!

Autor: Felix H. (felixh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry ich dachte die Kristallkugel verrät dir alles :P

Ok da hab ich wohl schneller gehandelt als nachgedacht.
arrayindex=0+layer; //sagt aus, weche Stelle des Arrays angesprochen wird
multiplexer(0x0C); //Das ist eine Funktion, die über I²C einen Kanal in einem I²C Multiplexer freischaltet
                                
I2C8574A(0x7A, out[arrayindex]); //Der wert von out[arrayindex] wird in einen I/O Expander geschrieben (LEDs leuchten)
multiplexer(0x08); //Anderer Kanal in Multiplexer
zs[arrayindex]=read(0x4B); //Der Wert der Tasten wird ausgelesen und in den "Z"wischen"s"peicher geschrieben, da es unterschiedlichen Tastenkobinationen gibt
if(zs[arrayindex]==0xFE||zs[arrayindex]==0xFD||
   zs[arrayindex]==0xFB||zs[arrayindex]==0xF7||
   zs[arrayindex]==0xEF||zs[arrayindex]==0xDF||
   zs[arrayindex]==0xBF||zs[arrayindex]==0x7F) //Das stellt mit sicher, dass die Funktion nur ausgelöst wird wenn auch wirklich nur einen Taste gedrückt wird. Eine Tastenverriegelung
  {
out[arrayindex]=zs[arrayindex];//Der Zwischenspeicher wird in den richtigen Speicher geschrieben(Irgendwie umständlich merke ich)                                              
I2C8574A(0x7A, out[arrayindex]);//Der neue ausgangswert wird über I²C in den I/O Baustein geschrieben, die entsprechende LED leuchtet                    
  }

So das ganze ist ein Programmteil einer uC gesteuerten 16x16 
Audiokreuzschiene.

Autor: Felix H. (felixh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus t. Firefly schrieb:
> Was hat das mit PC-Programmierung zu tun?
>
> Karl Heinz: Deine Kristallkugel ist heute aber besonders gut drauf!

Es geht mir nicht um das was mein Programm bewirkt sondern darum wie ich 
es schaffe, dass

aus 10 und 10 nicht 10 sonder 00 wird und gleichzeitig aus 10 und 01 
nicht 11 sondern 01

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Felix H. schrieb:

> Es geht mir nicht um das was mein Programm bewirkt sondern darum wie ich
> es schaffe, dass
>
> aus 10 und 10 nicht 10 sonder 00 wird und gleichzeitig aus 10 und 01
> nicht 11 sondern 01

Um es kurz zu machen:
Hä?

(Sollen das irgendwelche Bits sein?

Das ist doch simpel:
  Du kriegst einen Wert herein, der dir sagt welches Bit durch den
  Tastendruck betroffen ist.
  Weiters hast du eine Variable, die dir sagt, welche Taste momentan
  gerade gedrückt ist (eine 1 bedeutet: gedrückt; 0: nicht gedrückt)

  Mit dem Tasten-Wert (1-Bit auf 1 für die gedrückte Taste) schaust
  du in der Variablen nach: Ist dort an der Position eine 1, dann
  setzt du die Variable komplett auf 0 - keine Taste gedrückt
  Ist dort aber eine 0, dann wird die Variable ganz einfach auf den
  Bitcodierten Wert der gedrückten Taste gesetzt (und damit eine
  möglicherweise früher gedrückte Taste gelöscht)

Also:
schaffst du es eine Variable, nenn sie TastenNr und nicht wieder irgend 
so einen nichtssagenden Namen, so zu bestücken, dass die Zahl da drinnen 
der Nummer einer gedrückten Taste entspricht?

Den Teil musst du selber hinkriegen, dass kann nicht mal meine 
Kristallkugel aus dem Codefetzen rauslesen (und meine Kugel ist gut in 
solchen Sachen!)

Dann
static unsigned char TasteGedrueckt;  // '1' Bit - taste gedrückt
                                      // '0' Bit - Taste nicht gedrückt
                                      // 8 Bits - 8 Tasten die sich gegenseitig auslösen

....


     TastenNr = ......    du bist drann

     if( TasteGedrueckt & ( 1 << TastenNr ) )    // war sie schon gedrückt?
       TasteGedrueckt = 0;
     else
       TasteGedrueckt = ( 1 << TastenNr );

und das wars dann schon.

Autor: Felix H. (felixh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Um es kurz zu machen:
> Hä?

ok ich versuche es nochmal irgendwie mit meinen wilden worten zu 
erklären


die tasten stelle ich durch [1](gedrückt) und [0](nicht gedrückt) dar.
es gibt 8 tasten.

und jetzt das beispiel
wenn ich den alten wert einfach dem neuen setzt wie im beispiel sieht es 
so aus
taster 1 ist aktiv, taste 4 wird gedrückt
vorher: [1][0][0][0][0][0][0][0]
eingabe:[0][0][0][1][0][0][0][0]
dann:   [0][0][0][1][0][0][0][0] //so soll es sein

taster 1 ist aktiv, taste 1 wird gedrückt
vorher: [1][0][0][0][0][0][0][0]
eingabe:[1][0][0][0][0][0][0][0]
dann:   [1][0][0][0][0][0][0][0] //so soll es nicht sein

wenn ich den alten wert aber durch xor mit dem neuen verbinde kommt das 
raus

taster 1 ist aktiv, taste 4 wird gedrückt
vorher: [1][0][0][0][0][0][0][0]
eingabe:[0][0][0][1][0][0][0][0]
dann:   [1][0][0][1][0][0][0][0]// so soll es nicht sein

taster 1 ist aktiv, taste 4 wird gedrückt
vorher: [1][0][0][0][0][0][0][0]
eingabe:[1][0][0][0][0][0][0][0]
dann:   [0][0][0][0][0][0][0][0]// so soll es sein

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Felix H. schrieb:

> taster 1 ist aktiv, taste 4 wird gedrückt
> vorher: [1][0][0][0][0][0][0][0]
> eingabe:[1][0][0][0][0][0][0][0]
> dann:   [0][0][0][0][0][0][0][0]// so soll es sein

Das heisst in einfache Worte gefasst:

1. Eine gedrückte Taste deaktiviert alle anderen
2. Wird die bereits gedrückte Taste ein zweites Mal gedrückt, 
deaktiviert sie sich auch selbst.

uint8_t tasten_checken (uint8_t port_value)
{
    static uint8_t state;

    if (state & port_value)
    {
       state = 0;
    }
    else
    {
       state = port_value;
    }
    return state;
}

Du übergibst an tasten_checken() einfach die acht bit von Deinen 8 
Tastern, du bekommst dann den neuen Taster-Status von der Funktion 
zurück.

Ist es das, was Du möchtest?

Gruß,

Frank

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würd ja ne zentrale Entprell- und Flankenerkennungsroutine im 
Timerinterrupt machen.
Und dann kannst Du die Drückereignisse ganz leicht auswerten, wie Du 
lustig bist.

Dazu gibt es schon langjährig bewährte Lösungen in der Codesammlung.
Tastenprobleme sind für mich ein Fremdwort.


Peter

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Ich würd ja ne zentrale Entprell- und Flankenerkennungsroutine im
> Timerinterrupt machen.

Warum sollte ich Tasten, die wie Radio-Buttons wirken sollen, 
entprellen?

Gruß,

Frank

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil bei Dir ein weiterer Tastendruck auf dieselbe Taste diese wieder 
ausschalten soll.

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus t. Firefly schrieb:
> Weil bei Dir ein weiterer Tastendruck auf dieselbe Taste diese wieder
> ausschalten soll.

Stimmt, an Regel 2 habe ich gar nicht mehr gedacht, nur an das 
klassische Röhrenradio :-)

Gruß,

Frank

Autor: Felix H. (felixh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Danke für die vielen Tips.
Habs jetzt hinbekommen und zusätzlich das Programm um 1kb verkleinert.
hab es so gemacht wie Frank beschrieben hat.
 
multiplexer(0x0C); //multiplexer...
bufferout=read(0x4B); //Tastenstatus wird in bufferout geschrieben

if(bufferout==0xFE||bufferout==0xFD||bufferout==0xFB||bufferout==0xF7||bufferout==0xEF||bufferout==0xDF||bufferout==0xBF||bufferout==0x7F)//Tastenverriegelung
{
out[arrayindex]=(out[arrayindex]==bufferout)?0xFF:bufferout;//if schleife zur überprüfung ob der neue wert dem alten entspricht                                                                                   
I2C8574A(0x7A, out[arrayindex]);//neue werte in die I/Os schreiben
} 

btw. die namen der variablen haben schon sinn, da sie nur zur 
überprüfung auf die LED geschaltet werden und später auf die ausgänge 
der Kreuzschiene

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Felix H. schrieb:

> btw. die namen der variablen haben schon sinn,

ein Name 'arrayindex' macht niemals Sinn.

Und BTW: 'if' ist keine Schleife, sondern eine Abfrage oder 
Falluntescheidung. In einer Schleife wird etwas wiederholt abgearbeitet.

Autor: Felix H. (felixh)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja ich muss mich nicht darüber streiten was bei mir Sinn und bei dir 
keinen macht.

Das if keine Schleife ist sehe ich ein.

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.