Forum: Compiler & IDEs STK 500 Led reihenfolge.


von My T. (mytrasher)


Lesenswert?

Hallo,
ich habe angefangen mich mit dem mcs zu beschäftigen und wollte was 
probieren und in c programmieren jedoch klappt alles irgendwie nicht 
richtig....

1
#include <avr/io.h>               
2
#include <util/delay.h> 
3
4
5
6
 
7
int main (void) {                
8
 
9
   DDRB = 0xFF; // Ausgabe PORT (LEDs)
10
   DDRD = 0x00; // Eingabe PORT (Taster)
11
   PORTD = 0xFF;
12
   PORTB = 0x00; // Ausgabe PORT " Alle LEDs Aus"             
13
14
15
void long_delay(uint16_t ms)
16
{
17
    for(; ms>0; ms--) _delay_ms(1);
18
}
19
20
   while(1) {  
21
 long_delay(3000);
22
  PORTB = ((1<<PB1) | (1<<PB0));
23
   long_delay(3000);
24
   PORTB = ((1<<PB2) | (1<<PB3));
25
  
26
  */ 
27
    }
28
29
                  
30
   return 0;                 
31
   }
1. Was es machen soll: 3sec warten led0-1 ausmachen 3 sec warten led2-3 
ausmachen... ende

WAS es macht: 3 sec warten led 0-1 ausmachen 3sec warten led 0-1 
ANmachen led 2-3 ausmachen DANN wieder led0-1 anmachen etc...  wieso?

und noch was komisches: wenn ich das zweite " long_delay(3000);" 
entferne leuchten alle leds AUSSER led 2-3 ?
entferne ich jedoch die erste " long_delay(3000);" leuchten alle leds 
ausser led0-1 ....

 Was ist das und wo ist mein denkfehler?

von LED (Gast)


Lesenswert?


von My T. (mytrasher)


Lesenswert?

ich weiss .... das war ja nicht meine frage ich weiss das eine logische 
0 anliegen muss damit diese angehen und 1 damit ausgehen aber irgendwie 
finde ich meine schleife richtig machen tut es aber was anderes

von Karl H. (kbuchegg)


Lesenswert?

My Trasher schrieb:

> WAS es macht: 3 sec warten led 0-1 ausmachen 3sec warten led 0-1
> ANmachen led 2-3 ausmachen DANN wieder led0-1 anmachen etc...  wieso?

Weil die LED offensichtlich 'verkehrt rum' angesteuert werden müssen. 
Ein 0 Bit schaltet die LED ein, ein 1 Bit schaltet sie aus.

Das ist an und für sich nicht schlimm, man muss es nur bei den Ausgaben 
berücksichtigen.

> und noch was komisches: wenn ich das zweite " long_delay(3000);"
> entferne leuchten alle leds AUSSER led 2-3 ?

Was ist dran komisch?

Wenn du nach dem Lichtauschschalten das Licht SOFORT wieder einschaltest 
und dann 5 Sekunden wartest, ehe du das Licht ausschaltest und gleich 
darauf wieder einschaltest, dann wirst du eben die Dunkelphase kaum 
sehen.

Entrolle halt einfach mal deine Schleife ein wenig
Was pssiert, wenn man mal ein bischen verfolgt, wie die Schleife 
abgearbeitet wird?


   PORTB = ((1<<PB1) | (1<<PB0));
   long_delay(3000);
   PORTB = ((1<<PB2) | (1<<PB3));    // <----------

   PORTB = ((1<<PB1) | (1<<PB0));    // <----------
   long_delay(3000);
   PORTB = ((1<<PB2) | (1<<PB3));


Das da zwischen den beiden markierten Zeilen mal ganz kurz die anderen 
LED brennen, wirst du nicht sehen. Deine Augen machen nun mal bei 
Zeitdauern von ein paar Millionstel Sekunden nicht mehr mit.

von My T. (mytrasher)


Lesenswert?

