Forum: Mikrocontroller und Digitale Elektronik Pin ist Active Low, warum?


von vmni (Gast)


Lesenswert?

Moin,

Ich bin noch sehr neu in der µC Welt und versuche mich an ein paar 
ersten Blink Programmen.
Nun hab ich eine Art Blaulicht + Warnblinker simuliert und es 
funktioniert auch. Nur ein Problem gibt es, Ich habe Pin PC0 als Eingang 
konfiguriert und den internen Pull-Up Wiederstand deaktiviert. Ob der 
Pin aktiv ist frage ich folgendermaßen ab:
1
(PINC & (1 << 0))
Meiner Logik nach ist das
0b00000001   <-PINC-- PC7 - 1: Inaktiv | PC0: Aktiv
0bxxxxxxx1   <-Vergleich
0b1 = 1 = If Abfrage ist wahr.

Das Problem, mein Programm schaltet sich ab wenn ich den PIN auf GND 
ziehe.
Ziehe ich ihn auf VCC passiert nichts. Wie kann ich den Pin dazu 
konfigurieren das er High-Aktiv ist und nicht Low-Aktiv?

Und was noch wäre, die Programmlogik ist verkehrt. Mein Programm 
schaltet sich scheinbar ab wenn der Pin Low-Aktiv ist. Dabei soll es 
sich umgekehrt verhalten. Einschalten wenn Pin (High-Aktiv) und 
abschalten wenn Pin Low ist.

