PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Anfänger-Problem mit Eingangsabfrage



fuxx
04.08.2009, 09:33
Hallo zusammen,
Ich habe leider schon wieder ein Problem. Ich versuche den Status eines Eingangs abzufragen, aber das will nicht so klappen.

Ich möchte testweise in einer Endlosschleife einen Eingang abfragen, und falls dieser gesetzt ist, eine Aktion durchführen

Das Problem: Wenn ich den Status des Eingangs verändere und danach den Controller "resete", funktioniert es, den Ausgang auf High/Low zu setzen aber nicht im Verlauf des Programms. Hab auch schon verschiedene Endlosschleifen versucht. Alles nichts genützt.

Hier mein Program:
#include "asuro.h"
#include <avr/io.h>
#include "iom8.h"
#include <stdlib.h>
#include <avr/delay.h>
#include <inttypes.h>

int main(void)
{

DDRD = 0xff;
DDRB = 0x00; //PB als EIngang
PORTB = 0xff; //internen PULL-UP einschalten
while (1) {
if (PINB & (1<<PINB0))
PORTD = (1<<PD3);
}
}

021aet04
04.08.2009, 09:50
if (PINB & (1<<PINB0))


Probier es mit einer While Schleife
while (PINB & (1<<PINB0)) PORTD = (1<<PD3);
oder
while (PINB & (1<<PB0)) PORTD = (1<<PD3);

Das 2te sollte funktionieren. So haben wir es in der Schule gemacht.

markusj
04.08.2009, 09:51
Du sollst die Headerfiles unter "ioXXXX.h" nicht includen, also insbesondere nicht ""iom8.h" - das erledigt <avr/io.h> automatisch für dich.

Ob da noch irgendwelche andere C-Fallstricke versteckt sind, kann ich jetzt aufs erste nicht erkennen ...

mfG
Markus

Edit: Punkt zwei wurde gestrichen, weil grob falsch ...

fuxx
04.08.2009, 10:06
Habe jetzt ioXXXX.h entfernt und die Schleifen so nachgebaut wie 021aet04 gesagt hat, leider ohne Erfolg bzw mit Reseten gehts wieder aber nicht während dem Betrieb. Gibt es noch andere Gründe, an denen es liegen kann?

oberallgeier
04.08.2009, 10:09
... Status eines Eingangs abzufragen ... will nicht so klappen
Die fehlerhafte Aktion mit der ioXXXX.h hat markusj schon beanstandet. Daher wundert es mich, dass Dein Compiler das korrekt übersetzt. Hast Du beim Hexfile schon aufs Datum geschaut? Ob das nicht einer ist, der früher mal erstellt wurde (<< ist ein beliebter Fehler, tritt bei mir öfters nach Mitternacht auf *ggg*).

Der folgende Code (-schnipsel) läuft bei mir mit ähnlichen Portinitialisierungen auf (m)einem mega168.


// Pins/Ports als Ein- (0) oder Ausgänge (1) konfigurieren, Pull Ups (1) aktivieren
// A = Ausgang, E = Eingang ohne , EU = Eingang MIT PullUp
DDRB = 0b10011111; // siehe aktuell oben oder Fortschritt/R2D2
PORTB = 0b01100000; // und Port/Pull Ups (1) aktivieren
. . . . . . .
// ================================================== ===============================
. . . . . . .
/* while (1)
{ if ( ! (PINB & (1 << PINB5)) ) // Taste abfragen auf SCK
{ PORTC |= (1<<PC4); } // LED auf PC4/MISO einschalten
else
{ PORTC &= ~(1<<PC4); } // LED auf PC4/MISO ausschalten
oder: if ( PIND & ( 1<<PIND2 ) ); // mache was wenn PinD2 High ist
}
*/

Übrigens: geposteter Code sieht viel besser aus, wenn man ihn in [Code]-Tags packt.

Viel Erfolg.

sast
04.08.2009, 10:25
Die Frage ist, was du als Ergebnis haben willst.

Wenn sich der Zustand des Ausgangs mit dem Zustand des Eingangs ändern soll, dann musst du auch den Ausgang wieder zurück setzen.

Das ist bei Joe's Codeschnipsel gut zu sehen.

Bisher hattest du nur einmal den Ausgang gesetzt und dann passiert natürlich auch nichts mehr wenn PB0 nicht 1 ist. Der Ausgang setzt sich nicht allein zurück.

sast

markusj
04.08.2009, 11:06
Wenn sich der Zustand des Ausgangs mit dem Zustand des Eingangs ändern soll, dann musst du auch den Ausgang wieder zurück setzen

Damn, du hast recht - hatte ich zuerst auch in meinem Beitrag angekreidet und dann in einem Anfall geistiger Umnachtung wieder rausgenommen ...