die beschreibung zu den ports bitte nicht beachten sry die waren von 
anderem programm sry sollte ichv orher erwähnen

von My T. (mytrasher)


Lesenswert?

Ich dachte ich habs so verstanden...


PORTB = 0x00; // ALLE LEDS an

while(1) {  //endlosschleife

long_delay(3000); // warte 3 sec
PORTB = ((1<<PB1) | (1<<PB0)); //schalte led01 aus

PORTB = ((1<<PB2) | (1<<PB3)); // schalte led23 aus

aber NICHT das led 01 LEUCHTET und led23 immer aus ist?.... oder?


    }

von Karl H. (kbuchegg)


Lesenswert?

My Trasher schrieb:
> Ich dachte ich habs so verstanden...
>
>
> PORTB = 0x00; // ALLE LEDS an
>
> while(1) {  //endlosschleife
>
> long_delay(3000); // warte 3 sec
> PORTB = ((1<<PB1) | (1<<PB0)); //schalte led01 aus
>
> PORTB = ((1<<PB2) | (1<<PB3)); // schalte led23 aus
>
> aber NICHT das led 01 LEUCHTET und led23 immer aus ist?.... oder?

Nochmal: Sie ist nicht IMMER aus!

Aber sie leuchtet so kurz, dass du das nicht siehst!
Du kannst mit freiem Auge keine LED leuchten sehen, die ein paar 
MILLIONSTEL Sekunden leuchtet! Du unterschätzt die Geschwindigkeit mit 
der dein µC arbeitet. Und zwar ganz gewaltig!

Und der Rest ist eine Frage dessen, ob jetzt ein 0-Bit die LED zum 
leuchten bringt oder ein 1 Bit.
Beim STK500 bin ich mir jetzt gar nicht mal sicher, ob da nicht sogar 
ein 1 Bit die jweilige LED leuchten lässt. Überleg dir halt, wie du das 
testen kannst.

von My T. (mytrasher)


Lesenswert?

aber wieso ist dann led 01 dauerhaft an? oder geht diese so schnell aus 
und dann das ichs nicht sehe?

weil led2-3 SEHE ich wirklich fur ne milisekunde ein und ausgehen ^^ 
jeztt wo dus sagst

von Karl H. (kbuchegg)


Lesenswert?

My Trasher schrieb:
> aber wieso ist dann led 01 dauerhaft an? oder geht diese so schnell aus
> und dann das ichs nicht sehe?
>
> weil led2-3 SEHE ich wirklich fur ne milisekunde ein und ausgehen ^^

OK. Ein magst du vielleicht noch sehen, wenn man ganz genau in die LED 
sieht.
Aber die Aus-Phase der anderen LED sieht du nicht. Deine Netzhaut lässt 
das 'Bild' noch ein wenig nachleuchten.

von My T. (mytrasher)


Lesenswert?

ok hab das jetzt denke ich bissl kapiert :D ABER

while(1) {

long_delay(3000); // warte 3 sec
 PORTB = ((1<<PB1) | (1<<PB0)); //schalte led01 aus

 PORTB = ((1<<PB2) | (1<<PB3)); // schalte led23 aus

mussen die LEDS 0-3 dauerhaft AUS sein? oder wird nachdem die schleife 
durchlaufen ist die leds wieder eingeschaltet?

die 4 leds müssen doch alle zusammen aus sein und nicht nacheinander :(

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

My Trasher schrieb:
> ok hab das jetzt denke ich bissl kapiert :D ABER
>
> while(1) {
>
> long_delay(3000); // warte 3 sec
>  PORTB = ((1<<PB1) | (1<<PB0)); //schalte led01 aus
>
>  PORTB = ((1<<PB2) | (1<<PB3)); // schalte led23 aus
>
> mussen die LEDS 0-3 dauerhaft AUS sein?

NEIN

Bei diesem Code sieht der Ablauf folgendermaßen aus:

- LED 0 und 1 werden nach 3 Sekunden ausgeschaltet

- Sofort danach wird LED 0 und 1 eingeschaltet und LED 2 und 3
  ausgeschaltet

Dieser Vorgang wiederholt sich ständig.

von My T. (mytrasher)


Lesenswert?

omg so ist es also :( ich dachte die led 01 bleibt dauerhaft aus bis die 
schleife komplett durchlaufen ist :(
dachte es würde so ablaufen :  3sec warten led 0 1 aus dan sofort 23 
aus.. dan wieder alle an und von vorne :(

wie bringe ich led 01 dazu dauerthaft auszubleiben in der schleife?

sry wenn ich sie nerve

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Magnus M. schrieb:
> Dieser Vorgang wiederholt sich ständig.

Sprich:

LED 0 und LED 1 sind 3 Sekunden an und nur (seeehr) kurz aus.

LED 2 und LED 3 sind 3 Sekunden aus und nur (seeeehr) kurz an.

von Karl H. (kbuchegg)


Lesenswert?

Magnus M. schrieb:
>>  PORTB = ((1<<PB1) | (1<<PB0)); //schalte led01 aus
>>
>>  PORTB = ((1<<PB2) | (1<<PB3)); // schalte led23 aus
>>
>> mussen die LEDS 0-3 dauerhaft AUS sein?

Ich glaube, was du noch nicht behirrnt hast, ist das du zb mit

   PORTB = ((1<<PB2) | (1<<PB3));

eigentlich 2 Dinge machst
* du schaltest PB2 und PB3 auf 1
* ABER: im gleichen Atemzug schaltest du PB0 und PB1 auf 0

von My T. (mytrasher)


Lesenswert?

ok ich glaube das war das :/

ich dachte in der schleife kann ich led 01 ausmachen dann  led23 
ausmachen da led 01 ja schon aus ist... aber scheinbar schalten sind 
led01 wieder an...

jedoch die frage wie belasse ich led 01 in der auschaltphase dauerthaft 
wenn ich  dazu dan led 23 ausschalte

von Karl H. (kbuchegg)


Lesenswert?

My Trasher schrieb:
> ok ich glaube das war das :/
>
> ich dachte in der schleife kann ich led 01 ausmachen dann  led23
> ausmachen da led 01 ja schon aus ist... aber scheinbar schalten sind
> led01 wieder an...


  Was erwartest du.

  Du weißt zu (jetzt mal in Binärschreibweise geschrieben)

  PORTB = 0b00000011;

Bit 0 ist auf 1   --> Led aus
Bit 1 ist auf 1   --> Led aus
Aber: Bit2 ist auf 0   --> Led an
      Bit3 ist auf 0   --> Led an

> jedoch die frage wie belasse ich led 01 in der auschaltphase dauerthaft
> wenn ich  dazu dan led 23 ausschalte


Indem du lernst, dass man Einzelbits mittels Bitmanipulation beeinflusst

Bitmanipulation

und dann natürlich noch
AVR-GCC-Tutorial

von My T. (mytrasher)


Lesenswert?

ja das weiss ich aber scheinbar habe ich irgenwie nicht richtig 
verstnaden...

ich weiss dass..

PORTB = 0b00000011;
Bit 0 ist auf 1   --> Led aus
Bit 1 ist auf 1   --> Led aus
Aber: Bit2 ist auf 0   --> Led an
      Bit3 ist auf 0   --> Led an

jedoch dacht ich das wen ich

PORTB= 0b00000011;
mit PORTB = ((1<<PB2) | (1<<PB3));
mache
ich dann 0b00001111; bekomme :/

von Karl H. (kbuchegg)


Lesenswert?

My Trasher schrieb:


> PORTB= 0b00000011;
> mit PORTB = ((1<<PB2) | (1<<PB3));
> mache
> ich dann 0b00001111; bekomme :/

Warum sollte da das rauskommen?
Du machst
   PORTB = (1<<PB2) | (1<<PB3);

da steht eindeutig

   PORTB = 0b00001100;
                 ^^
                 ||
                 |+- PB2
                 +-- PB3

und das schaltet dann eben die LED entsprechend den 0-en und 1-en. PB2 
und PB3 sind zwar auf 1, aber PB0 und PB1 sind offensichtlich auf 0.

Wenn du den vorhergehenden Zustand von PORTB berücksichtigen willst, 
dann musst du den auch berücksichtigen. D.h. der muss in der Zuweisung 
in irgend einer Form ja wohl auftauchen. Und damit sind wir dann wieder 
bei
Bitmanipulation

von xfr (Gast)


Lesenswert?

My Trasher schrieb:
> jedoch dacht ich das wen ich
>
> PORTB= 0b00000011;
> mit PORTB = ((1<<PB2) | (1<<PB3));
> mache
> ich dann 0b00001111; bekomme :/

PORTB = ((1<<PB2) | (1<<PB3));
ist nichts anderes als:
PORTB = 0b00001100;

Was Du willst ist:
PORTB = PORTB | 0b00001100;

Also PORTB so lassen wie er ist und nur die zwei Bits zusätzlich auf 1 
setzen.

Kann man auch kürzer schreiben als:
PORTB |= 0b00001100;

oder:
PORTB |= ((1<<PB2) | (1<<PB3));

von My T. (mytrasher)


Lesenswert?

ich habe doch den port in der vorherigen eingabe doch längst verändert 
oder nicht?

ich habs ja verstanden das diese scheinbar wieder gelöscht werden in der 
nächsten eingabe :/ dennoch

von Karl H. (kbuchegg)


Lesenswert?

My Trasher schrieb:
> ich habe doch den port in der vorherigen eingabe doch längst verändert
> oder nicht?
>
> ich habs ja verstanden das diese scheinbar wieder gelöscht werden in der
> nächsten eingabe :/ dennoch

nicht scheinbar. Wenn du schreibst

   i = 5;
   i = 3;

dann ERWARTEST du, dass nach der zweiten Zuweisung i den Wert 3 hat und 
nicht irgendwelche Bits von der Zuweisung zuvor den Vorgang überleben!

Das dein i hier konkret PORTB heißt und die Bits da drinn auf LED 
herausgeführt sind, ist zwar ein netter Zufall, ändert aber am Prinzip 
nichts.

Zuweisung ist Zuweisung: alle Bits werden entsprechend der rechten Seite 
der Zuweisung neue gesetzt.

Alles andere wäre fatal! So könnte man nicht programmieren.

von My T. (mytrasher)


Lesenswert?

wäre das richtig wenn ich schreiben würde?

long_delay(3000); // warte 3 sec
 PORTB |= ((1<<PB1) | (1<<PB0)); //schalte led01 aus
long_delay(3000);
 PORTB |= ((1<<PB2) | (1<<PB3)); // schalte led23 aus


tut mir wirklich leid wenn ich es falsch mache aber bitte helft mir :D

edit : nu stimmt es  ich idiot danke :D

von Karl H. (kbuchegg)


Lesenswert?

My Trasher schrieb:
> wäre das richtig wenn ich schreiben würde?

Das kommt drauf an, was du als 'richtig' definierst.
Du bist der Progammierer. Was du als richtig definierst ist per 
Definition richtig.

> tut mir wirklich leid wenn ich es falsch mache aber bitte helft mir :D

Probiers halt aus!
Übe!

Du darfst sowieso nicht erwarten, dass du heute mit programmieren 
anfängst und nächste Woche bist du der Superstar.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Gezieltes Setzen einzelner Bits:

PORTB |= ((1<<PB2) | (1<<PB3));


Gezieltes Löschen einzelner Bits:

PORTB &= ~((1<<PB2) | (1<<PB3));


Gezieltes Togglen einzelner Bits:

PORTB ^= ((1<<PB2) | (1<<PB3));

von kopfkratzer (Gast)


Lesenswert?

Lies Dir mal das durch:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Bitfelder
Stichwort Bitmanipulation, wie Magnus M. schon geschrieben hat.

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.