Forum: Mikrocontroller und Digitale Elektronik GPIO-Ports und Keypad richtig konfigurieren


von Ulf K. (spurzylinder)


Lesenswert?

Hallo zusammen,

ich habe vor kurzem angefangen mich mit dem STM32F407 Board 
auseinanderzusetzen, da ich gerne kleine Projekte umsetzen möchte.
Aus diesem Grund wollte ich klein anfangen und habe jetzt leider ein 
kleines Problem, wobei ich eure Hilfe gebrauchen könnte.

Mein Ziel ist es ein 4x4 Keypad anzuschließen mit dem ich dann 
verschiedene Funktionen steuren kann. Das Keypad habe ich an die Ports 
(PC7, PC9, PA9, PA13, PA15, PC11, PD0 und PD2) angeschlossen.
Die ersten 4 Pins habe ich als Input, an denen ein High Pegel anliegt 
und die unteren als Output Pins mit Lowpegel konfiguriert.
Damit ich ich nun auslesen kann, welche Taste auf dem Pad gedrückt wird, 
möchte ich nun folgendes tun:
Wird eine Taste gedrückt soll der entsprechende High Pegel auf Low 
gezogen werden. Anschließend werden die Zeilen nacheinander auf High 
gesetzt und es wird geprüft wann nun wieder ein High Pegel anliegt. 
Somit ist Spalte und Zeile bestimmt, welche die Taste symbolisiert.

Mein generelles Problem ist nun, dass der anliegende High Pegl leider 
nicht auf Low gezogen wird, wenn die Verdingung zwischen High und Low 
gezogen wird.
Stelle ich jedoch eine Verdingung mit GND her, wird der High Pegel auf 
0V gezogen. Ich habe bereits diverse Konfigurationen der Pins 
ausprobiert, sprich GPIO output level, GPIO mode und GPIO 
Pull-uo/Pull-down.
Leider hat nichts von diesen Einstellungen geklappt.
Ich habe meine Projekte mit CubeMX vorkonfiguriert und programmiere mit 
Keil.

Meine Standardeinstellungen habe ich mal unten angefügt und würde gerne 
wissen, ob meine geplante Vorgehensweise richtig ist und wie ich es 
schaffe, den anliegenden High Pegel durch die Schalterbetätigung auf den 
entsprechenden Lowpegel bekomme.
Idealerweise ohne großartig was mit einem Breadboard auf zubauen.


** Configure pins
  HAL_GPIO_WritePin(C1_GPIO_Port, C1_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(C2_GPIO_Port, C2_Pin, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, C3_Pin|C4_Pin, GPIO_PIN_SET);

  /*Configure GPIO pins : PA0 R3_Pin R4_Pin */
  GPIO_InitStruct.Pin = GPIO_PIN_0|R3_Pin|R4_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : R1_Pin R2_Pin */
  GPIO_InitStruct.Pin = R1_Pin|R2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

: Bearbeitet durch User
von Och nöö (Gast)


Lesenswert?

Nicht schon wieder: kilometerlanger Sourcecode im Text.

Kannst du die Hinwise zum Posten von Code nicht verstehen?
Zu kleingedruckt? Dann kauf dir eine Lupe.

von Nop (Gast)


Lesenswert?

Na ob das so sinnvoll ist, ERST write_pin zu machen und DANN den Init?

von Stefan F. (Gast)


Lesenswert?

Ich bin mit diesem Hardware Abstraktionslayer nicht vertraut, aber das 
sieht unstimmig aus:

> GPIO_InitStruct.Pin = GPIO_PIN_0|R3_Pin|R4_Pin;
> GPIO_InitStruct.Pin = R1_Pin|R2_Pin;

Ist es vorgesehen, mit einer Struktur mehrere Pins gleichzeitig zu 
konfigurieren?

> GPIO_InitStruct.Pull = GPIO_NOPULL;

Wenn der Eingang keinen Pull-Up Widerstand hat, wer zieht ihn dann hoch? 
Hast du externe Pull-Up Widerstände?

> die unteren als Output Pins mit Lowpegel konfiguriert.

In den von Dir gezeigten Code-Zeilen ist davon aber nichts zu sehen.

Die von Dir beschriebene Vorgehensweise ist etwas anders als ich es 
gewohnt bin, aber klingt plausibel. Es gibt ja nicht nur einen richtigen 
Weg zum Ziel.

von W.S. (Gast)


Lesenswert?

Ulf K. schrieb:
> Mein Ziel ist es ein 4x4 Keypad anzuschließen mit dem ich dann
> verschiedene Funktionen steuren kann. Das Keypad habe ich an die Ports
> (PC7, PC9, PA9, PA13, PA15, PC11, PD0 und PD2) angeschlossen.

Nun, sowas kann man zum Testen ja mal machen. Ansonsten nimmt man für 
die Steuer-Leitungen die Datenleitungen zum Display, entkoppelt mit je 
einem Widerstand (2k2..4k7 reichen meistens).

Was mir bei deinem Gedanken auffällt ist, daß du von "auf High gesetzt" 
schreibst:

Ulf K. schrieb:
> Anschließend werden die Zeilen nacheinander auf High
> gesetzt und es wird geprüft

So geht das nicht gut. Normalerweise nimmt man einen Widerstand, der die 
Sense-Leitung dezent zur inaktiven Seite der Steuer-Leitungen zieht 
(hier z.B. 68k oder so). Zum Detektieren, ob überhaupt eine Taste 
gedrückt ist, werden alle Steuer-Leitungen gesetzt (bei dir auf Low) und 
geschaut, ob auch alle Sense-Leitungen auf inaktiv (bei dir auf High) 
liegen. Tun sie das, dann ist nix gedrückt.

So weit so gut. Wenn aber eine der Sense-Leitungen ein Low liefert, dann 
geht es weiter: Nun werden der Reihe nach alle Steuer-Leitungen auf Hi-Z 
gesetzt und nachgeschaut, ab welcher Steuer-Leitung die Sense-Leitungen 
wieder auf High gehen.

Merke wohl: die Steuer-Leitungen nicht auf High setzen, sondern auf 
Tristate, also High-Z. Und merke auch, daß du dem Ganzen etwas Zeit zum 
analogen Einschwingen geben mußt.

W.S.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.