Das ganze Programm:
1
#define F_CPU 1000000
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
7
int main(void) {
8
9
#define F_CPU 1000000
10
11
#include <avr/io.h>
12
#include <util/delay.h>
13
14
15
int main(void) {
16
17
  DDRA = 0x0F;
18
  DDRC = 0x00;
19
  PORTC = 0x01;
20
21
  int x = 0;
22
23
  //LED TEST
24
  PORTA = 0x0F;
25
  _delay_ms(1000);
26
  PORTA = 0x00;
27
28
  while (1) {
29
30
    if (PINC & (1 << 0)) {
31
32
      _delay_ms(200);
33
      PORTA |= ((1 << 0) | (1 << 1));
34
      _delay_ms(60);
35
      PORTA &= ~((1 << 0) | (1 << 1));
36
      _delay_ms(60);
37
      PORTA |= ((1 << 0) | (1 << 1));
38
      _delay_ms(60);
39
      PORTA &= ~((1 << 0) | (1 << 1));
40
      _delay_ms(200);
41
      
42
      if (x == 0) {
43
        PORTA |= ((1 << 2) | (1 << 3));
44
        x++;
45
        } else {
46
        PORTA &= ~((1 << 2) | (1 << 3));
47
        x = 0;
48
      }
49
      } else {
50
      PORTA &= ~((1 << 0) | (1 << 1));
51
      PORTA &= ~((1 << 2) | (1 << 3));
52
    }
53
  }
54
  return 0;
55
}

Ich hoffe ich konnte mein Problem ausführlich und verständlich 
beschreiben :-(

Vielen Dank im Vorraus!

Viele Grüße
vmni

von Joachim B. (jar)


Lesenswert?

offener PIN bedeutet meist high, mehr high geht halt nicht, Abhilfe wäre 
ein pulldown zu schalten oder einzulöten.

Wobei ich immer einen externen pullup R vorziehen würde, Begründung:

1. Externe Pullups kann keiner per SW abschalten!
2. Pullups begrenzen den Strom sicher falls der Port mal out und low 
wird ohne den Port zu killen.

3. Die Abfrage auf Taste gedrückt = low = 0 ist nur ein Logikproblem und 
kein technisches, invertiere ich das Ergebnis kann ich wie immer 
addieren, ver-unden und alles wie immer machen.

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

vmni schrieb:
> Meiner Logik nach ist das
> 0b00000001   <-PINC-- PC7 - 1: Inaktiv | PC0: Aktiv
Was ist "Aktiv" und was "Inaktiv"?

> Wie kann ich den Pin dazu konfigurieren das er High-Aktiv ist und nicht
> Low-Aktiv?
High-Aktiv und Low-Aktiv ist alleine eine Frage der Definition. Dem uC 
ist es schnurzegal.
Um einen "High-Aktiven" Pin zu bekommen, fragst du ihn ab, ob er '1' ist 
und reagierst dann mit der gewünschten Aktion. Wenn er '0' ist, dann 
taust du nichts. Das wars...

Obe ien Pin High ist, wird mit

vmni schrieb:
> Das Problem, mein Programm schaltet sich ab wenn ich den PIN auf GND
> ziehe.
Wie schaltet es sich "ab"?

> Ziehe ich ihn auf VCC passiert nichts.
Und was passiert dazwischen? Ist der Pin einfach offen und darf tun, was 
er will?

BTW: für Tests nimm einfach einen Eingang und schalte direkt einen 
Ausgang. Ohne das ganze Zinnober drumrum...

von Wolfgang (Gast)


Lesenswert?

Joachim B. schrieb:
> offener PIN bedeutet meist high, mehr high geht halt nicht ...
Das ist definitiv falsch

Das mag vielleicht zu TTL-Zeiten so gewesen sein. Bei aktuellen µC ist 
ein offener Eingangspin erstmal ein nicht zulässiger Betriebszustand, 
weil der Eingang dann einen unerlaubten Spannungspegel annehmen kann.

Im Datenblatt von einem ATmega328 findet man z.B. bei 5V Betriebspannung 
für high einen zulässigen Bereich von 0.6VCC .. VCC+0.5V  und für low 
einen von -0.5V .. 0.3VCC. Der Bereich 0.3VCC .. 0.6VCC ist also nicht 
zulässig. Ein Mittel dagegen ist die Aktivierung des internen Pull-Up 
Widerstandes oder der Anschluss eines externen Pull-Up oder Pull-Down 
Widerstandes.

von vmni (Gast)


Lesenswert?

Lothar M. schrieb:
> Was ist "Aktiv" und was "Inaktiv"?
Nach meiner gewünschten Definition
Pin = Vcc: Aktiv
Pin = GND: Inaktiv

> High-Aktiv und Low-Aktiv ist alleine eine Frage der Definition. Dem uC
> ist es schnurzegal.
> Um einen "High-Aktiven" Pin zu bekommen, fragst du ihn ab, ob er '1' ist
> und reagierst dann mit der gewünschten Aktion. Wenn er '0' ist, dann
> taust du nichts. Das wars...
Aber das tue ich doch
1
if (PINC & (1 << 0))
Meiner Logik nach ist das
0b00000001  PINC
0bxxxxxxx1  & (1 << 0)
0b00000001  Ergebnis = Pin ist Aktiv.

Die Abfrage PINC ergibt doch an den Stellen eine 1 an denen die PINs mit 
Vcc verbunden sind.


>> Das Problem, mein Programm schaltet sich ab wenn ich den PIN auf GND
>> ziehe.
> Wie schaltet es sich "ab"?

Jau. Das Problem ist, das er beim Copy'n'Paste ausversehen die 
Kommentare nicht mit in den Post übernommen hat. Aber kurz gesagt, im 
else Block von der PIN Abfrage.
1
if (PINC & (1 << 0)) {
2
     [...]
3
} else {
4
      PORTA &= ~((1 << 0) | (1 << 1));
5
      PORTA &= ~((1 << 2) | (1 << 3));
6
    }

>> Ziehe ich ihn auf VCC passiert nichts.
> Und was passiert dazwischen? Ist der Pin einfach offen und darf tun, was
> er will?
Ist der Pin mit Vcc verbunden passiert nichts.
Ist der Pin mit GND verbunden wird die else Bedingung wahr und die 
Lämpchen gehen aus.

> BTW: für Tests nimm einfach einen Eingang und schalte direkt einen
> Ausgang. Ohne das ganze Zinnober drumrum...
Hatte ich schon, aber mir kam gerade ne Erleuchtung :D
Werde ich machen.

Viele Grüße
vmni

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

vmni schrieb:
> Ist der Pin mit Vcc verbunden passiert nichts.
Dann passiert [...]

vmni schrieb:
> Ist der Pin mit GND verbunden wird die else Bedingung wahr und die
> Lämpchen gehen aus.
Wenn die Lämpchen vom uC-Pin nach GND gehen.

von Joachim B. (jar)


Lesenswert?

Wolfgang schrieb:
> Joachim B. schrieb:
>> offener PIN bedeutet meist high, mehr high geht halt nicht ...
> Das ist definitiv falsch

offensichtlich nicht wenn der TO nach high ziehen keinen Unterschied 
bemerkt oder wie siehst du das?

Ich schrieb ja auch meist! und nicht immer ;)

von vmni (Gast)


Lesenswert?

Joachim B. schrieb:
> Wolfgang schrieb:
>> Joachim B. schrieb:
>>> offener PIN bedeutet meist high, mehr high geht halt nicht ...
>> Das ist definitiv falsch
>
> offensichtlich nicht wenn der TO nach high ziehen keinen Unterschied
> bemerkt oder wie siehst du das?
>
> Ich schrieb ja auch meist! und nicht immer ;)

