Anfängerschaltung geht nicht

Gast #3719640
Lesenswert?

Ich bin gerade in das Themengebiet der Mikrokontroller eingestiegen. 
Probiere schon seit Tagen eine Schaltung aus, die einfach nicht 
funktionnieren will.


Quellcode:

#define F_CPU 1000000UL     /* 1MHz */


#include <avr/io.h>
#include <util/delay.h>    //integriert Zeit

// Prototypen
void long_delay(uint16_t);


int main()
{
  // LED-Pins als Ausgang definieren
  DDRD  |= (1<<PD3) | (1<<PD4) | (1<<PD5) | (0<<PD6);    //PD3, PD4, PD5 
->LEDs||PD6 ->Taster
  PORTD |= (1<<PD6);  //interner Pullup ein


  while (1)
  {
    if (!(PIND & (1<<PIND6)))  //wenn Taster gedrückt wird schalte LED 
aus
    {
      PORTD = (0<<PD3);
      long_delay(200);    //warte 200 ms
    }
    PORTD = (1<<PD3);  //wenn nichts gedrückt ist leuchtet LED
  }
}


//Funktion für exaktere Zeit
void long_delay(uint16_t ms)
{
  for(; ms>0; ms--)
  _delay_ms(1);
}
______________________________________________________________________ 
_

Ich weis ich lasse den Taster nicht entprellen aber die Schaltung müsste 
auch ohne Entprellen gehen. Sobalt ich die Schaltung anstecke leuchtet 
die LED kurz auf und ist dann die ganze Zeit aus. Es ändert sich nichts 
wenn der Taster gedrückt wird.
Angehängte Dateien:
#3719670
Lesenswert?

Tobias schrieb:
> DDRD  |= (1<<PD3) | (1<<PD4) | (1<<PD5) | (0<<PD6);    //PD3, PD4, PD5
> ->LEDs||PD6 ->Taster
(0<<PD6) weglassen.
Beim "initialisieren" der Register einfach ein = verwenden, sämtliche 
nicht gesetzten Bits werden automatisch auf 0 gesetzt, gesetzt mit 
(1<<PDx).
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Einf.C3.BChrungsbeispiel

http://www.mikrocontroller.net/articles/Bitmanipulation
Tobias schrieb:
> PORTD = (0<<PD3);
Im Artikel Bitmanipulation unter "Bits löschen"  PORTD &=~ (1<<PD3);

Tobias schrieb:
> PORTD = (1<<PD3);  //wenn nichts gedrückt ist leuchtet LED
Im Artikel Bitmanipulation unter "Bits setzen" PORTD |= (1<<PD3);
#3719675
Lesenswert?

Julian Baugatz schrieb:
> Peter Luidolt schrieb:
>> Wenn du ihn nach GND schaltest, dann wird dein µC nicht starten.
>
> Quatsch, der Reset-Pin wird intern auf Vcc gezogen, der externe Pull-Up
> macht die Schaltung nur störungsunempfindlicher.

Ich würde mich nicht darauf verlassen. Speziell wenn noch ein Programmer 
dranhängt dann reicht der interne Pull-Up vielleicht nicht.

Liebe Grüße,
Lui
Gast #3719676
Lesenswert?

Hi

>Du musst also dafür sorgen, dass dort ein positives Signal anliegt. Dazu
>den Reset-Pin mittels Widerstand (z.B. 1k) nach +5V legen.
>Wenn du den Reset nicht beschaltest, dann weiß man nicht so genau was
>geschehen wird.

Der RESET-Pin hat einen internen Pull-Up-Widerstand. Allerdings ist der 
mit 30..60k nicht sehr stark. Ein externer Widerstand ist durchaus 
angebracht.

MfG Spess
#3719685
Lesenswert?

Vielleicht hilft dir das weiter.
Ich hatte es mir anfangs als Merkstütze so aufgeschrieben.
1
Programmieren in C
2
Eine Zusammenfassung
3

4

5

6
Pins schalten:
7

8

