Forum: Mikrocontroller und Digitale Elektronik Bitverschiebung Verständnis Problem!


von Mario W. (Firma: Privat) (wlfmario)


Lesenswert?

Ich als Einsteiger versuche gerade mich etwas in die C Programmierung im 
Atmel Studio einzuarbeiten.
Doch leider gibt es dort ein kleines Problem bei dem ich bis jetzt keine 
Lösung gefunden habe.

Ich versuche eine einfache Ampel mit LED's auf dem Breadboard und dem 
Atmega 328P zu programmieren nur alles nach den delay scheint irgenwie 
nicht ausgeführt zu werden.

um den Fehler zu finden habe ich erst einmal einer LED an D2 
angeschlossen, die sich auch einschalten lässt, doch nach dem delay 
geht sie nicht aus.

In vielen Tutorials wird dies mit einer Bitverschiebung gemacht nur bei 
mir funktioniert das einfach nicht.
Evtl. hat jemand einen Tipp was ich Falsch mache.

evtl. habe ich da auch etwas bei der UND Verknüpfung falsch verstanden.
1
#ifndef F_CPU
2
#define F_CPU 1000000UL
3
#endif
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
int main(void)
9
{
10
  DDRD = 0b00000111;
11
    
12
    while (1) 
13
    {
14
  PORTD |= (1<<2);
15
  _delay_ms(500);
16
  PORTD &= ~(1<<2);  
17
  }
18
}

von brt (Gast)


Lesenswert?

Die LED get sehr kurz aus, aber die While-Schleife schaltet sie ja 
direkt wieder ein. Du brauchst 2*delay(), 1*nach dem Ein- und 1*nach dem 
Ausschalten...

von Michael U. (amiga)


Lesenswert?

Hallo,
naja, die wird schon ausgehen. Für ein paar µs. Du machst sie ja dann in 
Deiner while(1) Schleife gleich wieder an...

Gruß aus Berlin
Michael

von Vancouver (Gast)


Lesenswert?

Nach dem zweiten Portzugriff in der Schleife auch ein Delay einbauen. 
Sonst geht die LED aus und sofort wieder an.

von besser lesbar (Gast)


Lesenswert?

Mario W. schrieb:
> (1<<2)

...
#define BIT_1       0b00000010
#define BIT_2       0b00000100
...


PORTD |= (BIT_2);

von besser lesbar (Gast)


Lesenswert?

besser lesbar schrieb:
> ...
> #define BIT_1       0b00000010
> #define BIT_2       0b00000100
> ...

#define LED_RED       BIT_2


> PORTD |= (LED_RED);

von Karl M. (Gast)


Lesenswert?

Hallo,

hmm, besser lesbar über ein Macro, ja aber mit korrekter Bezeichbung des 
Ports und seiner Nummer.
1
#define LED_RED (1<<PD2)

von Einer K. (Gast)


Lesenswert?

Ich habe den Code aus dem Eingangsposting mal in Form gebracht....
(Der sah ja aus, wie die Leberwurst hinter meinem Schrank)
1
#ifndef F_CPU
2
#define F_CPU 1000000UL
3
#endif
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
int main(void)
9
{
10
  DDRD = (1<<PD2);
11
    
12
  while (1) 
13
  {
14
    PIND = (1<<PD2);
15
    _delay_ms(500);
16
  }
17
}

von Karl M. (Gast)


Lesenswert?

Super,

Arduino Fanboy D. schrieb:
> #ifndef F_CPU
> #define F_CPU 1000000UL
> #endif
>
> #include <avr/io.h>
> #include <util/delay.h>
>
> int main(void)
> {
>   DDRD = (1<<PD2);
>
>   while (1)
>   {
>     PIND = (1<<PD2); // <=== ja hiermit können einige Avr ihren Port-Pin 
Umschalten
// sonst halt per XOR: PORTD ^= (1<<PD2);
>     _delay_ms(500);
>   }
> }

von Wolfgang (Gast)


Lesenswert?

Mario W. schrieb:
> Ich versuche eine einfache Ampel mit LED's auf dem Breadboard und dem
> Atmega 328P zu programmieren nur alles nach den delay scheint irgenwie
> nicht ausgeführt zu werden.
>
> um den Fehler zu finden habe ich erst einmal einer LED an D2
> angeschlossen, die sich auch einschalten lässt, doch nach dem delay
> geht sie nicht aus.

Doch - die geht aus. Nimm mal ein Oszi. Dann kannst du das auch sehen.

Und wenn du dich davon überzeugt hast, vergiss das mit dem delay() am 
besten gleich wieder und beschäftige dich mit Timern uns FSM ;-)

von Mario W. (Firma: Privat) (wlfmario)


Lesenswert?

Habt ihr das Klatschen gehört ?
Das war meine Hand die ich mir vor die Stirn gehauen habe. :D
Danke für die Hilfe, für diesen Dummen Fehler habe ich Stunden verbracht 
um ihn zu finden, dabei war es so Einfach. ;)