Zum Test hab ich diesen etwas einfacheren Code verwendet
1
#define F_CPU 1000000
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
7
int main(void) {
8
9
  DDRA |= ((1<<0) | (1<<1) | (1<<2) | (1<<3));  // PA0-PA3: Ausgänge (LEDs)
10
  DDRC &= ~(1<<0);                // PC0: Eingang
11
  PORTC &= ~(1<<0);                // PC0: Kein PullUp
12
13
  //LED TEST
14
  PORTA |= ((1<<0) | (1<<1) | (1<<2) | (1<<3));
15
  _delay_ms(1000);
16
  PORTA &= ~((1<<0) | (1<<1) | (1<<2) | (1<<3));
17
18
  while (1) {
19
20
    if (PINC & (1 << 0)) {  // Wenn Eingang = Vcc
21
      PORTA |= ((1<<0) | (1<<1) | (1<<2) | (1<<3));
22
    } else {  // Wenn Eingang = GND
23
      PORTA &= ~((1<<0) | (1<<1) | (1<<2) | (1<<3));
24
    }
25
  }
26
  return 0;
27
}

Das Problem ist folgende:
Eingang mit Vcc verbunden: LEDs leuchten klar und deutlich.
Eingang freiliegend: LEDs leuchten wenig schwächer, flackern ganz 
leicht.
Eingang mit GND verbunden: LEDs sind ausgeschaltet.

Das was zu meiner Irretierung führte war, das ich einen Schalter Eingang 
= Vcc verbunden hatte. War der Schalter ein, war der Eingang mit Vcc 
verbunden und die LEDs leuchten. War der Schalter aus, schwebte der 
Eingang und war mit nichts verbunden, die LEDs gingen dennoch nicht aus.

Hab ich den Schalter allerdings mit GND verbunden, gingen die LEDs aus 
wenn der Schalter an war. War der Schalter aus, war der Eingang 
freiliegend und die LEDs gingen wieder an.

Der teilweise ausversehen aktivierte PullUp erschwerte die Fehlersuche 
insofern das er den freiliegenden Zustand der an den leicht flackernden 
LEDs erkennbar war, definitiv auf Vcc zog.

Das führte zu der Aktiv Low Annahme. In Wirklichkeit war der Eingang 
aber wie gewünscht Aktive High, nur das im unverbundenen Zustand des 
Eingang, der Eingang immernoch High war (auch ohne PullUp).

Lösungen fallen mir 2 ein:

1) Wechselschalter (Vcc/GND) statt normalen (Vcc/Getrennt)
2) PullDown Wiederstand

Aber eine Frage: Ist es wirklich normal das ein freiliegender Eingang 
der die "Spannung aus der Luft zieht" wirklich dazu führt das der 
Mikrocontroller die ganze Zeit high erkennt?

