PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : lese zustand PA5 gebe ihn auf PA4 aus



karthago
30.11.2006, 10:25
Hallo zusammen!

ich wollte diese kleine Aufgabe :
Lese von Port A, Pin 4 den Zustand eines Tasters ein und gebe ihn auf Port A, Pin 5 aus (wo eine LED eingesclossen ist )

für ATMEGA32



//*******************************************
// READ FROM AP03 WRITE TO AP04

//*******************************************

#include <avr/io.h>

#define LED 4
#define TASTER 3
#define LED_ON PORTA |= (1 << LED )
#define LED_OFF PORTA &= ~( 1<< LED )
#define VALUE_TASTER bit_is_set (PINA, TASTER)



uint8_t VALUE;

// Initialisierung

void init (void)
{
DDRA |= (1 << LED); // PIN5 von DDRA als ausgang

DDRA &= ~( 1<< TASTER); // PIN4 von DDRA als eingang
PORTA |= (1 << TASTER); // Interne Pullup einschalten
}



int main (void)

{
init();

VALUE = VALUE_TASTER;

while (1)

{

if ( VALUE==1)


LED_ON;

else

LED_OFF;

}

return 0;
}


kompilieren war min 0 fehler
aber wurde mir gesagt dass es nicht funktionnieren wird weil es wird nur der Status des Tasters beim Einlesen festgehalten und auf die LED abgebildet.


Ich habe den fehler aber nicht gefunden, könnt ihr mir bitte helfen??

Danke!

p_mork
30.11.2006, 10:53
Hallo karthago,
das programm liest nur den Zustand von PA3 beim einschalten. wenn du willst, dass der controller ständig die LED nach dem Zustand des Tasters ein bzw auschaltet muss das programm so aussehen:


//*******************************************
// READ FROM AP03 WRITE TO AP04

//*******************************************

#include <avr/io.h>

#define LED 4
#define TASTER 3
#define LED_ON PORTA |= (1 << LED )
#define LED_OFF PORTA &= ~( 1<< LED )
#define VALUE_TASTER bit_is_set (PINA, TASTER)



uint8_t VALUE;

// Initialisierung

void init (void)
{
DDRA |= (1 << LED); // PIN5 von DDRA als ausgang

DDRA &= ~( 1<< TASTER); // PIN4 von DDRA als eingang
PORTA |= (1 << TASTER); // Interne Pullup einschalten
}



int main (void)

{
init();

VALUE = VALUE_TASTER;

while (1)

{

if ( VALUE_TASTER)


LED_ON;

else

LED_OFF;

}

return 0;
}


MfG Mark

SprinterSB
30.11.2006, 10:53
Du liest den Status ja nur 1x ein. Es müsste heissen
... if (VALUE_TASTER) ...

karthago
30.11.2006, 11:17
Ich hab nicht dran gedacht :)


Vieeeeeeeeeeeeeeeeelen dank!