von HildeK (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
> int main(void)
> {
>   DDRD = (1<<PD2);
>
>   while (1)
>   {
>     PIND = (1<<PD2);
>     _delay_ms(500);
>   }
> }

Nur als Hinweis:
Richtigerweise würde man aber die erste Zeile so schreiben:
1
    DDRD = (1<<DDD2); 
2
// besser noch, um andere Einstellungen am Port nicht zu ändern
3
    DDRD |= (1<<DDD2);
Mir ist es zwar noch nicht begegnet, aber es könnte durchaus sein, dass 
die Werte von PD2 und DDD2 nicht zwangsweise gleich sind. Das hängt 
davon ab, wie die Hardware aufgebaut ist. Ich habe aber auch nur wenige 
AVR-Datenblätter angeschaut.
DDD2 steht für Data Direction von Pin D2 (bei z.B. Port B2 hieße das 
dann DDB2).
Es gibt jeweils eine Makrodefinition für PDx, PINDx und DDDx für den 
Port D.

von Einer K. (Gast)


Lesenswert?

HildeK schrieb:
> Mir ist es zwar noch nicht begegnet, aber es könnte durchaus sein, dass
> die Werte von PD2 und DDD2 nicht zwangsweise gleich sind.

Alle AVR Ports sind sind in der Hinsicht symmetrisch aufgebaut.
Je nach µC fehlen manchmal Pins in einem 8Bit Port, aber das tut der 
Sache keinen Abbruch.

Schätze mal, dass man das verifizieren kann, in dem man einen Parser 
über die XML Dateien scheucht, welche dem Atmel Studio bei liegen.


Allerdings hast du dennoch recht!
Ordentlicher wäre es.
Allerdings auch schlechter zu lesen und mehr zu merken.


> Richtigerweise würde man aber die erste Zeile so schreiben:
Da es in dieser Anwendung keine Auswirkungen hat, ist "Richtig === 
Falsch"
Man muss also die Situation ändern, um zu einer neuen Bewertung zu 
kommen.

von HildeK (Gast)


Lesenswert?

Arduino Fanboy D. schrieb:
>> Richtigerweise würde man aber die erste Zeile so schreiben:
> Da es in dieser Anwendung keine Auswirkungen hat, ist "Richtig ===
> Falsch"

Ok, ich hätte schreiben sollen: "Ordentlicherweise würde man ....", und 
ich habe auch nicht 'falsch' geschrieben und habe den Konjunktiv 
verwendet.
War auch so gemeint und nur ein Hinweis, falls mal jemand darüber 
stolpern sollte.
Wenn ein Anfänger das im AVR-GCC-Tutorial 
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Zugriff_auf_IO-Ports 
anschaut, wird es ihm ggf. auffallen. Mir ging es jedenfalls so ...

Arduino Fanboy D. schrieb:
> Schätze mal, dass man das verifizieren kann,

Kann man sicherlich, den Aufwand spare ich mir jedoch und verwende 
weiterhin DDnx. Damit ist jede Gefahr im Falle einer Ausnahme weg. :-)

von Hennes (Gast)


Lesenswert?

Hallo

"Das war meine Hand die ich mir vor die Stirn gehauen habe. :D
Danke für die Hilfe, für diesen Dummen Fehler habe ich Stunden verbracht
um ihn zu finden, dabei war es so Einfach. ;)"

Und genau das, gut nachher "etwas" verschärft ;-) , ist das was das 
Programmieren lernen so schwer oder zumindest zeitaufwendig macht.
Die Befehle und reinen Techniken wie Schleifen, Abfragen usw., ja selbst 
der Kram mit den Pointern ist relativ schnell erlernt und für sich 
alleine verstanden.
Dieses aber alles bewusst und in einer guten Mischung zwischen geplant 
und den "Bauchgefühl" vernünftig und zielgerichtet zu nutzen und 
"automatisch" richtig "ohne denken" (bitte nicht zu wörtlich nehmen, 
aber ihr versteht schon was ich meine) anwenden zu können ist, meiner 
Meinung nach, die große Kunst die hinter der Programmierung steht.
Was muss ich alles beachten, wo sind die gemeinen Stolperfallen (ganz 
unabhängig von der jeweiligen Programmiersprache)? Das ist, so glaube 
ich zumindest das was das eigentliche Problem und die Herausforderung 
bei Programmieren (zumindest im µC Umfeld - zum Bereich PC usw. kann ich 
mangels Erfahrung nichts sagen).
Scheinbar gibt es da außer viel eigener Erfahrung, eigenen Fehlern und 
abschauen von guten Code (den man aber erstmal als Anfänger erkennen 
muss) kaum Möglichkeiten das gezielt und nach Plan zu lernen.

Hennes

von Einer K. (Gast)


Lesenswert?

Hennes schrieb:
> Dieses aber alles bewusst und in einer guten Mischung zwischen geplant
> und den "Bauchgefühl" vernünftig und zielgerichtet zu nutzen und
> "automatisch" richtig "ohne denken" (bitte nicht zu wörtlich nehmen,
> aber ihr versteht schon was ich meine) anwenden zu können ist, meiner
> Meinung nach, die große Kunst die hinter der Programmierung steht.

Das steht hinter vielen Beschäftigungen!
Eigentliche hinter allen, wo ein Mensch gut drin werden kann.

Hier wird es als etwas 4 Stufiges beschrieben:
https://de.wikipedia.org/wiki/Kompetenzstufenentwicklung

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.