Zugegebenerweise: Mir war bewusst das ein freiliegender Eingang schonmal 
spontane "Zuckungen" haben kann. Aber ich dachte immer grundlegend low, 
spontane Vcc "Einfänge".

von uwe (Gast)


Lesenswert?

> Eingang freiliegend: LEDs leuchten wenig schwächer, flackern ganz
> leicht.

> Aber eine Frage: Ist es wirklich normal das ein freiliegender Eingang
> der die "Spannung aus der Luft zieht" wirklich dazu führt das der
> Mikrocontroller die ganze Zeit high erkennt?

> Aber ich dachte immer grundlegend low,
> spontane Vcc "Einfänge".

Der fängt sich halt alle möglichen FREQUENZEN ein(Radio, Fernsehen, 
Handy, WLAN,50Hz Netzbrumm, usw.). und die sind halt schneller als dein 
Auge gucken kann und die Amplitude geht halt mal Hoch mal Runter wenn 
die LEDs 50% der Zeit auf an waren und 50% der Zeit Aus dann leuchten 
die halt nur halb so Hell. Aber bei andren Modulationsformen als den 
50Hz Netzbrumm kann das An zu Aus verhältnis natürlich ständig wechseln 
deshalb das Flackern. UND NEIN undefiniert ist undefiniert, deshalb 
betreibt man keinen Eingang ohne Pullup oder Pulldown wenn man nicht 
wirklich dazu gezwungen wird. Und Lowaktiv ist einfach verbreiteter, 
Highaktive Steuersignale gibt es nur ganz selten, solltest du dich drann 
gewöhnen bzw. auch so machen wie alle anderen.

von uwe (Gast)


Lesenswert?

> Zugegebenerweise: Mir war bewusst das ein freiliegender Eingang schonmal
> spontane "Zuckungen" haben kann. Aber ich dachte immer grundlegend low,
> spontane Vcc "Einfänge"

Gutes Beispiel:
Schon mal das gedudel inKophörern oder anderen Musikanlagen gehabt wenn 
dich jemand auf deinem Handy angerufen hat?

von Possetitjel (Gast)


Lesenswert?

vmni schrieb:

> Aber eine Frage: Ist es wirklich normal das ein
> freiliegender Eingang der die "Spannung aus der
> Luft zieht" wirklich dazu führt das der
> Mikrocontroller die ganze Zeit high erkennt?

Selbstverständlich.

Darüberhinaus ist bei Leistungs-FETs ein schwimmendes
Gate russisches Roulette für den FET.

> Zugegebenerweise: Mir war bewusst das ein freiliegender
> Eingang schonmal spontane "Zuckungen" haben kann. Aber
> ich dachte immer grundlegend low, spontane Vcc "Einfänge".

Das gilt für Bipolartransistoren; deren Basis braucht ja
einen gewissen (wenn auch kleinen) Strom. Ein offenes Gate
dagegen macht, was es will.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

vmni schrieb:
> 2) PullDown Wiederstand
Gegenfrage: warum nimmst du nicht den Pullup des uC? Der ist genau dafür 
da...

> Aber eine Frage: Ist es wirklich normal das ein freiliegender Eingang
> der die "Spannung aus der Luft zieht" wirklich dazu führt das der
> Mikrocontroller die ganze Zeit high erkennt?
Schlimmer: er erkennt um die 50 mal pro Sekunde ein HIGH und ein LOW. 
Deshalb das Geflacker...

Possetitjel schrieb:
> Das gilt für Bipolartransistoren; deren Basis braucht ja einen gewissen
> (wenn auch kleinen) Strom.
Trotzdem gehört es auch dort zum guten Design, einen Leckstrom oder 
Kriechstrom mit einem BE Widerstand abzuleiten.

uwe schrieb:
> Lowaktiv ist einfach verbreiteter, Highaktive Steuersignale gibt es nur
> ganz selten
Das kommt noch aus der TTL Zeit, wo der Ausgangstreiber ein NPN 
Transistor war. Und aus der anschließenden CMOS Zeit, wo der N-Kanal Fet 
gegen GND niederohmiger war...