karthago
30.11.2006, 13:26
Ich habs korrigiert , aber der Betreuer sagt dass es auch so nicht geht :((((

ich verstehe nichts

SprinterSB
30.11.2006, 14:16
evtl. noch invertieren, da der Taster invertierend angeschlossen ist. Jedenfalls nach der PullUp-Config zu schliessen.

Guy
01.12.2006, 08:43
Was willst du genau?

Ich nehme mal an du willst dass, wenn die Taste gedrückt ist die LED an ist, und wenn die Taste nicht gedrückt ist, die LED aus ist.

Wenn du dir deinen Code an schaust, siehst du sofort, dass das nicht geht.

Du fragst deinen Taster nur einmal vor der Endlosschleife ab, also kann der Zustand von der LED sich auch nicht ändern.

Falsch!
VALUE = VALUE_TASTER;
while (1)
{
//LED schalten
} //

Richtig!
while (1)
{
VALUE = VALUE_TASTER;
//LED schalten
} //


//*******************************************
// READ FROM AP03 WRITE TO AP04

//*******************************************

#include <avr/io.h>

#define LED 4
#define TASTER 3
#define LED_ON PORTA |= (1 << LED )
#define LED_OFF PORTA &= ~( 1<< LED )
#define VALUE_TASTER bit_is_set (PINA, TASTER)



uint8_t VALUE;

// Initialisierung

void init (void)
{
DDRA |= (1 << LED); // PIN5 von DDRA als ausgang

DDRA &= ~( 1<< TASTER); // PIN4 von DDRA als eingang
PORTA |= (1 << TASTER); // Interne Pullup einschalten
}



int main (void)

{
init();



while (1)

{
VALUE = VALUE_TASTER;
if ( VALUE_TASTER)


LED_ON;

else

LED_OFF;

}

return 0;
}

Hier noch der Code wenn du die Taste druckst geht die LED an, beim nochmaligen drücken wieder aus.



//*******************************************
// READ FROM AP03 WRITE TO AP04

//*******************************************

#include <avr/io.h>

#define LED 4
#define TASTER 3
#define LED_ON PORTA |= (1 << LED )
#define LED_OFF PORTA &= ~( 1<< LED )
#define VALUE_TASTER bit_is_set (PINA, TASTER)



uint8_t VALUE;

// Initialisierung

void init (void)
{
DDRA |= (1 << LED); // PIN5 von DDRA als ausgang

DDRA &= ~( 1<< TASTER); // PIN4 von DDRA als eingang
PORTA |= (1 << TASTER); // Interne Pullup einschalten
}



int main (void)

{
init();
while (1)
{
if (VALUE_TASTER)
{
if ( !(PINA & (1<<PINA4)) )
LED_ON;
else
LED_OFF;
}
}
return 0;
}


mfg
Guy

karthago
01.12.2006, 17:14
Sehr schön!

Vielen Dank

Travolds
28.12.2006, 09:23
hallo,

wies aussieht arbeite ich alle alten threads durch :) ich hab nämlich hier auch ein kleines problem.

folgender code:


#include <avr/io.h>

#define LED (1)
#define BUTTON (1)

int main(void)
{
/* PORTB.PIN1 to output */
DDRB |= _BV(LED);

/* PORTA.PIN1 to input */
DDRA &= ~_BV(BUTTON);

/* activate internal pullups */
PORTA |= _BV(BUTTON);
PORTB |= _BV(LED);

for (;;) {
if (bit_is_set(PINA, BUTTON)) {
if (!bit_is_set(PINB, LED)) {
PORTB |= _BV(LED);
} else {
PORTB &= ~_BV(LED);
}
}
}

return(0);
}


mit der beschaltung wie im anhang.

ich habe jetzt das problem, dass die LED an PINB1 immer schwach leuchtet. Sobald ich den Taster drücke, leuchtet die LED heller bzw. hört ganz auf zu leuchten, jedoch wechselt sie immer wieder in den schwach-leuchte-zustand zurück, sobald man den taster loslässt.

-- 1: wieso leuchtet die LED immer schwach?
-- 2: Sollte folgender Befehl die LED nicht durchgehend leuchten lassen


PORTB |= _BV(LED);

und durch den untenstehenden befehl beim nächsten tastendruck wieder ausschalten?


PORTB &= ~_BV(LED);


Jedenfalls würd ich das Datenblatt so interpretieren.
Ist sicher was ganz dummes aber ich komm einfach nicht drauf..

danke nochmal + lg

Kaiser-F
28.12.2006, 11:37
Hallo Travoldos,

Ich versuche mal zu helfen/verbessern :-)

1. Hardware:
Den Widerstand R3 mit 100k kannst Du Dir normalerweise sparen,
Weil Du ja sowieso die internen Pullup-Widerstände des AVRs benutzt.
( Nur so als Tipp um Hardwareaufwand zu sparen )

2. Software:
Ich will Dir keinesfalls zu nahe treten, sind nur Verbesserungsvorschläge:
Ich würde anstatt:
DDRB |= _BV(LED);
lieber:
DDRB |= (1<<LED);
verwenden.
Ist "standardisierter", und lässt sich von den meisten besser lesen...
Aber die obige Version ist sicherlich nicht falsch!


Nehmen Wir mal diese IF-Schleife unter die Lupe:

if (bit_is_set(PINA, BUTTON)) {
if (!bit_is_set(PINB, LED)) {
PORTB |= _BV(LED);
} else {
PORTB &= ~_BV(LED);
}
}

Ich denke dein erster Fehler liegt schon in der ersten Zeile:
"if (bit_is_set(PINA, BUTTON))"
"Wenn Button-Pin High ist"

Dieser Fall tritt ein, wenn der Taster NICHT gedrückt ist.
Jetzt durchläuft er die zweite If-Funktion,
Ist die LED aus, schaltet er sie ein.
Das Programm beginnt erneut,

Eingang ist High (bit is set), er kommt in die erste IF.
Dann kommt er zur zweiten:
LED ist ein, er schaltet sie aus
Das Programm beginnt erneut.

Also schaltet er die LED ständig aus und ein.
Das erklärt, warum sie schwach leuchtet.


Wenn du nun den Taster drückst, dann kann er keine IF-Funktion durchlaufen.
Die LED zeigt nun den zu letzt gesetzten stand an.

Und ich wette, dass die LED bei manchen Tastenbetätigungen auch AUS ist.



Abhilfe:

In der ersten schleife schreiben:

if (bit_is_clear(PINA, BUTTON))


Das gaze ist aber auch kritisch!
Du müsstest die Tastenprellung berücksichtigen.
Mit dem Finger Tippst du zwatr nur einmal auf den taster,
aber der Kontakt prallt ein paar mal hin und her.
Also "Tippt" er ein paar mal mehr.
Daher kann es sein, dass die LED an und gleich wieder aus geht,
ohne dass man es sieht.

Travolds
28.12.2006, 12:12
hallo und erstmal danke für die antwort,



Den Widerstand R3 mit 100k kannst Du Dir normalerweise sparen,
Weil Du ja sowieso die internen Pullup-Widerstände des AVRs benutzt.

ok danke :)



Ich will Dir keinesfalls zu nahe treten, sind nur Verbesserungsvorschläge:
Ich würde anstatt:
DDRB |= _BV(LED);
lieber:
DDRB |= (1<<LED);
verwenden.
Ist "standardisierter", und lässt sich von den meisten besser lesen...

ich sehe das nicht als zu nahe treten bin für jeden tipp dankbar :)



