Forum: Compiler & IDEs Pin soll Ein- und Ausgang sein - ich steh auf der Leitung


von Santiago (Gast)


Lesenswert?

Hallo,

irgendwie bin ich im Moment blockiert und sehe den Fehler nicht.
Folgende Situation:

An einem Pin ist ein Taster angeschlossen - und die Verarbeitung klappte 
bislang auch ganz gut.

Jetzt soll über den gleichen Pin noch ein Relais gesteuert werden.
Während der Schaltphase des Relais brauche ich den Taster nicht.

Dafür gibt es folgende Saucen:
Erstmal der Bereich aus config.h
1
/*
2
 * Inputs
3
 */
4
#define PORT_T1 PIND
5
#define DDR_T1  DDRD
6
#define PIN_T1  PD2
7
8
#define PORT_T2 PIND
9
#define DDR_T2  DDRD
10
#define PIN_T2  PD3

Im Timer-Interrupt wird der Taster überprüft:
1
   if (PORT_T1 & (1 << PIN_T1))
2
      state.btT1++;
3
   else 
4
      state.btT1 = 0;
Solange der Taster alleine am Pin war - kein Problem.

Jetzt im Doppel dachte ich, wenn ich das Richtungsregister mit abfrage, 
kann ich abfangen, wenn/ob das Relais geschaltet ist und werte das nicht 
als Eingabe.

Das wollte ich folgendermaßen umsetzen:
1
      if (!(DDR_T1 & (1 << PIN_T1)) && (PORT_T1 & (1 << PIN_T1)))
2
         state.btT1++;
3
      else
4
         state.btT1 = 0;
... aber mit dem Code funzt nix mehr.

von Michael U. (amiga)


Lesenswert?

Hallo,

man kann solche Tricks zwar machen, aber hast Du auch in der Schaltung 
bedacht, was mit dem Relais oder dem auf Ausgang programmierten Pin 
passiert, wenn der Taster gedrückt wird?

Im Programm sehe ich da weniger ein Problem, Du weißt ja dort, wann Dein 
Relais angesteuert wird, also irgendein Flag setzen und wenn das gesetzt 
ist, die Tastenabfrage komplett übergehen.

Gruß aus Berlin
Michael

von Santiago (Gast)


Lesenswert?

Hallo Michael,

danke für Deine Aufmerksamkeit.

> man kann solche Tricks zwar machen, aber hast Du auch in der Schaltung
> bedacht, was mit dem Relais oder dem auf Ausgang programmierten Pin
> passiert, wenn der Taster gedrückt wird?

Bedacht schon - ob ich das Richtige gedacht habe, muss sich dann zeigen.
Der Taster ist über Pulldown-Widerstand angeschlossen und das Relais 
(auf einer anderen Platine) hat vor dem Schalt-Transistor noch einen 
Vorwiderstand.
Ich hätte gedacht, dass das klappen könnte.

> Im Programm sehe ich da weniger ein Problem, Du weißt ja dort, wann Dein
> Relais angesteuert wird, also irgendein Flag setzen und wenn das gesetzt
> ist, die Tastenabfrage komplett übergehen.

Getreu dem Motto: "und fällt dem Programmierer nix mehr ein, dann setzt 
er halt ein Schalterlein"?