: Bearbeitet durch Moderator
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Gegenfrage: warum nimmst du nicht den Pullup des uC? Der ist genau dafür
> da...

Weil er offenbar gegen Vcc schaltet. D.h. er hat dann ein Dauer-High.

Die Logik seines Schalters umzudrehen und den Schalter gegen GND 
schalten zu lassen, den Pullup einzuschalten und dann das if() zu 
negieren, darauf ist der TO noch nicht gekommen...

Naja, es gibt immer ein erstes Mal... ;-)

: Bearbeitet durch Moderator
von uwe (Gast)


Lesenswert?

Achso das Lowaktiv kommt bestimmt noch von den TTLs 74xxx, da waren die 
Enable (Chip Select, Output Enable, Write Enable,...) alle Low aktiv. 
Wenn man nichts an den Eingang angeschlossen hat war das wegen des 
Designs von TTLs immer ein High. Wenn man kontaktprobleme hatte 
schalteten nicht irgendwelche Ausgänge von Tristate auf irgendeinen 
Pegel um, oder es aktivierten sich nicht von alleine irgendwelche Chips.
Das war ganz angenehm, hat sich ins Hirn Gebrannt und man hat sich halt 
daran gewöhnt, daß 0 meißtens halt aktiv bedeutet. deshalb ist das auch 
heute bei den meißten ICs so(auch wenn die auf CMOS Technologie basieren 
und der Eingang immer einen definierten Pegel haben muß).

von vmni (Gast)


Lesenswert?

Frank M. schrieb:
> Lothar M. schrieb:
>> Gegenfrage: warum nimmst du nicht den Pullup des uC? Der ist genau dafür
>> da...
>
> Weil er offenbar gegen Vcc schaltet. D.h. er hat dann ein Dauer-High.
>
> Die Logik seines Schalters umzudrehen und den Schalter gegen GND
> schalten zu lassen, den Pullup einzuschalten und dann das if() zu
> negieren, darauf ist der TO noch nicht gekommen...
>
> Naja, es gibt immer ein erstes Mal... ;-)

Doch schon ;)
Ist ja ziemlich naheliegend.

Allerdings wollte ich nicht einfach nur das Symptom bekämpfen sondern 
auch den Grund der Ursache für das scheinbare Fehlverhalten erfahren.

Hab ich ja jetzt: Das mein freiliegender Pin als eine Antenne fungiert. 
Und das mehr als erwartet.

Wie gesagt, ich hab eher einen Fehler in meiner Programmlogik erwartet 
als das es einfach an dem schwebenden Pin liegt.

Da hätte ich noch ne Frage, lässt sich das messen?
Hab probehalber einfach den Pin ein kleines Stück hervorgezogen 
(Steckbrett) und dann versucht gegen Masse die Spannung zu messen.

Herauskam: Nichts. Aber das könnte auch an meinem sowieso defekten 
Baumarkt Multimeter liegen. Ein neues, qualitatives soll in Kürze 
angeschafft werden (Fluke?).

Grüße
vmni

von Wolfgang (Gast)


Lesenswert?

vmni schrieb:
> Herauskam: Nichts.

Kein Wunder. Die Ladung vom Gate ist über das Multimeter innerhalb von 
Mikrosekunden abgeflossen. Danach war da natürlich nichts mehr zu 
messen.

von Timo N. (tnn85)


Lesenswert?

Das wirst du nicht messen können. Auch mit einem sehr guten Multimeter 
mit sehr hohem Eingangswiderstand (>10 MOhm) nicht.

von vmni (Gast)


Lesenswert?

Wolfgang schrieb:
> vmni schrieb:
>> Herauskam: Nichts.
>
> Kein Wunder. Die Ladung vom Gate ist über das Multimeter innerhalb von
> Mikrosekunden abgeflossen. Danach war da natürlich nichts mehr zu
> messen.

Jo, danke euch allen :)
Alle Fragen ersteinmal geklärt.

Schönen Abend
vmni

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.