Forum: Mikrocontroller und Digitale Elektronik Anfängerschaltung geht nicht


von Tobias (Gast)


Angehängte Dateien:

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.

von Peter L. (luidoltp)


Lesenswert?

Tobias schrieb:
> 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.

Wie hast du den Reset-Pin angeschlossen?

Liebe Grüße,
Lui

von MaWin (Gast)


Lesenswert?

Es fehlt:
- ein ELSE
- ein Stützkondensator
- ein Vorwiderstand
- und vielleicht die Beschaltung von AVCC und AGND und RESET

von Tobias (Gast)


Lesenswert?

Der Resetpin(Pin: linke Seite ganz oben) ist nicht angeschlossen. Ich 
will die schaltung ja nicht resetten

von Tobias (Gast)


Angehängte Dateien:

Lesenswert?

Wozu ein else. Wenn kein else da steht macht er doch nichts und das soll 
er dann auch machen

von Peter L. (luidoltp)


Lesenswert?

Du musst den Reset-Eingang beschalten.

http://www.mikrocontroller.net/articles/AVR_Checkliste#Reset-Pin_korrekt_beschaltet.3F

Liebe Grüße,
Lui

: Bearbeitet durch User
von Julian B. (julinho)


Lesenswert?

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.

von Holger L. (max5v)


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);

: Bearbeitet durch User
von Peter L. (luidoltp)


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

von spess53 (Gast)


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

von F. F. (foldi)


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.

: Bearbeitet durch User
von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Ist noch niemandem aufgefallen dass das essentielle while(1){ ... } 
fehlt?

von F. F. (foldi)


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.

: Bearbeitet durch User
von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Nachtrag:

Das while steht komplett nutzlos am Ende eines Kommentares.

Tobias schrieb:
>   PORTD |= (1<<PD6);  //interner Pullup ein    while (1)

: Bearbeitet durch User
von Walter (Gast)


Lesenswert?

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

damit schaltest du die pullups aus

und was ist damit??

MaWin schrieb:
> - ein Stützkondensator
> - ein Vorwiderstand
> - und vielleicht die Beschaltung von AVCC und AGND und RESET

von F. F. (foldi)


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.

von Walter (Gast)


Lesenswert?

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

von x0r (Gast)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


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.

: Bearbeitet durch Moderator
von Walter (Gast)


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!

von Tobias (Gast)


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.

von Walter (Gast)


Lesenswert?

Tobias schrieb:
> Ich habe den Fehler entdeckt.

du hast in verdeckt ...

von x0r (Gast)


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.

von Frank M. (ukw) (Moderator) Benutzerseite


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....

von Walter (Gast)


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?

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.