mikrocontroller.net

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


Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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???

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
...

int main()
{

  .... hier wird die Hardware initialisiert
  .... bzw. für variablen die Ausgangswerte eingestellt

  while( 1 ) {

     .... hier arbeitet das Programm

  }
}


> Welchen Fehler mach ich???

Du hast das Tutorial immer noch nicht gelesen.

Autor: Silvan König (silvan) Benutzerseite
Datum:

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

Falsch!

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

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

}
}
}

Autor: Silvan König (silvan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pull-down Widerstand

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
int main (void)
{
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
    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.

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht 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:
PORTC |= (1 << PC0);

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Andi (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

}
}
}

Autor: Sam .. (sam1994)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Thorsten Kühne (odysseus-dpb)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Thorsten Kühne (odysseus-dpb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Karl heinz Buchegger

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.