Ich denke dein erster Fehler liegt schon in der ersten Zeile:
"if (bit_is_set(PINA, BUTTON))"
"Wenn Button-Pin High ist"

*am kopf hau* ist natürlich falsch ich habs aber nicht gesehen



Und ich wette, dass die LED bei manchen Tastenbetätigungen auch AUS ist.

:-b




if (bit_is_clear(PINA, BUTTON))

kannte ich noch nicht - wieder was gelernt :)




Das gaze ist aber auch kritisch!
Du müsstest die Tastenprellung berücksichtigen.
Mit dem Finger Tippst du zwatr nur einmal auf den taster,
aber der Kontakt prallt ein paar mal hin und her.
Also "Tippt" er ein paar mal mehr.
Daher kann es sein, dass die LED an und gleich wieder aus geht,
ohne dass man es sieht.

die entprellproblematik ist mir bewusst, mir ging es hier rein darum basics zu üben

vielen dank nochmal!

Kaiser-F
28.12.2006, 12:54
Kein Problem, dazu sind Wir ja da! ;-)

Noch ein Tipp:
Das "if (bit_is_set(PINA, BUTTON)){}" sieht man auch nicht mehr gerne...

Sieht man fast nur so:
if( PINA & (1<<BUTTON) ){}

Diese Sachen sind halt "klassischer", "standardisierter" für C.
Wenn Du Dich von Anfang an an die "normalen" C-Anweisungen hältst,
tuhst dich wesentlich leichter, wenn Du mal was außerhalb der
ATMEL-GCC-Umgebung machst.

Für den Anfang spielt es aber keine Rolle.

Viel Spaß noch! Du greifst es genau richtig an!