Forum: Mikrocontroller und Digitale Elektronik Anfängerfrage zu Taster


von Al3ko -. (al3ko)


Angehängte Dateien:

Lesenswert?

Hi Leute,

ich bin in Sachen µC soweit, als dass ich LEDs zum Blinken bringen kann. 
Die Geschichte mit DDR, PORT und Bitmanipulation in dieser Hinsicht sind 
mir also bekannt.

Nun möchte ich im nächsten Schritt gerne etwas mit Tastern herumspielen, 
sprich auch PIN verwenden.

Im Anhang seht ihr die Beschaltung. Ich habe bewusst auf das "Drum 
herum" verzichtet, da die LEDs funktionieren und ich den Fokus gerne auf 
meine Beschaltung mit dem Taster und der LED setzen möchte.

Bevor ich den C Code poste, ein kleiner Kommentar vorab:
Ich habe bewusst auf das Thema Entprellen verzichtet, da ich es als 
zweiten Schritt implementieren wollte. Mir geht es hier erstmal um PIN 
und LED.

Hier also der Code:
1
#include <avr/io.h>
2
#include <inttypes.h>
3
#define F_CPU 1000000UL
4
#include <util/delay.h>
5
6
7
int main(void)
8
{
9
    DDRB &= ~( 1 << PB1 );          //PB1 auf Eingang (Taster)
10
    PORTB &= ~( 1 << PB1 );         //Pullup-Widerstand deaktivieren
11
    DDRD |= (1<<PD7);          //PD7 als Ausgang (LED)
12
13
14
    if (PINB & (1<<PB1))      //Prüfe, ob PB1 logisch high ist
15
    {              
16
    _delay_ms(500);
17
    _delay_ms(500);
18
    if(PINB & (1<<PB1))      //Prüfe erneut, ob PB1 logisch high ist nach 1s
19
    {
20
    PORTD |= (1<<PD7);      //Wenn PB1 immer noch logisch high ist, setze PD7 high
21
    _delay_ms(500);        //Warte 500ms, damit man die LED leuchten sieht
22
    }
23
    }
24
}

Beim Code habe ich mich teilweise an das AVR-GCC Tutorial gehalten.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
Kapitel: Eingänge Wie kommen Signale in den µC

Ich verwende einen Atmega8 mit AVR Studio4 und einem original AVR ISP 
mkII programmer.


Kann mir jemand meinen Gedankenfehler zeigen?

Vielen Dank.

Gruß

von Ralf Liebau (Gast)


Lesenswert?

Ich würde das mit einem interrupt machen - dann musst du nicht immer 
durch die if-schleife im hauprogramm...

von Noname (Gast)


Lesenswert?

>Ich habe bewusst auf das "Drum herum" verzichtet

Hast in dem Sinne darauf verzichtet, dass Du es hier nicht gezeichnet 
hast oder in dem Sinne, dass Du es auch nicht eingebaut hast. Also 
Abblockkondensatoren Takt etc.?

>Kann mir jemand meinen Gedankenfehler zeigen?

Was ist denn überhaupt das Problem?

Jedenfalls wird das Programm machen was dasteht. Allerdings wills Du 
vermutlich, dass das nicht nur einmal funktioniert sondern immer wieder.
Dann fehlt eine Endlosschleife in main.

Und warum eigentlich mühsam einen Pull-Down-Widerstand einbauen und (ok, 
weniger mühsam) den eingebauten Pull-Up deaktivieren?

von Noname (Gast)


Lesenswert?

>dann musst du nicht immer durch die if-schleife

http://www.if-schleife.de/

von Al3ko -. (al3ko)


Lesenswert?

Hallo Noname,

Noname schrieb:
>>Ich habe bewusst auf das "Drum herum" verzichtet
>
> Hast in dem Sinne darauf verzichtet, dass Du es hier nicht gezeichnet
> hast oder in dem Sinne, dass Du es auch nicht eingebaut hast. Also
> Abblockkondensatoren Takt etc.?
Hmm, war wirklich ungeschickt ausgedrückt. Ich habe das Drum Herum 
(Kondensatoren, Reset, Spannungsversorgung etc.) lediglich nicht 
eingezeichnet. Auf meinem Steckbrett sind die aber alle vorhanden und 
die LEDs (mein erstes Projekt mit µC) blinken, wie sie sollen.

>>Kann mir jemand meinen Gedankenfehler zeigen?
>
> Was ist denn überhaupt das Problem?
Wieder eine berechtigte Frage :D
Das Problem ist, dass die LED an PD7 nicht leuchtet, obwohl ich den 
Taster an PB1 gedrückt halte. Dass an PB1 bei gedrücktem Taster ein 
logisches High Signal ist, habe ich durch ein Multimeter geprüft. Sowohl 
Durchgangs- als auch Spannungsprüfung. Beides OK.

> Jedenfalls wird das Programm machen was dasteht. Allerdings wills Du
> vermutlich, dass das nicht nur einmal funktioniert sondern immer wieder.
> Dann fehlt eine Endlosschleife in main.
Ohje, while(1){} habe ich total vergessen. Kann ja auch nix werden :D
Habe es eingefügt und nun leuchtet die LED, wenn ich den Taster drücke. 
Danke für den Hinweis :)

