Hallo!
@ andi.studi
Gratulation!
Eine Pause zwischen zwei nachfolgenden Einlesungen habe ich als selbstverständlich betrachtet und leider nicht als mögliche Fehlerquelle berücksichtigt.
Viel Erfolg beim Lösen allen nächsten Problemen!
MfG
\/ \
/ \
/ \
/ \
/ \
/
so 2 Tasten werden nun gleichzeitig erkannt.
verodert und per led anzeige auf portD und auf dem display in dezimal dargestellt.
es lag an einem timing problem.
in jeder spalten abfrage funktionierten ja nur die letzten beiden if abfragen richtig sobalt 2 Tasten gedrückt waren.
mit 100µs wartezeit nachdem die zu scanende spalte aktiviert wurde funktionierte auch die 2. zeile richtig.
und nu mit 200µs klappt alles.
erste stufffe ist erklommen \Code:signed int KEY_Scancode (void) { signed int code=0x0000; INTCON2bits.RBPU=0; //pull-up's an TRIS_KEY = 0b11110000; // KEY-PORT bit 0,1,2,3 = Ausgänge (bit 0 für LCD_E=0) PORTKEY = 0b11111110; //*******1.Spalte(1,4,7,*)************************************************************************* TRIS_KEY = 0b11111100; spalte1 = 0; delay100us(2); if (zeile1==0) code = code | 1; //1 if (zeile2==0) code = code | 8; //4 if (zeile3==0) code = code | 64; //7 if (zeile4==0) code = code |512; //* //*******2.Spalte(2,5,8,0)************************************************************************* TRIS_KEY = 0b11111010; spalte2 = 0; delay100us(2); if (zeile1==0) code = code | 2; //2 if (zeile2==0) code = code | 16; //5 if (zeile3==0) code = code |128; //8 if (zeile4==0) code = code |1024; //0 //*******3.Spalte(3,6,9,#)************************************************************************* TRIS_KEY = 0b11110110; spalte3 = 0; delay100us(2); if (zeile1==0) code = code | 4; //3 if (zeile2==0) code = code | 32; //6 if (zeile3==0) code = code |256; //9 if (zeile4==0) code = code |2048; //# return code; }/
jetzt gehts weiter mit der erkennung ob eine taste gedrückt ist, ob sie noch festgechalten wird, oder schon losgelassen wurde.
PicNick schrieb:
Was ist mit Marix-Bit gemeint, und womit wird er verglichen.Ich persönlich würde für alle Tasten eine Bit-Matrix anlegen, die ich beim scannen einzeln vergleiche.
Matrix-Bit = 1 und TastenPin=1 --> nix zu tun
Matrix-Bit = 1 und TastenPin=0 --> taste (neu) gedrückt ->sende ON
Matrix-Bit = 0 und TastenPin=0 --> taste festgehalten, nix zu tun
Matrix-Bit = 0 und TastenPin=1 --> taste ausgeslassen--> sende OFF
und dann den Tastenpin in der Matrix merken
Das kann man nun unterschiedlich geschickt machen, aber das Prinzip bleibt
bin gespannt auf eire anregungen.
Hallo!
@ andi.studi
Gratulation!
Eine Pause zwischen zwei nachfolgenden Einlesungen habe ich als selbstverständlich betrachtet und leider nicht als mögliche Fehlerquelle berücksichtigt.
Viel Erfolg beim Lösen allen nächsten Problemen!
MfG
Nicht, dass die folgenden Programmzeilen besonders elegant oder effizient wären, aber zum Verständnis, was ich meine:
(beschränkt auf das Wesentliche)
Nebeneffekt "at first", weil ja alle Matrixbits auf 0 stehen: ALLE Tasten on, und dann gleich ALLE Tásten OFF.Code:static char Matrix[12]; //-------------------------------------------------------------- void KEY_Check (int index, int maske) { if ( Matrix[index] ^= ( PORTB & maske ) ) // änderung alt/neu { if ( PORTB & maske) // alt=0,neu =1 SendKeyOFF( index) else SendKeyON( index ) Matrix[index] = PORTB & maske; // merken } } signed int KEY_Scancode (void) { spalte1 = 0; spalte2 = 1; spalte3 = 1; KEY_Check (0 , 1); KEY_Check (1 , 2); KEY_Check (2 , 4); KEY_Check (3 , 8); spalte1 = 1; spalte2 = 0; spalte3 = 1; KEY_Check (4 , 1); KEY_Check (5 , 2); KEY_Check (6 , 4); KEY_Check (7 , 8); spalte1 = 1; spalte2 = 1; spalte3 = 0; KEY_Check (8 , 1); KEY_Check (9 , 2); KEY_Check (10 , 4); KEY_Check (11 , 8); }
Man müsste daher ganz am Anfang alle tasten auf "aus" stellen
for (int ix=0; ix < 12; ix++)
Matrix[ix] = 0xFF;
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
hallo PicNick,
danke für die erleuterung,
doch wie es aussieht stehe ich auf dem bit![]()
mir will einfach nicht klar werden was
macht.if ( Matrix[index] ^= ( PORTB & maske ) )
was bringt mir z.b. den die bitweise verundung zwischen PORTB und maske " ( PORTB & maske )"?
bsp.
Taste PortB________ maske______resultat?
1:__ 1110 1100__0000 0001___0000 0000
4:__ 1101 1100__0000 0010___0000 0000
7:__ 1011 1100__0000 0100___0000 0100
2:__ 1110 1010__0000 0001___0000 0000
5:__ 1101 1010__0000 0010___0000 0010
für "Matrix[index] ^= ( PORTB & maske )" kann ich auch
"Matrix[index] = Matrix[index] ^( PORTB & maske )" schreiben, ist das richtig?
Ich bin ein Koffer
"maske" muss natürlich den Postb-Bits der Tasten entsprechen, also
KEY_Check (0 , 0x10);
KEY_Check (1 , 0x20);
KEY_Check (2 , 0x40);
KEY_Check (3 , 0x80);
(PortB & maske ) ergibt ein Byte, das nur aus dem fraglichen Bit aus PortB besteht.
if ( matrix[index] ^= (PortB & maske ) ) ist ja EXCLUSIV ODER.
Das ergebnis ist also nur != 0, wenn das gefragte bit in Matrix und PortB verschieden ist
*schäm*
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
hi @ all
vielen dank für alles, und vorallem danke ich PicNick,
super idee!!!
nun läuft es auch endlich stabiel
hier nen ausschnitt:
musste aber: if ( Matrix[index] ^ ( PORTB & maske ) ) // änderung (alt=0/neu=1)Code:#define MAXB 12 // bestimmt die grösse von keybuffer (keybuffer[MAXB])//0..255 static int keybuffer[MAXB]={0,0,0,0,0,0,0,0,0,0,0,0}; //funktion bufferlöschne schreiben und in die init packen static uint8 keycount=0; void KEY_Check (uint8 index, uint8 maske) { static uint8 Matrix[12]= {0x10,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x40,0x80,0x80,0x80}; unsigned int code; static uint8 i=1; if ( Matrix[index] ^ ( PORTB & maske ) ) // änderung (alt=0/neu=1) { /*******************************************sende breakcode, taste losgelassen********************/ if ( PORTB&maske) { switch(index+100) { case 100: code=0x2001; break; case 101: code=0x2002; break; case 102: code=0x2004; break; case 103: code=0x2008; break; case 104: code=0x2010; break; case 105: code=0x2020; break; case 106: code=0x2040; break; case 107: code=0x2080; break; case 108: code=0x2100; break; case 109: code=0x2200; break; case 110: code=0x2400; break; case 111: code=0x2800; break; } } /*******************************************sende makecode, taste gedrückt**********************/ else { switch(index) { case 0: code=0x0001; break; case 1: code=0x0002; break; case 2: code=0x0004; break; case 3: code=0x0008; break; case 4: code=0x0010; break; case 5: code=0x0020; break; case 6: code=0x0040; break; case 7: code=0x0080; break; case 8: code=0x0100; break; case 9: code=0x0200; break; case 10: code=0x0400; break; case 11: code=0x0800; break; } } Matrix[index] = PORTB & maske; // merken Matrix[index] ist null bei gedrükter Taste // füllt puffer mit make und break code //////////////////////////////////////////////////////// // keybuffer[keycount++]=code; // code in aktuelles feld speichern und feld um 1 erhöhen // if (keycount>MAXB-1) keycount=0 ; // wenn feld ende erreicht gehe zu feld anfang if(code<=0x0800) { keybuffer[keycount] |= code; i=0; } if (code>=0x2000 && i==0) { keycount++; i=1; } if (keycount>MAXB-1) keycount=0; } } uint8 KEY_scancheck (void) { INTCON2bits.RBPU=0; //pull-up's an TRIS_KEY = 0b11110000; // KEY-PORT bit 0,1,2,3 = Ausgänge (bit 0 für LCD_E=0) PORTKEY = 0b11111110; TRIS_KEY = 0b11111100; spalte1 = 0; KEY_Check (0 , 0x10); //1 KEY_Check (3 , 0x20); //4 KEY_Check (6 , 0x40); //7 KEY_Check (9 , 0x80); //* spalte1 = 1; TRIS_KEY = 0b11111010; spalte2 = 0; KEY_Check (1 , 0x10); //2 KEY_Check (4 , 0x20); //5 KEY_Check (7 , 0x40); //8 KEY_Check (10, 0x80); //0 spalte2 = 1; TRIS_KEY = 0b11110110; spalte3 = 0; KEY_Check (2 , 0x10); //3 KEY_Check (5 , 0x20); //6 KEY_Check (8 , 0x40); //9 KEY_Check (11 ,0x80); //# spalte3 = 1; }
heisen und nicht ^=// brauchte etwas länger um das zu finden
nun versuch ich die funktion uint8 KEY_scancheck (void) über einen timer interrupt in regelmässigen abständen auszuführen.
wünscht mir glück
und nochmals danke
mfg andi
uiiii
naja, irgendwann lern' ich's
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
hej so langsamm wird was draus, nun funktioniert auch das einlesen per timer0 interrupt. \/
musste diesen aber ausschalten bei den funktionen die daten and LCD senden, welches sich auf dem gleichen port befindet, da sonst das LCD gesponne hat.
weiß jemand womit das zu tun hat?
sry habe keinen plan davon
![]()
![]()
sry habe keinen plan davon
![]()
![]()
Lesezeichen