Denkfehler bei Matrixtastatur?

OP #1207914
Lesenswert?

Hallo,

ich hatte mich Gestern schoneinmal an Euch gewendet, da ich Probleme mit 
meiner Matrixtastatur 3x4 habe.

Ich habe die Schaltung jetzt wie auf 
http://sprut.de/electronic/pic/programm/tastatur.htm beschrieben 
umgesetzt.


Die Spalten auf die Ausgänge 0..2 die Zeilen auf die Eingänge 3..6

Weiter sind bei den Eingängen die internen Pull UP Wiederstände auf HIGH 
gesetzt.

Von jedem Schalter geht jeweils in Kabel in einen Ausgang und eins in 
einen Eingang. Am Pin vom Schalter, der einen Ausgang anliegen hat, geht 
noch ein Kabel zu GND.

Nun ist es allerdings so, dass auch wenn die Ausgänge auf High liegen am 
Schalterpin 0V anliegen. Sobald ich die Kabel von GND wieder trenne, 
liegen 5V an.

Was mache ich falsch?


Danke und Gruß,

Zerb287
#1207931
Lesenswert?

Stefan K. wrote:

> Von jedem Schalter geht jeweils in Kabel in einen Ausgang und eins in
> einen Eingang. Am Pin vom Schalter, der einen Ausgang anliegen hat, geht
> noch ein Kabel zu GND.

Wozu???

> Nun ist es allerdings so, dass auch wenn die Ausgänge auf High liegen am
> Schalterpin 0V anliegen. Sobald ich die Kabel von GND wieder trenne,
> liegen 5V an.

Oh Wunder!

> Was mache ich falsch?

Wohl das Kabel zu GND?
OP #1207941
Lesenswert?

Hallo,

danke für die rasche Antwort. Jedoch, wenn das Kabel zu GND nicht gelegt 
ist, dann bekomme ich die 0 nicht in den Port, da der Pull UP 
Wiederstand nicht los lässt!

Soweit war ich schon, deshalb ja das Kabel zu GND!

Wie kann ich das nun lösen?

Mein code:

#include <avr/io.h>

int main (void) {



   //DDRC  = 0x00;
   //PORTC = 0x00;
   //PORTA = 0xff;



  DDRC  &= ~(1<<DDC3) | (1<<DDC4) | (1<<DDC5) | (1<<DDC6);
  PORTC |= (1<<PC3) | (1<<PC4) | (1<<PC5) | (1<<PC6);
  PORTC |= (1<<PC0) | (1<<PC1) | (1<<PC2);


   while(1) {


    PORTC &= ~(1<<PC0);


    if (! (PINC & (1<<PC3)) )
     {
     PORTA = 0xff;
     } else { PORTA = 0x00;}




    //PORTC |= (1<<PC0);

}

   return 0;
}
#1207959
Lesenswert?

Stefan K. wrote:
> Hallo,
>
> danke für die rasche Antwort. Jedoch, wenn das Kabel zu GND nicht gelegt
> ist, dann bekomme ich die 0 nicht in den Port, da der Pull UP
> Wiederstand nicht los lässt!

Die 0 kommt doch (nacheinander) von den Ausgängen 0..2!

> Soweit war ich schon, deshalb ja das Kabel zu GND!

Habe wohl nicht verstanden, wie Du das Kabel zu GND angeschlossen hast.
Mach bitte eine Zeichnung.

> Wie kann ich das nun lösen?

Prüf nach, ob bei den Ausgängen 0..2 jeweils eine 0 anliegt.
Z.B. zwischen 5V und dem Ausgang mit dem Voltmeter messen.
Dabei muss aber der Ausgang ruhen, also das Programm muss angehalten 
sein.

>
> Mein code:
Sorry, ich kann kein AVR-ASM
OP #1207968
Lesenswert?

Hallo,

ja die Null bei den Ausgängen, die ich nach und nach anlege, die Liegt 
an, das passt soweit.

ABER: Die 0 liegt an den Pins des Atmega zwar an, da aber von selben 
Schalterpin an dem das Kabel vom Ausgang ankommt, auch ein Kabel zu GND 
wegführt, liegt dort auch wenn der Ausgan 0..2 geschaltet ist eine 0 an.

Das Problem, welches daraus resultiert ist, dass jede Taste einer Zeile 
die LED einschalten kann, da ja überall eine Null anliegt, kann jeder 
Andere Taster einer Zeile den Pull UP Wiederstand down zeihen.

Gruß Stefan
Persönliche Seite #1207979
Lesenswert?

Du musst schon auch lesen und verstehen, was den sprut sein Programm 
macht:

"Die Ausgänge werden nacheinander auf "0" gelegt und dabei die Eingänge 
RB4-RB7 ausgewertet. Liegt dabei ein Eingang auf "0", so muß dieser 
durch eine gedrückte Taste mit dem aktiven Ausgang verbunden sein."

Das heist also,

1. Deine vier Eingänge liegen im Ruhezustand auf high.
2. Dann schaltest du einen der Ausgänge auf low und liest die vier 
Eingänge ein. Ist ein Bit gesetzt, dann weist du aufgrund des 
geschalteten Ausgangs und des gestzten Bits, welcher Taster gedrückt 
wurde.
3. Du deaktivierst den 1. Ausgang und aktivierst den 2. Ausgang. Dann 
liest du wieder die vier Eingänge ein und schaust ob ein Taster gedrückt 
wurde.
4. Zu guter letzt musst du das nun noch einmal mit dem 3. Ausgang 
machen.

Auf diese Weise findest du heraus, welcher Taster gedrückt wurde. Nun 
noch entprellen und du kannst damit arbeiten...

Sven

PS: Dein Kabel zu Ground ist Unsinn.
#1207985
Lesenswert?

Stefan K. wrote:
> Hallo,
>
> ja die Null bei den Ausgängen, die ich nach und nach anlege, die Liegt
> an, das passt soweit.

Super


> ABER: Die 0 liegt an den Pins des Atmega zwar an, da aber von selben
> Schalterpin an dem das Kabel vom Ausgang ankommt, auch ein Kabel zu GND
> wegführt, liegt dort auch wenn der Ausgan 0..2 geschaltet ist eine 0 an.

Kabel zu GND????


> Das Problem, welches daraus resultiert ist, dass jede Taste einer Zeile
> die LED einschalten kann, da ja überall eine Null anliegt, kann jeder
> Andere Taster einer Zeile den Pull UP Wiederstand down zeihen.

Willst Du nun bitte ein Zeichnung posten und uns erklären, warum ein 
Kabel (übrigens eher Verbindung, oder wenn's wirklich sein muss, Draht, 
Litze oder Leitung genannt) nach GND führen muss?
OP #1208009
Lesenswert?

Hallo,

Zeichnung ist in Arbeit, jedoch wenn ein Ausgang auf 0 gesetzt ist, wir 
am Eingang nie eine 0 Angelegt, warum weiss ich nicht!

Hierbei ist der Ausgang mit einer 0 direkt mit dem Eingang mit 5V durch 
den Pull UP Wiederstand verbunden.


Verbindung zw. Schalter und GND wurde bereits beseitigt.


Gruß Stefan


P.S. Ich bin angehender Wirtschaftsinformatiker und habe mit E-Technik 
etc. leider nicht viel zu tun, beschäftige mich aber Hobbymäßig damit 
daher entschuldigt bitte meine wirren Bezeichnungen ;-))
Gast #1208038
Lesenswert?

Hast Du ein Multimeter oder eine andere Möglichkeit Spannungen zu 
messen?

Leg mal einen Ausgang auf low und schau Dir die Spannungen an. 
Eingänge/Ausgänge. Wenn alles stimmt, dann drück mal ne Taste und schau 
Dir an was passiert. So lernst Du die kleine Schaltung verstehen und 
kannst Dir die Software nochmal ansehen und testen.

Wenn Hardware und Softwrae gleichzeitig nicht stimmen, so ist es schwer 
iorgendwo anzufangen. Viel Glück.
#1208039
Lesenswert?

Stefan K. wrote:

> Zeichnung ist in Arbeit

Super!

> jedoch wenn ein Ausgang auf 0 gesetzt ist, wir
> am Eingang nie eine 0 Angelegt, warum weiss ich nicht!

Ist der Ausgang ganz sicher auf 0 gesetzt? Hast Du zwischen 5V und 
Ausgang die Spannung nachgemessen? Wieviel beträgt sie?

> Hierbei ist der Ausgang mit einer 0 direkt mit dem Eingang mit 5V durch
> den Pull UP Wiederstand verbunden.

Ja, aber der Pullup Widerstand "gibt nach", es müsste sich eine log. 0 
ergeben.

> Verbindung zw. Schalter und GND wurde bereits beseitigt.

OK


> P.S. Ich bin angehender Wirtschaftsinformatiker und habe mit E-Technik
> etc. leider nicht viel zu tun, beschäftige mich aber Hobbymäßig damit
> daher entschuldigt bitte meine wirren Bezeichnungen ;-))
Schon ok.

