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
intmain(void){
8
9
#define F_CPU 1000000
10
11
#include<avr/io.h>
12
#include<util/delay.h>
13
14
15
intmain(void){
16
17
DDRA=0x0F;
18
DDRC=0x00;
19
PORTC=0x01;
20
21
intx=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
return0;
55
}
Ich hoffe ich konnte mein Problem ausführlich und verständlich
beschreiben :-(
Vielen Dank im Vorraus!
Viele Grüße
vmni
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.
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...
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.
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
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.
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 ;)
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
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".
> 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.
> 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?
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.
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...
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... ;-)
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ß).
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
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.
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