Forum: Mikrocontroller und Digitale Elektronik Problem mit Eingang abfragen :(


von Andi (Gast)


Lesenswert?

Hallo,

hab da mal wieder ein Problemchen, wollte gerade einen Eingang abfragen 
und dann ne LED zum leuchten bringen.

Dabei werden PB0 welcher als Ausgang gesetzt ist und PC0 welcher als 
Eingang deklariert gebrückt. Also bekomm ich direkt 5V von PB0 auf PC0. 
Dies soll dann eine LED welche an PB1 angeschlossen ist zum leuchten 
bringen.

Hier mal der Code:

#include <avr/io.h>




int main (void)
{
DDRC &= ~(1<<PC0); //Pin C1 als Eingang setzen
PORTB |= (1<<PB0); //Pin B0 auf Ausgang und High setzen


if ( !(PINC & (1<<PINC0)) ) { //Abfrage ob an Pin C0 5V anliegen


   PORTB |= (1<<PB1); // Pin PB1 auf High
}
else
{
    PORTB &= ~(1<<PB1); //Pin PB1 auf Low
}
}


Welchen Fehler mach ich???

von Karl H. (kbuchegg)


Lesenswert?

Andi schrieb:

> int main (void)
> {
> DDRC &= ~(1<<PC0); //Pin C1 als Eingang setzen
> PORTB |= (1<<PB0); //Pin B0 auf Ausgang und High setzen



Ähm.
Du weisst aber schon, dass der Default-Zustand der Ports lautet: Alles 
ist ein Eingang.
Ausserdem hast du immer noch keine Endlosschleife, so dass der 
arbeitende BLock immer wieder abgearbeitet wird.


Ausnahmslos jedes Programm auf einem AVR hat minimal diese Struktur:
1
...
2
3
int main()
4
{
5
6
  .... hier wird die Hardware initialisiert
7
  .... bzw. für variablen die Ausgangswerte eingestellt
8
9
  while( 1 ) {
10
11
     .... hier arbeitet das Programm
12
13
  }
14
}


> Welchen Fehler mach ich???

Du hast das Tutorial immer noch nicht gelesen.

von Silvan K. (silvan) Benutzerseite


Lesenswert?

Andi schrieb:
> DDRC &= ~(1<<PC0); //Pin C1 als Eingang setzen
> PORTB |= (1<<PB0); //Pin B0 auf Ausgang und High setzen

Falsch!

1
DDRB |= (1<<PB0);  //Pin B0 als Ausgang
2
PORTB |= (1<<PB0); //Pin B0 High setzen
3
// DDRC &= ~(1<<PC0);  //Pin C0 ist nach POR automatisch 0

von Andi (Gast)


Lesenswert?

Erstmal danke für die Antwort und Sorry wenn ich mich zu blöd anstelle.

Aber ich kapiers nicht im Tutorial wirds doch auch nicht anders gemacht 
als in meinem Programm.
Hab jetzt noch die While Schleife eingefügt und auch die anderen 
Ratschläge berücksichtigt.
Irgendwie leuchtet die led jetzt egal ob die brücke gesteckt ist oder 
nicht :)

#include <avr/io.h>




int main (void)
{

DDRB |= (1<<PB0);
DDRB |= (1<<PB1);
while (1) {
PORTB |= (1<<PB0); //Pin B0 auf Ausgang und High setzen



if ( PINC & (1<<PINC0) )  { //Abfrage ob an Pin C0 5V anliegen


   PORTB |= (1<<PB1); // Pin PB1 auf High
}
else
{
    PORTB &= ~(1<<PB1); //Pin PB1 auf Low

}
}
}

von Silvan K. (silvan) Benutzerseite


Lesenswert?

Pull-down Widerstand

von Karl H. (kbuchegg)


Lesenswert?

Andi schrieb:
> Erstmal danke für die Antwort und Sorry wenn ich mich zu blöd anstelle.
>
> Aber ich kapiers nicht im Tutorial wirds doch auch nicht anders gemacht
> als in meinem Programm.

Nochmal.

Wenn der µC Strom bekommt und dein Programm losläuft, sind bereits alle 
Ports auf Eingang geschaltet. Das ist der Default-Zustand. In diesem 
Zustand erhält dein main() die Kontrolle

Das du hier
1
int main (void)
2
{
3
DDRC &= ~(1<<PC0); //Pin C1 als Eingang setzen

den Pin PC0 auf Eingang setzt, ist zwar löblich, aber eigentlich ist der 
bereits auf Eingang geschaltet.

Du musst aber auf jeden Fall jeden Pin, den du als Ausgangspin verwenden 
willst, auf Ausgang schalten (über das DDR Register) und das tust du 
nicht!

Das hier
1
    PORTB |= (1<<PB0); //Pin B0 auf Ausgang und High setzen
schaltet den Pin nicht auf Ausgang!
Das schaltet den Pin, sofern er auf Ausgang gestellt ist auf 1. Aber 
dazu muss er erst einmal als Ausgangspin definiert werden!


> Irgendwie leuchtet die led jetzt egal ob die brücke gesteckt ist
> oder nicht :)

Deine Alternativen sind daher:
Die Brücke ist gesteckt und die 1 vom Ausgangspin steuert den 
Eingangspin auf 1
Aber: Wenn die Brücke nicht gesteckt ist, heißt das nicht automatisch, 
dass der Eingangspin dann 0 ist! Ein Eingang der nicht aktiv angesteuert 
wird (und der keinen Pullup Widerstand geschaltet hat) kann entweder 0 
oder 1 sein, je nachdem wie weit dein Fernseher entfernt ist, heute 
Vollmond ist bzw. wieviele Bier noch in deinem Eiskasten sind.
Man lässt einen Eingangspin niemals unbeaufsichtigt! Der darf nie 
einfach so in der Luft hängen. Denn dann tut er genau das: Er saugt sich 
jedes noch so kleine elektromagnetische Feld aus der Luft und schaltet 
unkontrolliert damit auf 0 oder 1.

von Sam .. (sam1994)


Lesenswert?

Ich hoffe dein Schaltung sieht so aus: PORTC0 --- Taster ---- GND
Dann sollte die LED-Standardmäßig leuchten und wenn der Taster gedrückt 
wird sollte sie aus sein.
Im µC mss dafür allerdings der PullUp aktiv sein. Wenn der nicht an ist, 
liegt ein undefinierter Zustand am Pin wenn der Taster nicht gedrückt 
ist.
Das würde man so machen:
1
PORTC |= (1 << PC0);

PS: Eine Einrückung wäre hilfreich, dann kann man den Code besser lesen.

von Karl H. (kbuchegg)


Lesenswert?

Samuel K. schrieb:
> Ich hoffe dein Schaltung sieht so aus: PORTC0 --- Taster ---- GND

Viel perverser.
Er hat PC0 mit PB1 mit einer Drahtbrücke verbunden. PB1 setzt er auf 0 
und versucht dann den Potr zu schalten, indem er die Drahtbrücke 
entfernt bzw. ansteckt.

Wozu auch immer das gut sein soll.

von Andi (Gast)


Lesenswert?

Also erst einmal danke euch allen es funktioniert jetzt lag am Port. Pin 
C0 hat dauerhaft 5V Ausgang geschalten weiß auch nicht wieso. Hab jetzt 
den Eingang auf D7 gelegt und es funktioniert.

Hier mal der Code falls jemand mal genau so doofe Sachen machen will wie 
ich :)