Sorry, ich schrieb weiter oben, dass ich kein AVR-ASM kann.
Natürlich ist das C und nicht ASM, ich meinte ich kenne die Architektur 
der AVRs und die Register etc. fast gar nicht.

Ich glaube, Du hast möglicherweise die I/O nicht richtig eingestellt:

DDRC  &= ~(1<<DDC3) | (1<<DDC4) | (1<<DDC5) | (1<<DDC6);

Das ~ bezieht sich ev. nur auf den Ausdruck (1<<DDC3).

Versuchs mal mit

DDRC = 7;

oder mit Klammerung
DDRC  &= ~ ( (1<<DDC3) | (1<<DDC4) | (1<<DDC5) | (1<<DDC6) ) ;
OP #1208056
Lesenswert?

Hallo,

ja ein Multimeter habe ich, sogar ein Oszilloskop, das Hilft gerade aber 
nicht. Die Schaltung ist überprüft und stimmt. Mit der Initialisierung 
usw. das passt auch, habe die Schaltung ausgesteckt, denn ich habe einen 
Parallel Port stecker verwendet und an der Quelle gemessen. Das passt 
soweit auch alles. Nur der Pull UP Wiederstand zeiht nicht an, das 
verstehe ich nicht.
#1208102
Lesenswert?

Hab zwar noch nicht den Durchblick durch den Thread, aber ich sehe grad 
auf anhieb das du PORTC verwendest? Weiss nicht welchen Chip du hast, 
aber bei den vielen liegt auf dem PORTC das JTAG-Interface (PC2 bis 
PC5). Wenn das Teil nicht per Fuse-BIT deaktiviert wird, kann man mit 
den Pins wenig anfangen. Bin erst gestern selbst wieder drauf 
reingefallen, wieso eine 7-Segment Anzeige, die am PORTC hing, komische 
Zeichen angezeigt hat... ;-)

Das so von meiner Seite als Schuss ins Blaue...

Grüße,
Sebi
OP #1208222
Lesenswert?

Hallo,

keine Ahnung, was das macht oder wie ich das setzen oder löschen muss.

Was mich wundert ist, dass

wenn der Ausgang auf 0 ist, der Eingang per Pull-UP auf 1 ist tritt 
folgendes beim Spannung messen auf:

->> Bei gedrücktem Schalter (kontakt zu)

Der Pin am Schalter vom Eingang ist auf 5V, der Pin am Schalter worauf 
der Ausgang sitzt, ist ebenso 5V.

Der Pull-UP Wiederstand wird also nicht down gezogen, sondern das Signal 
von 5V wird über die Schaltung weitergegenen!


WARUM?
#1208264
Lesenswert?

Die Pins PC2 bis PC5 haben ein eigenes Verhalten wenn JTAG aktiviert 
ist. Da kannst du setzen oder auslesen wie du lustig bist, die PINS 
lassen sich nicht normal nutzen, ausser für das JTAG-Interface.

Im Grunde müsste das mit der Software gehen mit welcher du deinen Chip 
programierst. Im Artikel werden mehere Tools besprochen:

http://www.mikrocontroller.net/articles/AVR_Fuses

Ansonsten hilft die Suche im Forum hier, da dieses Thema recht häufig 
vorkommt. ;-)

Du kannst natürlich auch einen anderen Port probieren...

Grüße,
Sebi
OP #1209074
Lesenswert?

Hallo nochmal,


also, JTAG ist deaktiviert!

also, ich habe jetzt meine Schaltung verkleinert. Nur noch das 
AVR-NET-IO Bord von pollin. daran habe ich an den PortC0 0V angelegt. 
Das passt soweit auch. Als Eingang den ProtC3 verwendet und den internen 
PullUp Wiederstand aktiviert. Auch das passt.


Wenn ich jetzt direkt den PORTC0 mit PORTC3 verbinde, bleibt der Pull UP 
Wiederstand gesetzt!

Es wird an PORTC3 keine 0 angelegt!

MEIN CODE:

int main(void)
{
DDRC &= ~( ( 1 << DDC3 ) | ( 1<<DDC4) | (1<<DDC5) | (1<<DDC6) );
PORTC |= (1<<PC3);
PORTA = 0x00;

while(1)
   {


   if (!(PINC & (1<<PINC3)))
      {
    PORTA = 0xff;
    } else { PORTA = 0x00;}
   }

return 0;
}

FUNKTIONIERT NICHT!!!


Gruß Stefan
#1209105
Lesenswert?

Stefan K. wrote:

> daran habe ich an den PortC0 0V angelegt.
PortC0 ist doch ein Ausgang, oder? Da darfst Du nichts anlegen.
Den musst Du in Software auf 0 oder 1 setzen.