> Und warum eigentlich mühsam einen Pull-Down-Widerstand einbauen und (ok,
> weniger mühsam) den eingebauten Pull-Up deaktivieren?

Den Pull-Down Widerstand habe ich eingebaut, damit PB1 bei nicht 
gedrücktem Taster ein fest definiertes Potential - nämlich GND - hat.

Um den internen Pull-Up Widerstand zu verwenden, müsste ich doch meine 
Schaltung umbauen (okay, einmal den Taster umstecken). Nämlich Taster 
gegen GND und dann den internen Pull-Up Widerstand aktivieren. Hmm, 
ginge auch. Keine Ahnung, weshalb ich mich für diese Variante 
entschieden habe.

Gruß

von Jannik O. (jannipanni)


Lesenswert?

Meine Tipps:

#include <avr/io.h>
#include <inttypes.h>
#define F_CPU 1000000UL
#include <util/delay.h>


int main(void)
{
    DDRB &= ~( 1 << PB1 );          //PB1 auf Eingang (Taster)
    DDRD |= (1<<PD7);          //PD7 als Ausgang (LED)

while(1) {

    if (PINB & (1<<PB1))      //Prüfe, ob PB1 logisch high ist
    {
    _delay_ms(1000);         //warte 1s
    if(PINB & (1<<PB1))      //Prüfe erneut, ob PB1 logisch high ist
    {
    PORTD |= (1<<PD7);      //Wenn PB1 immer noch logisch high ist, 
setze PD7 high
    _delay_ms(500);        //Warte 500ms, damit man die LED leuchten 
sieht
    }
    }
}
}

1: Wozu den internen Pullup Widerstand abschalten? Wenn du im Schaltplan 
den Widerstand weglässt, ist das doch einfacher oder?
2: Programm in eine while-Schleife legen, damit das Programm sich immer 
wiederholt und am ende des programms nicht einfach irgendwas passiert.
3: wozu 2x _delay_ms(500); schreiben, wenn man auch einmal 
_delay_ms(1000); schreiben kann? spart schreibarbeit.
4: Am ende könnte das programm nochmal ca. 10s warten und die led wieder 
ausschalten, damit man das programm wiederholen kann. sonst wäre es ja 
etwas langweilig :)

von Al3ko -. (al3ko)


Lesenswert?

Moin obi wan,
auch dir danke für deine Tipps.

Hier nun mein abgeänderter C Code
1
#include <avr/io.h>
2
#include <inttypes.h>
3
#define F_CPU 1000000UL
4
#include <util/delay.h>
5
6
7
int main(void)
8
{
9
10
while(1)
11
{
12
    DDRB &= ~( 1 << PB1 );          //PB1 auf Eingang (Taster)
13
    PORTB &= ~( 1 << PB1 );         //Pullup-Widerstand deaktivieren
14
  DDRD |= (1<<PD7);          //PD7 als Ausgang (LED)
15
16
17
    if (PINB & (1<<PB1))      //Prüfe, ob PB1 logisch high ist
18
    {              
19
  _delay_ms(50);
20
    while(PINB & (1<<PB1))    //Prüfe erneut, ob PB1 logisch high ist nach 1s
21
    {
22
    PORTD |= (1<<PD7);      //Wenn PB1 immer noch logisch high ist, setze PD7 high
23
    }
24
  PORTD &=~(1<<PD7);        //Setze PD7 low, damit die LED ausgeht.
25
    }
26
}
27
return 0;
28
}

Schließlich soll ja auch die LED ausgehen, wenn der Taster nicht mehr 
gedrückt ist :D
Habs getestet, funktioniert sehr gut.

Zu deiner Frage mit dem internen Pull-Up Widerstand.

Ich stelle eine Gegenfrage:
Wozu sollte der aktiviert sein?

Wenn ich den Taster drücke, soll logisch 1 sein, sprich 5V an PB1. Ist 
der interne Pull-Up Widerstand aktiviert, ist doch ständig eine logische 
1 an PB1. Ferner brauche ich doch irgendwo einen Pull Down Widerstand, 
der mir den PB1 fest auf GND zieht, wenn der Taster nicht gedrückt ist.

Ich kann eure Logik nicht ganz nachvollziehen :/

Gruß

von Noname (Gast)


Lesenswert?

>Wenn ich den Taster drücke, soll logisch 1 sein, sprich 5V an PB1

Gegenfrage: Warum muss ein gedrückter Taster eine 1 ergeben?
Wenn Du Dich von dieser Festlegung lösen kannst, dann sparst Du einen 
Widerstand.

von Al3ko -. (al3ko)


Lesenswert?

Noname schrieb:
>>Wenn ich den Taster drücke, soll logisch 1 sein, sprich 5V an PB1
>
> Gegenfrage: Warum muss ein gedrückter Taster eine 1 ergeben?
> Wenn Du Dich von dieser Festlegung lösen kannst, dann sparst Du einen
> Widerstand.

True!

Zu Testzwecken wollte ich einfach sagen:
- LED ist aus
- Drücke ich den Taster, geht die LED an

Verwende ich den Pull-Up Widerstand und packe den Taster gegen GND, 
müsste ich die if-Abfrage auch negieren. Soweit habe ich wohl gar nicht 
gedacht, so dass ich in der von dir zitierten Festlegung verharrt bin.

Gruß

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.