#include <avr/io.h>



int main (void)
{


DDRB  = 0xff;
PORTB = 0x02;
PORTD |= (1 << PD7);




while (1) {
PORTB |= (1<<PB1); //Pin B0 auf Ausgang und High setzen



if ( PIND & (1<<PIND7) )  { //Abfrage ob an Pin C0 5V anliegen


   PORTB |= (1<<PB0); // Pin PB1 auf High
}
else
{
    PORTB &= ~(1<<PB0); //Pin PB1 auf Low

}
}
}

von Sam .. (sam1994)


Lesenswert?

Andi schrieb:
> PORTD |= (1 << PD7);

Wegen dem hier funktioniert es. Das geht auch mit PortC. Wenn nicht ist 
dein µC kaputt.

Einrückung schadet trotzdem nicht. glaub mir, es ist eine Qual sich 
durch deinen Code zu wühlen.

von Peter D. (peda)


Lesenswert?

Andi schrieb:
> Also erst einmal danke euch allen es funktioniert jetzt lag am Port. Pin
> C0 hat dauerhaft 5V Ausgang geschalten weiß auch nicht wieso. Hab jetzt
> den Eingang auf D7 gelegt und es funktioniert.

Guck mal, welchen AVR Du hast, manche haben auf PORTC das JTAG.


Peter

von Thorsten K. (odysseus-dpb)


Lesenswert?

Hallo

Ich habe auch ein ähnliches Problem wie "Andi".
Ich wollte einen Eingang auf einen Ausgang legen.
Wenn ich den Eingang auf High setz geht die Led am Ausgang wie gewünscht 
aus.
Wenn ich jedoch den Eingang nicht belege oder ihn auf Low lege, geht die 
Led nach 50 ms An und nach weiteren 50 ms wieder Aus. Und das so lange 
bis ich den Eingang wieder auf High setze.

Ich verwende folgendes Programm welches ich in Bascom geschrieben habe.
Habe es auch mit einen Attiny 13 versucht. Ohne Erfolg. Vor etwa einen 
Halben Jahr ging jedoch alles noch ohne Problemme?!

$regfile = "attiny2313.dat"
 Ddrb = &B00110000
Portb = &B11001000

Do

If Pinb.0 = 0 Then Pinb.2 = 1
If Pinb.0 = 1 Then Pinb.2 = 0

Waitms 50
Loop

Könnt ihr mit sagen wo mein Problemm bzw Fehler liegt?
Schonmal Danke im Vorraus!

von Karl H. (kbuchegg)


Lesenswert?

Thorsten Kühne schrieb:

> Ich habe auch ein ähnliches Problem wie "Andi".

Nicht wirklich

> Ich wollte einen Eingang auf einen Ausgang legen.

Dann tu das

> Wenn ich den Eingang auf High setz geht die Led am Ausgang wie gewünscht
> aus.


> $regfile = "attiny2313.dat"
>  Ddrb = &B00110000

UNd jetzt schaust du mal, was deine Pins machen.
Welches BIt ist für Pinb.0 zuständig (das 0-te von rechts)
und welches ist für Pinb.2 zuständig

Alle Pins, die du als Eingang verwenden willst, müssen dort eine 0 haben
Alle Pins, die du als Ausgang verwenden willst, müssen dort eine 1 haben

Die 0 für Pinb.0, also den Eingang, sehe ich.
Aber die 1 für Pinb.2 sehe ich nicht.

Dafür sehe ich jede Menge anderer 1-er, deren entsprechenden Pins im 
Programm aber gar nicht benutzt werden!

> Portb = &B11001000

Für alle Eingangspins legt das Port Register fest, ob dort ein Pullup 
eingeschaltet werden soll.
Bei deinem Eingangspin ist das mehr als ratsam, da du ja den Pin 
zwischendurch auch schon mal offen lässt. Der Pullup sorgt dann dafür, 
dass sich dieser Eingangspin nicht einfach jedes beliebige 
elektromagnetische Feld aus der Umgebung krallt und das je nach Lust, 
Laune, Wasserstand der Donau und Mondphase entweder als 0 oder als 1 
interpretiert, sondern dass auch in diesem Fall, der Pin einen 
definierten 1 Pegel annimmt.

Nur: Dazu muss der Pullup eingeschaltet werden!
Dazu muss eine 1 an die entsprechende Bitposition für einen Eingangspin.

Bei dir ist da aber für Pin 0 keine 1 eingetragen. Der Pullup ist daher 
nicht eingeschaltet und der Pin .... nimmt, wenn du ihn offen lässt 
zufällig mal 1 und mal 0 an.

Ergo: Pullup einschalten!

> Do
>
> If Pinb.0 = 0 Then Pinb.2 = 1
> If Pinb.0 = 1 Then Pinb.2 = 0

Seit wann werden denn Ausgnänge geschaltet, indem man dem Pin Register 
etwas zuweist?
Pin.. ist für die Eingänge zuständig. Für die Ausgänge ist das das 
Port.. Register.

von Thorsten K. (odysseus-dpb)


Lesenswert?

Hallo Karl heinz Buchegger

Danke für deine schnelle Hilfe.
Habe mein Programm entsprechend deinen Vorschlägen geändert. Jetzt geht 
es endlich.

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.