> Das passt soweit auch. Als Eingang den ProtC3 verwendet
Wie setzt Du PortC3 auf Eingang? Soviel ich weiss, ist das bei AVR über 
den DDRC. 0 = Eingang, 1 = Ausgang

> und den internen PullUp Wiederstand aktiviert.
Wo im Code passiert das?

> Wenn ich jetzt direkt den PORTC0 mit PORTC3 verbinde, bleibt der Pull UP
> Wiederstand gesetzt!
>
> Es wird an PORTC3 keine 0 angelegt!

Und wenn Du PortC3 mit einem Draht auf GND ziehst (zuerst von PortC0 
trennen), kannst Du das 0 lesen?


Tipp: Schreib mal die direkten Werte in den Sourcecode statt den 
Bit-Operationen. Und mit direkten Zuweisungen statt |= etc.
Sicher ist sicher.
OP #1209134
Lesenswert?

Hallo,

mir scheint als hätte ich eine wichtige Entdeckung gemacht.

CODE:

if ((PINC & (1<<PC3)))
      {
    PORTC |= (1<<PC7);
    } else { PORTC &= ~(1<<PC7) ;}

Wenn ich nun den PORT7 mit dem Oszilloskop messe, mir also die Ausgabe 
anschaue, dann sehe ich, dass der laufend ein und ausgeschaltet wird.

|-|-|-| Also die Ausgabe des Oszi schaut so aus.

WARUM, das heißt meine if Anweisung stimmt nicht, da diese jedes zweite 
Mal erfüllt zu sein scheint.
OP #1209179
Lesenswert?

Habe soeben die Zuweisung abgeändert.

Allerdings, ist während der Abfrage der Portpin 7 immer nur teilweise 
aktiviert. Wenn ich messe, dann liegt er auf .3,7V.

Stimmen die Abfragen? Oder wo liegt der Fehler?

Mein CODE:

DDRC = 0x87;

PORTC = 0x00;

//DDRC = 0x07;
while(1)


   {

   PORTC = 0x01;

   if (PORTC == 0x01)
      {
    if (PINC & (1<<PC3))
      {
    PORTC = 0x80;
    }
      if ( PINC & (1<<PINC4))
      {
    PORTC = 0x80;
    }
      if ( PINC & (1<<PINC5))
      {
    PORTC = 0x80;
    }
      if ( PINC & (1<<PINC6))
      {
    PORTC = 0x80;
    }
    } else { PORTC = 0x01 ;}
    PORTC = 0x01;

   }
#1209242
Lesenswert?

Es darf natürlich jeder sein eigenes Fahrrad neu erfinden, bloß brauchts 
dann ordentlich Geduld, ehe man seine eckigen Räder rund kriegt.

Es gibt verständlicher Weise auch wenig Begeisterung der Experten, sich 
den tausendsten Versuch einer Tasteneingabe anzugucken.


Max hat doch gerade erst wieder nen schönen Code gepostet:

Beitrag "Re: Matrix-Tastatur Abfrage in C"

Einfach mal laufen lassen.


Peter
OP #1209391
Lesenswert?

Naja,

Die Abfragen passen nun. Nach reichlich messen mit dem Oszi habe ich das 
Problem entdeckt, weiss aber nicht woran es lag, nun funktioniert der 
Code.

Ein neues Problem ist jedoch entstanden:

Wenn ich 0V vom Ausgang anlege, den Pull UP am Eingang auf 1 habe und 
den Schalter nun drücke, dann passiert folgendes:

Die Schaltung pendelt sich auf 2,5V auf jeder Seite des Schalters ein.

Also im Klartext:

Am Pin worauf der Ausgang liegt nun 2,5V und am Pin worauf der Eingang 
liegt ebenso 2,5V.

Ich finde das ziemlich seltsam?


Was meint Ihr woran es liegt.

--> Sorry, den Code habe ich nicht gesehen.
#1209597
Lesenswert?

Stefan K. wrote:
> Am Pin worauf der Ausgang liegt nun 2,5V und am Pin worauf der Eingang
> liegt ebenso 2,5V.

Miß mal die Stromaufnahme des AVR. Wenn die stark ansteigt, kämpfen 2 
Ausgänge gegeneinander, das ist nicht gesund für den AVR.

Deshalb nimmt man für ne Tastenmatrix immer open-drain Ausgänge, d.h. 
ein Pin kann nur Low-Ausgang oder Eingang sein.

High-Ausgang ist verboten, wenn ein anderer Pin Low-Ausgang ist!


Peter

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