@fuxx: Der zweite Teil deiner Fallunterscheidung fehlt - du setzt zwar den Ausgang auf High, aber wenn die Fallunterscheidung "false" ergibt, tust du genau - nichts, wie du beobachtet hast.

Korrigiert sähe es etwa so aus:


#include "asuro.h"
#include <avr/io.h>
#include <stdlib.h>
#include <avr/delay.h>
#include <inttypes.h>

int main(void) {
DDRD = 0xff;
DDRB = 0x00; //PB als EIngang
PORTB = 0xff; //internen PULL-UP einschalten
while (1) {
if (PINB & (1<<PINB0)) {
PORTD = (1<<PD3);
} else {
PORTD = 0x00;
}
}
}

mfG
Markus

Edit: Nachtrag, die Variante mit der Schleife ist ziemlicher Käse, solange wie die Bedingung erfüllt ist, rennt das Teil im Kreis - wenn du noch was anderes tun willst, gute Nacht ...

oberallgeier
04.08.2009, 12:40
Hi,

EINE Frage wäre natürlich noch zu stellen, sie ist hardwareorientiert: Wird der Tastenpin wirklich auf GND gezogen? Nichts für ungut, dass ich das frage. Ansonsten - bekomme ich nur riesige Nebenwirkungen (Bauch- Augen- und Kopfschmerzen) bei so waghalsiger Klammernsetzung wie eben. Aber ich bin eben noch ziemlicher Anfänger in C.

markusj
04.08.2009, 12:50
Ansonsten - bekomme ich nur riesige Nebenwirkungen (Bauch- Augen- und Kopfschmerzen) bei so waghalsiger Klammernsetzung wie eben. Aber ich bin eben noch ziemlicher Anfänger in C.

Darf ich fragen, bei wem die Klammersetzung waghalsig ist?
Die Klammersetzung ist auch teilweise Geschmackssacke, es lohnt sich, einen einheitlichen Stil für sich selbst zu finden, ich bin inzwischen (Universitär begründet) bei einem Stil der den Java Code Conventions folgt angekommen.
Editoren mit Auto-Formatter sind da etwas feines ...

mfG
Markus

oberallgeier
04.08.2009, 13:14
... Klammersetzung ist auch teilweise Geschmackssacke ... ich bin inzwischen (Universitär begründet) ...Ok, ich nehme alles zurück. Bin nur ein Simpel von hinterm Wald. Mit entsprechend simplem Geschmack.

sast
04.08.2009, 13:20
Das mit den Klammern ist schon ok.

Was mir aufstößt, ist der else Zweig. Anstatt nur ein Bit zurückzusetzen, setzt du gleich den ganzen Port auf 0. Das mag bei dieser Anwendung noch so funktionieren, sollte man sich aber gar nicht erst angewöhnen. Joe's Variante ist die elegantere.

Ansonsten ist es erst einmal egal ob der Taster auf GND oder VCC geht, das führt höchstens zu einer invertierten Ausgabe. Vorausgesetzt der entgegengesetzte Zustand wird am Eingang hardwareseitig definiert.

sast

oberallgeier
04.08.2009, 13:27
... erst einmal egal ob der Taster auf GND oder VCC geht, das führt höchstens zu einer invertierten Ausgabe ...Uuuups - wieder was gelernt:

...
DDRB = 0x00; //PB als EIngang
PORTB = 0xff; //internen PULL-UP einschaltenIch glaube, das ist bei meinen mega168 + 328 anders. PullUp und dann Vcc dran - ich dachte immer, das gibt nix.

sast
04.08.2009, 13:43
PORTB = 0xff;

Punkt für dich. Deshalb mein Nachsatz "Vorausgesetzt der entgegengesetzte Zustand wird am Eingang hardwareseitig definiert. "

sast

markusj
04.08.2009, 13:51
sast: Natürlich, in meinem Code würde ich dass auch niemals so tun.
Aber nachdem er auch den ganzen Port auf einmal zuweist, bin ich davon ausgegangen, dass die anderen Pins vorerst nicht von belang sind.
Natürlich sollte man, wenn man den restlichen Port mitnutzen will, stattdessen eben analog zum Code von Joe selektiv arbeiten.

mfG
Markus

PS: Joe, du hast an für sich vollkommen Recht: Pullup und VCC gibt nix - aber (manueller) Pulldown und VCC gibt dann halt das invertierte Signal...

fuxx
05.08.2009, 10:27
Hallo,
hab erst heute wieder Zeit gefunden rein zuschauen.

Also zu dem Code: Ich fange gerade erst so richtig an, deshalbt sieht alles etwas Laienhaft aus :/

Die Pinbelegung war vorerst egal, da es sich eh nur um einen Test handelte, aber der Fehler war, dass ich auch wieder rücksetzen muss. Naja manchmal sind es die kleinen Sachen, auf die es ankommt.

Trotzdem vielen Dank für die Geduld