Mir nehmen die Stellen, an denen wertvoller Speicher verschwendet wird 
zu schnell zu. Die Information ist doch im Chip drin. Das DDR-Register 
darf auch gelesen werden - warum klappt dann meine Abfrage von oben 
nicht?
Wo sitzt denn genau mein Denkfehler (und jetzt bitte net sagen: vor der 
Tastatur :( )

von Peter D. (peda)


Lesenswert?

Das ist tricky.

Ich würde sowas nur manche, wenn z.B. schon ein Kabel liegt und da eben 
nur noch ein Draht frei ist.

Wie es geht, steht hier:

Beitrag "Taster + LED am selben Draht (4*)"


Ansonsten würde ich einen (oder 2, 3, ..) 74HC595 nehmen.
Kostet unter Verwendung des SPI nur einen Portpin zusätzlich und Du hast 
8 (oder 16, 24, ..) zusätzliche Ausgänge.


Peter

von Michael U. (amiga)


Lesenswert?

Santiago wrote:

> Ich hätte gedacht, dass das klappen könnte.

Sollte so gehen.

>...
> Getreu dem Motto: "und fällt dem Programmierer nix mehr ein, dann setzt
> er halt ein Schalterlein"?
> Mir nehmen die Stellen, an denen wertvoller Speicher verschwendet wird
> zu schnell zu. Die Information ist doch im Chip drin. Das DDR-Register
> darf auch gelesen werden - warum klappt dann meine Abfrage von oben
> nicht?

Na gut, in ASM gibt es sowieso bei mir immer ein FLAG-Register und da 
wäre es ein belegtes Bit mehr...


> Wo sitzt denn genau mein Denkfehler (und jetzt bitte net sagen: vor der
> Tastatur :( )

Ich denke aber doch. ;)

Im Ernst: muß mal ein C-Programmierer über die Zeile schauen...

Schönen warmen Sonntag aus Berlin
Michael

von Santiago (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

> Ich würde sowas nur manche, wenn z.B. schon ein Kabel liegt und da eben
> nur noch ein Draht frei ist.

Sehe ich bei mir mal als gegeben :)

Ich habe ein Bild meines Testaufbaus beigefügt.
Basis ist das Evalboard des bayrischen Resteverwerters, aufgebohrt mit 
einem parallelen Programmieradapter (erst zu spät entdeckt, dass mein PC 
nix mehr seriell mag), und einem 40pol Adapter, welcher mir jeweils 
einen halben Port auf eine 10pol Wanne legt (10pol Flachkabel sind meine 
Standardkabel).
Daneben ist eine IO-Testplatine mit dem Drehencoder, einem vollen Port 
auf LED gelegt (wählbar zu schalten gegen Masse oder gegen Vcc) und 
durchgeschleift und eben das Relais.
Das Relais geht über den freien Kanal des Drehencoderkabels und auf dem 
Pin liegt der Taster des Evalboards.
Oben sieht man noch ein 7segment Element über Schieberegister und 10pol 
Steckbrettadapter und fliegender Verkabelung angeschlossen.

Die Ports sind so belegt:
Port B low nibble: low nibble LED-port Anzeige
Port B high: Schieberegister zu Segment-Anzeige
Port D low: Drehencoder, onboard Taster und Relais
Port D high: high nibble LED-port Anzeige (es fehlt das höchste Bit)

Bislang hatte ich keine Probleme, den Taster abzufragen, deshalb suche 
ich auch kein Problem in der Hardware.

> Wie es geht, steht hier:
Sorry, Peter, aber das ist mir zu hoch. Warum sollte ich eine Komparator 
nehmen? Wie gesagt, der Taster funktioniert mit der einfachen Abfrage 
problemlos.
Die Tasterprüfung läuft in einem Timer-ISR, die Verarbeitung der 
erkannten Tasten wird in main() durchgeführt.

>> Ich hätte gedacht, dass das klappen könnte.
> Sollte so gehen.

Hm - das ist genau mein Dilemma. Mit dem "Trivialcode" wird der Schalter 
erkannt. Frage ich aber zusätzlich das Pin-Richtungs-Register ab, wird 
kein Taster mehr erkannt (ohne jetzt das Relais geschaltet zu haben - 
also gleiche HW-Voraussetzungen).

> Na gut, in ASM gibt es sowieso bei mir immer ein FLAG-Register und da
> wäre es ein belegtes Bit mehr...

Klar! Ich komme auch nicht ohne zentralen Variablenpool aus. Nur sehe 
ich es nicht wirklich ein, warum ich einen Wert, der aus dem µC ablesbar 
sein sollte, nochmal selber speicheln sollte.

von Peter D. (peda)


Lesenswert?

Santiago wrote:

> Sorry, Peter, aber das ist mir zu hoch. Warum sollte ich eine Komparator
> nehmen? Wie gesagt, der Taster funktioniert mit der einfachen Abfrage
> problemlos.

Daß das eine geht, hilft nicht weiter, wenn man was ganz anderes will.

Du willst ja keine einfache Taste, sondern den Pin gleichzeitig als 
Ausgang nehmen. Daher ist es wurscht, obs nur mit der Taste geht.

Wie schon gesagt, es ist und bleibt tricky.

Aber ich will Dich zu nichts überreden.


Peter

von Santiago (Gast)


Lesenswert?

Hallo Peter,

> Daß das eine geht, hilft nicht weiter, wenn man was ganz anderes will.

Hm, könnten wir dann vielleicht erst das eine Problem abhandeln, bevor 
wir uns dem zweiten Problem zuwenden?

> Du willst ja keine einfache Taste, sondern den Pin gleichzeitig als
> Ausgang nehmen. Daher ist es wurscht, obs nur mit der Taste geht.

Hier bitte ich um etwas Nachsicht für meine fehlende HW-Kenntnisse.
Für mich sieht es so aus, dass ich schaltungstechnisch Taste und Pin als 
Ausgang gleichzeitig nehmen will.
Softwareseitig natürlich nicht gleichzeitig.

So wie ich Deine Beschreibung bei der Komparator Geschichte verstanden 
habe, ist der Taster durch die LED nimmer auf High gekommen.
Das Problem liegt ja bei mir nicht vor. Schaltungstechnisch sind beide 
ja schon von Anfang an auf der gleichen Leitung. Und der Taster wird 
zuverlässig erkannt (geht also auf high).

Dürfte ich Dich einmal bitten, die Schaltung beiseite zu lassen und Dir 
meine Codezeilen im ersten Post anzuschauen?
Ich würde gerne verstehen, warum ich mit der zweiten Abfrage keine 
Tastendrucke mehr erkennen kann.

von Oliver (Gast)


Lesenswert?

Die vier Zeilen sind völlig in Ordnung. Entweder ist vorher was im 
Programm verkehrt, oder der Pin erreicht trotz gedrückter Taste den 
high-level nicht.

Wenn du das nicht debuggen kannst (JTAG, oder z.B. in der ISR eine LED 
high setzen, wenn PIN_T1 high ist), häng mal die gesamte 
Relais-Schaltung ab, und schau, was dann passiert.

Oliver

von Peter D. (peda)


Lesenswert?

Santiago wrote:

> Ich würde gerne verstehen, warum ich mit der zweiten Abfrage keine
> Tastendrucke mehr erkennen kann.

Dann mußt Du schon einen compilierbaren Code schicken.

Mit den 4 Zeilen kann keiner was anfangen.

Ich weiß ja nicht, wie das DDR_T1 steht und was das state.btT1 für ne 
Funktion hat und woran Du die Fehlfunktion erkennst (was der Unterschied 
zwischen Fehlfunktion und Funktion ist).

Die Schaltung wäre auch wichtig.


Peter

von Peter D. (peda)


Lesenswert?

Oliver wrote:
> Die vier Zeilen sind völlig in Ordnung.

Würde mich mal interessieren, wie Du das feststellst.

Die 4 Zeilen sind syntaktisch in Ordnung.

Ob sie auch von der Logik her das tun, was der Fragesteller sich 
wünscht, kann man nicht feststellen.


Peter

von Santiago (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

vielleicht kann ich mich ja einfach nicht richtig ausdrücken?
Ich bitte also nochmals um Nachsicht.

> Die vier Zeilen sind völlig in Ordnung. Entweder ist vorher was im
> Programm verkehrt, oder der Pin erreicht trotz gedrückter Taste den
> high-level nicht.
>
> Wenn du das nicht debuggen kannst (JTAG, oder z.B. in der ISR eine LED
> high setzen, wenn PIN_T1 high ist), häng mal die gesamte
> Relais-Schaltung ab, und schau, was dann passiert.

Nochmal - es gibt kein Problem mit der Relais-Schaltung, oder wie ich 
schrieb - mit der Hardware.
Ich habe 2 Firmware - eine verwendet den ersten 4Zeiler vom ersten Post, 
die 2. verwendet den zweiten 4Zeiler vom ersten Beitrag.
Die erste Variante tut, die 2. net - ohne dass ich an der Schaltung oder 
im Rest des Programmes irgendwas verändere (das Relais ist in beiden 
Firmwares noch garnicht aktiv)

> Ich weiß ja nicht, wie das DDR_T1 steht und was das state.btT1 für ne
> Funktion hat und woran Du die Fehlfunktion erkennst (was der Unterschied
> zwischen Fehlfunktion und Funktion ist).

aus dem Grunde hatte ich den Auszug aus der config.h mit gepostet 
(erster unterlegter Bereich). DDR_T1 entspricht DDRD und state ist eine 
Struktur mit globalen Variablen, von denen eine btT1 heißt und ein 
Zähler ist.

Die betreffenden 4Zeiler werden im Timer-ISR abgearbeitet und haben den 
Sinn, für jeden Knopf einen Zähler hoch zu zählen, solange er gedrückt 
ist. Sobald der Knopf losgelassen wird (oder ein Low vom Prellen kommt), 
geht der Zähler auf 0.

In der Hauptprogramm-Schleife prüfe ich für jeden Taster, ob der Zähler 
einen (vorher festgelegten) Wert übersteigt. Wenn dies zutrifft, gilt 
die Taste als gedrückt und der entsprechende Zweig wird abgearbeitet.

> Die Schaltung wäre auch wichtig.

Ich habe die Schaltung mal nur für den Pin, um den es geht, gemalt 
(hatte keine Lust, das ganze Evalboard abzupinseln).
Wie durch die gestrichelten Ränder angedeutet, handelt es sich um 2 
Platinen, die über Flachbandkabel verbunden sind.
Bei dem 40pol-Adapter ist noch ein 100n-Blocker pro Stecker zwischen Vcc 
und Masse.

von Santiago (Gast)


Lesenswert?

Sorry, gerade erst entdeckt:

> Die 4 Zeilen sind syntaktisch in Ordnung.

wenn das so ist, könnte es sein, dass der 2. 4Zeiler zu lange braucht 
und der Timer nicht mehr richtig abgearbeitet werden kann?

von Oliver (Gast)


Lesenswert?

Dann zur Klarstellung:
Im zweiten Vierzeiler wird "state.btT1++;" ausgeführt, wenn das 
entsprechende Bit im DDR-Reg nicht 1 und der Tastereingang high ist, 
sonst "state.btT1 = 0;". Das wolltest du wohl auch so.

Mehr kann man den vier Zeilen nicht entnehmen, aber das beschriebene tun 
die ganz bestimmt.

Oliver
P.S. volatile ?

von Peter D. (peda)


Lesenswert?

Santiago wrote:
> aus dem Grunde hatte ich den Auszug aus der config.h mit gepostet
> (erster unterlegter Bereich). DDR_T1 entspricht DDRD

Ja, aber wann werden sie denn gesetzt/ausgewertet?


> und state ist eine
> Struktur mit globalen Variablen, von denen eine btT1 heißt und ein
> Zähler ist.

Das ging aber nicht aus dem config.h-Auszug hervor.

Ob Dein Code funktioniert, hängt davon ab, wann vor dem Abfragen der 
Taste das DDRD wie gesetzt wird. Und genau das sieht man immer noch 
nicht.


> Ich habe die Schaltung mal nur für den Pin, um den es geht, gemalt

Da sieht man schon viel klarer.
Der Taster ist also high-aktiv, was man vorher auch nicht wußte (Taster 
sind meistens low aktiv, um den Pullup zu sparen).
Ein Kondensater an nem Ausgang ist ein ganz böses Foul, da fließen dann 
immer riesige Umladeströme.
Und sobald man den Taster drückt, muß erstmal der Kondensator geladen 
werden, dieser Spannungseinbruch auf VCC könnte den brownout-reset 
auslösen.
Solange der Taster gedrückt ist, zieht das Relais, da ists wurscht, was 
der AVR macht.


Peter

von Santiago (Gast)


Lesenswert?

Hallo,

dank Euch beiden!

Die Bestätigung, dass mein 4Zeiler richtig ist, hat mich dann auf die 
Spur des Fehlers gebracht :)

Ich hatte in den letzten Tagen die Entwicklungsumgebung unter Linux 
eingerichtet und den Kwältext nur noch mit vim und make bearbeitet.
So hat sich ein Fehler eingeschlichen.

Und zwar geschah der Fehler bei der Initialisierung eines noch 
unbenutzten Tasters als Eingang:
1
   DDR_T3 |= (uint8_t) ~(1 << PIN_T3);

Ich habe zwar schon viel mit C gemacht, aber die ganzen Bitschiebereien 
habe ich seit der Ausbildung kaum verwendet. Deshalb ist an der Stelle 
wieder etwas Unsicherheit aufgekommen.

> Solange der Taster gedrückt ist, zieht das Relais, da ists wurscht, was
> der AVR macht.

Da muss ich dann wohl noch etwas in mich gehen ;)

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.