PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Pins Abfrage



crusico
21.01.2009, 09:11
Hi to @ll,

ich will folgendes:

wenn die Pins PC0=1 und PC2=0 dann LED an PC4 an.
Problem ist nur, das PC0 ein Ausgang ist!

Wenn ich das so progg, das PC0 als Eingang ist und ich mit


if ((PINC&0x05)==4) { /* Pin PC0=1 und PC2=0 dann... */

funktioniert es. Aber, wenn ich jetzt PC0 als Ausgang habe, klappt es leider nicht. Darf man für diese Abfrage nur Pins Eingänge benutzen?

Ich habe mal eine LED an PC0 angeschlossen und wenn ich PC3 drücke leuchtet die LED schwach.


So sieht mein Code aus, leider Funktioniert es nicht.
Was mache ich falsch?


#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>
#define F_CPU 8000000 // clock

int main(void) {
DDRC = (1<<PC0); /* Pin PC0 als Ausgang für Drehen Links */
DDRC = (1<<PC4); /* Pin PC4 als Ausgang für Led */

DDRC &= (~ (1<<PC2)|(1<<PC3)); /* Pin PC3 und PC2 als Eingang */
PORTC |= (1<<PC2)|(1<<PC3); /* Pull Up von PIN PC3 und PC2 aktivieren */
for(;;){

if (!( PINC & (1<<PINC3))) { /* mache was wenn PinC3 low ist */
PORTC|=(1<<PC0);
}
else{
PORTC&= ~(1<<PC0);
}

if ((PINC&0x05)==4) { /* Pin PC0=1 und PC2=0 dann... */
PORTC|=(1<<PC4);
}
else{
PORTC&= ~(1<<PC4);
}

}
}

askazo
21.01.2009, 09:34
Bei einem Ausgangs-Pin nützt Dir das PIN-Register gar nichts.
Allerdings steht der aktuelle Status eine Ausgangspins im PORT-Register - das wird schließlich auch von Dir gesetzt, um den Pin zu steuern.
Und das PORT-Register kannst Du auch auslesen, um den Status eines Ausgangs abzufragen.

Gruß,
askazo

sternst
21.01.2009, 09:41
Bei einem Ausgangs-Pin nützt Dir das PIN-Register gar nichts.

Auch bei einem Ausgang kann man über das PIN-Register den aktuellen (externen) Zustand des Pins einlesen.

crusico
21.01.2009, 09:44
Danke für die Info, aber wie mache ich das jetzt genau...
Über bischen Hilfe wäre ich sehr Dankbar!

sternst
21.01.2009, 09:47
if ((PINC&0x05)==4) { /* Pin PC0=1 und PC2=0 dann... */

Code und Kommentar passen hier nicht zusammen. Für PC0=1 und PC2=0 wäre der Wert von (PINC&0x05) 1, nicht 4.

crusico
21.01.2009, 09:55
ups, hast recht sternst. mein Fehler.
Funktioniert trotzdem nicht!

PC4 leutet immer wenn ich PC2 drücke.
Normal darf PC4 nur leuten, wenn PC0 auch noch auf 1 ist.

sternst
21.01.2009, 10:08
Liegt vermutlich daran, dass PC0 gar kein Ausgang ist, und damit dort gar nicht der Pegel ist, der dort eigentlich sein sollte.

DDRC = (1<<PC0); /* Pin PC0 als Ausgang für Drehen Links */
DDRC = (1<<PC4); /* Pin PC4 als Ausgang für Led */
Die Einstellung der ersten Zeile wird durch die 2. Zeile wieder überschrieben.

Jaecko
21.01.2009, 10:14
Ist dieser Chip noch "jungfräulich"? Dann kanns sein, dass dort auf PORT C der übliche Verdächtige namens JTAG aktiv ist. Der krallt sich da dann ein paar der Pins, die man dann nicht verwenden kann.

thewulf00
21.01.2009, 10:22
Wie sternst geschrieben hast, musst Du die beiden Zeilen "oderhaft" benutzen:
DDRC |= ...

crusico
21.01.2009, 10:44
Der Chip ist "jungfräulich", wie kann ich das mit den Pins ändern?

Ich habe mal dieses hier versucht weil PC3 ja auch als Eingang ist:

if ((PINC&0x0D)==1) { /* Pin PC0=1 und PC2=0 " PC3" dann... */

und jetzt leuchtet die Led, wenn ich PC2=1 und PC3=1 ist.
(Leider nicht PC0=1 und PC2=0)
Oder muss ich den PINC&0x0D anderes definieren?

AH,

sehe grade das an Board, wenn ich die Tasten drücke es auf 0V gezogen wird und nicht 5V raus gibt, muss eben den Eingang negieren, mal sehen ob es dann klappt

crusico
21.01.2009, 11:14
Mal eine "dumme" Frage, wenn ich abfragen will ob bei PC3 Eingang high Signal liegt, wie sieht der Code aus?

So:

if (PINC & (1<<PINC3)) { /* mache was wenn PinC3 high ist */

Jaecko
21.01.2009, 11:17
if (PINC & (1<<PINC3)) ist dann wahr, wenn in PINC das Bit PINC3 gesetzt ist. Also stimmt so.
Zum JTAG abschalten gibts da was in den Fusebits. Wo die sind, hängt von deiner Programmiersoftware ab.

crusico
21.01.2009, 11:26
mh, wenn ich aber das hier schreibe:

if (PINC & (1<<PINC3)) { /* mache was wenn PinC3 high ist */
PORTC&= ~(1<<PC0);
}
else{
PORTC|=(1<<PC0);
}

Leuchtet die LED nur, wenn ich 0V an Eingang PC3 habe!
Ich dachte die Led leuchtet wenn ich 5V an PC3 Eingang habe?

Jaecko
21.01.2009, 12:30
Was das Programm macht, kommt drauf an, wie der Schalter angeschlossen ist, und wie die LED angeschlossen ist.

Wenn der Pin beim Drücken auf High geht, wird in der if der Pin auf Low gesetzt. Je nach dem, wie dann die LED angeschlossen ist (von Pin nach Masse oder von 5V nach Pin) leuchtet die LED dann oder nicht.

Also einfach mal die beiden Anweisungen austauschen oder die if-Anweisung negieren: if (!(PINC & (1<<PINC3)))

crusico
22.01.2009, 06:47
Hi,

ich verstehe es irgendwie nicht :-(

Also, 1 Taster der 5V zum Eingang schaltet.
1 Ausgang wo eine Led mit Vorwiederstand gegen 0V ist.

Wenn ich das Programm so schreibe:


int main(void) {
DDRC |= (1<<PC0); /* Pin PC0 als Ausgang für Drehen Links */
DDRC &= (~ (1<<PC3)); /* Pin PC3 als Eingang */
PORTC |= (1<<PC3); /* Pull Up von PIN PC3 aktivieren */
for(;;){

if (PINC & (1<<PINC3)) { /* mache was wenn PinC3 high ist */
PORTC&= ~(1<<PC0);
}
else{
PORTC|=(1<<PC0);
}

}
}

oder wenn ich die if abfrage negiere, tut sich nichts!

Wenn ich aber den Schalter 0V durchschalte, dann ja. <-- warum das?

Oder definiere ich an Anfang das der Eingang schon 5V hat?

Jaecko
22.01.2009, 07:16
Sicher dass der Taster beim Drücken 5V anlegt? Dann bringts nichts, den Pullup einzuschalten; in dem Fall sind sonst immer 5V am Pin. Entweder vom internen Pullup oder vom Taster aussen.

Wenn der Pullup verwendet werden soll und der Taster auf Masse schalten soll, dann würde die if stimmen, d.h. beim Drücken des Tasters ist die if-Abfrage falsch (weil der Pin am Taster Low ist) und die Anweisung im else-Teil wird ausgeführt (C0 einschalten => LED leuchtet).

Falls er bei 5V schaltet, dann wird C0 in der if auf Low gesetzt: PORTC&= ~(1<<PC0); d.h. die LED geht aus, da dann an beiden LED-Anschlüssen 0V anliegen.

Also dein Programm mal kommentiert:


if (PINC & (1<<PINC3)) // PinC3 = High = 5V?
{
PORTC&= ~(1<<PC0); // Wenn ja: PC0 = Low, LED = Aus
}
else
{
PORTC|=(1<<PC0); // Wenn nein: PC0 = High, LED = An
}

crusico
22.01.2009, 07:54
Also wenn ich das Programm rüberschicke und dann an den Pin PC3 messe liegt dort schon 5V an ohne das ich den Taster angeschlossen habe!

Dann ist das ja klar, das ich einen Taster gegen Masse schalten muss. Das Funktioniert auch!

Aber ich will nicht gegen Masse schalten sondern +5V.

Wenn ich denn Pullup ausschalte, (Led leutet wann es will) funktioniert das ganze nicht, aber led geht dann auch an, wenn ich den Taster gegen masse verbinde!

Jaecko
22.01.2009, 08:01
Wenn du jetzt gegen Masse schaltest, macht das Programm genau das, was drinsteht. Wenn du gegen 5V schalten willst, musst du den internen Pullup ausschalten und aussen am Pin einen Widerstand gegen Masse schalten.
Wenn der Taster nicht gedrückt ist und der interne Pullup aus ist, nimmt der Pin irgend einen zufälligen Pegel an. Das Kabel des Tasters (und wenns auch noch so kurz ist) wirkt da als Antenne. Da reichts, wenn man mal dran vorbeiläuft; der Pin fängt sich irgend ne Ladung ein und wechselt undefiniert.

Darum einfach z.B. nen 1k...10k Widerstand nach Masse, dann ist der definiert auf 0V. Über den Taster lässt sich das dann auf 5V schalten.
Dann kanns noch sein, dass die beiden Anweisungen in der if-Abfrage umgetauscht werden müssen (Also wenn die LED beim Nicht-Drücken leuchtet und beim Drücken ausgeht)

crusico
22.01.2009, 08:12
danke! ich werde es mal gleich testen und Bericht erstatten.

OK, hat geklappt!

Also wenn ich Pull Up intern aktiv ist, muss ich gegen masse schalten.

Wenn ich Pull Up deaktiv habe, muss ich einen Wiederstand gegen masse schalten.

Thx!

crusico
22.01.2009, 08:51
Eine Frage noch, ist das hier richtig?

if ((PINC&0x0A)==8) { // Wenn PC3=1 und PC1=0 dann...
weil bei mir klappt es leider nicht oder habe ich da noch ein Denkfehler?

Jaecko
22.01.2009, 08:57
Wenn der Smiley der Wert 8 und ne schliessende Klammer ist, müsste das eigentlich so stimmen.
Ne längere Version wäre:
if (PINC & (1 << PC3)) && (!(PINC & (1 << PC1)))

crusico
22.01.2009, 09:05
ist eine Klammer mit 8, aber das funktioniert bei mir nicht.

Bei deiner If ist noch ein Fehler (wird bei mir angezeigt) drin.
Fehlt noch eine Klammer?



if ((PINC & (1 << PC3)) && (!(PINC & (1 << PC1))))

Jaecko
22.01.2009, 09:25
Upsa joa *g*. Um die beiden Ausdrücke fehlt noch ne Klammer, damits für das if als 1 Ausdruck aussieht.

Das mit den Smileys geht dann, wenn die Antwort nicht über "Kurz Antwort" erstellt wird sondern ganz unten über "Antwort erstellen". Da müsste dann eine Schaltfläche sein, wo man Smileys deaktivieren kann.

crusico
22.01.2009, 10:10
ok, danke für alles Jaecko!

So nun muss ich mal in Forum nach Zeitschleife suchen...das mann solange einen Ausgang bekommt nach Zeit, egal wie lange mal Taster drückt.