9
Zunächst muss man im Datenrichtungsregister die Richtung angeben; also, ob es ein Ausgang oder ein Eingang sein soll.
10
Standard sind die Datenrichtungsregister auf Null gestellt.
11
Die Bits werden von rechts nach links gelesen. Also steht rechts Null (0) und links ist das Bit 7
12
Alle Bits des Datenrichtungsregister B auf High, Eins (1) oder Ausgang setzen, das kann man auf verschiedene Weisen machen:
13
Im Anfang empfiehlt sich vielleicht die Binär Schreibweise
14
DDRB = 0xFF;  oder  DDRB = 0b11111111;  oder  DDRB |= (1<<DDB0) | (1<<DDB1) | … usw. ;
15

16
PORTB |=  (1 << PB5);  // Schaltet den Pin PB5 ein (+5V)
17
PORTB &= ~  (1 << PB2);  // Schaltet den Pin PB2 aus 
18
PORTB ^=  (1<<(PB4);  // Schaltet bei jeden Durchlauf das Bit um; 0 wird 1 und 1 wird Null
19

20

21
DDRB &= ~  (1 << DDB4);  // Den Pin als Eingang schalten
22
    und    // und Pullup high
23
PORTB |=  (1 << PB4);   // hier wird der interne Pullup eingeschaltet. Was ein Pullup macht, das musst 
24
        // du an anderer Stelle nachlesen. Nur soviel. Er verschafft dir ein           //klares Signal.
25

26
PORT oder PIN?
27

28
Ein Eingang wird als PIN angesprochen:
29

30
If (PINB & (1<<PINB1) ) {    //Wenn der Pin B1 High ist
31
  // dann reagiere darauf
32
}
33

34
If ( ! (PINB & (1<<PINB1)) ){    //Wenn der Pin B1 Low ist (Klammern zählen!!!) 
35
  // dann reagiere darauf
36
}

Leider ist die Formatierung verrutscht.
#3719997
Lesenswert?

Tobias schrieb:
> while (1)
>   {
>     if (!(PIND & (1<<PIND6)))  //wenn Taster gedrückt wird schalte LED
> aus
>     {
>       PORTD = (0<<PD3);
>       long_delay(200);    //warte 200 ms
>     }
>     PORTD = (1<<PD3);  //wenn nichts gedrückt ist leuchtet LED
>   }

Was ist damit?

Aber das ist auch unerheblich, "PORTD = (0<<PD3)" ist doch auch falsch 
und das schreibt auch niemand.
Verstehe sowieso nicht, wieso die Anfänger nicht erstmal mit "Blink" 
anfangen. und gleich bei den ersten Zeilen schon alles abfragen wollen.
#3720017
Lesenswert?

Walter schrieb:
> Tobias schrieb:
>> PORTD = (0<<PD3);
>
> damit schaltest du die pullups aus
>
> und was ist damit??

Kenne ich so nicht, steht so in keinem Buch was ich las und wurde hier 
in mehreren Beiträgen als falsch bezeichnet. Aber da ich ja immer gern 
dazu lerne, werde ich das mal irgendwann mit dem Drachen testen und 
gucken, ob wirklich was geschaltet wird.
Trotzdem, vielen Dank für den Hinweis.
Moderator Persönliche Seite #3720233
Lesenswert?

Tobias schrieb:
>       PORTD = (0<<PD3);

0<<PD3 ist immer 0. Durch die Zuweisung wird der komplette Port D auf 0 
(also auf Low) gesetzt.

Bisschen viel für eine LED. Es hätte gereicht:

PORTD &= ~(1<<PD3);

um genau das eine Bit "auszuknipsen".

Analog dazu:

PORTD = (1<<PD3);  //wenn nichts gedrückt ist leuchtet LED

Richtig wäre:

PORTD |= 1<<PD3;

An diesen zwei Statements sieht man, dass der TO grundlegende 
Verständnisprobleme mit der Programmiersprache C hat.

Mit "PORTD = (0<<PD3);" will er ein Bit löschen, schiebt aber nur eine 0 
in der Gegend herum und setzt dann auch noch den ganzen Port zurück.

Dummer Nebenefekt: Er schaltet damit seinen Pullup-Widerstand an seinem 
Taster ab und macht dadurch seinen Taster nutzlos.... obwohl er doch nur 
eine LED abschalten wollte.

Mit "PORTD = (1<<PD3);" passiert ähnliches. Der TO übersieht, dass hier 
zwar PD3 auf High gesetzt wird, aber sämtliche anderen Pins an PORT D 
ebenso ihren (eventuell abweichenden) Wert ändern.

Auch hiermit schießt sich der TO ins Knie und schaltet den für den 
Taster so wichtigen Pullup-Widerstand aus.

@Tobias: Versuche erstmal, eine, dann zwei LED blinken zu lassen. Wenn 
das sauber funktioniert, nimm den Taster hinzu.
Gast #3720323
Lesenswert?

x0r schrieb:
> Walter schrieb:
>> F. Fo schrieb:
>>> Kenne ich so nicht, steht so in keinem Buch was ich las und wurde hier
>>> in mehreren Beiträgen als falsch bezeichnet.
>>
>> siehe z.B.
>> http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
>
> Du solltest dir die Seite nochmal genauer ansehen und dir den Sinn der
> oben genannten Zuweisung überlegen.

vielleicht schaust du dir die Seite noch mal an, da wird nämlich erklärt 
wie man die Pullups ein und ausschaltet, und die genannte Zuweisung
PORTD = (0<<PD3)
schaltet die Pullups aus!
Gast #3720774
Lesenswert?

Ich habe den Fehler entdeckt. Der Port den ich als Eingang nehmen wollte 
ist als ICP gekennzeichnet. Als ich das selbe Programm mit PINB0 
ausprobiert habe hat es einwandfrei funktioniert.

Trotzdem danke für euere Hilfe.
Gast #3720997
Lesenswert?

Walter schrieb:
> vielleicht schaust du dir die Seite noch mal an, da wird nämlich erklärt
> wie man die Pullups ein und ausschaltet, und die genannte Zuweisung
> PORTD = (0<<PD3)
> schaltet die Pullups aus!

Eben nicht. Es schaltet den gesamten Port low, indem es eine Null um PD3 
nach links schiebt und den Rest des Ports Null setzt. Heraus kommt dann 
das selbe wie
PORTD = 0b00000000;
Deaktiviert zwar den Pullup, aber eben auch alle anderen.

Auf der Verlinkten Seite wird der Pullup mit dieser Zuweisung 
deaktiviert:
PORTD &= ~(1<<PD3);
Frank hat eigentlich alles dazu gesagt.
Moderator Persönliche Seite #3721113
Lesenswert?

Tobias schrieb:
> Ich habe den Fehler entdeckt. Der Port den ich als Eingang nehmen wollte
> ist als ICP gekennzeichnet.

Hat damit nichts zu tun. Du hast leider nicht verstanden, was ich oben 
schrieb: Du hast Dir durch falsche Anweisungen den Pullup auf Deinem 
Taster-Eingang abgeschaltet. Selbstverständlich kann man auch einen Pin, 
der als ICP gekennzeichnet ist, auch als Taster-Eingang verwenden.

> Als ich das selbe Programm mit PINB0
> ausprobiert habe hat es einwandfrei funktioniert.

Ist doch klar. Falsche Manipulationen von PORTD (versehentliches 
Abschalten des Pullups, siehe oben) haben keine Einwirkungen auf PORTB.

Damit hast Du den Fehler immer noch im Programm. Er tritt nur nicht mehr 
auf. Mit Deinen falschen Anweisungen kannst Du gerade EINE EINZIGE LED 
an einem PORT und einen Taster an einem ANDEREN Port verwenden. Was für 
eine Verschwendung....
Gast #3721195
Lesenswert?

x0r schrieb:
> Walter schrieb:
>> die genannte Zuweisung
>> PORTD = (0<<PD3)
>> schaltet die Pullups aus!
>
> Eben nicht. Es schaltet den gesamten Port low, indem es eine Null um PD3
> nach links schiebt und den Rest des Ports Null setzt. Heraus kommt dann
> das selbe wie
> PORTD = 0b00000000;
> Deaktiviert zwar den Pullup,

ich verstehe deine Einwände nicht,
verstehst du unter Pullup deaktivieren etwas anderes als Pullup 
ausschalten?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren