Forum: Mikrocontroller und Digitale Elektronik Verzögerung bei Lauflicht / Atmega8 / C


von Tim0 (Gast)


Lesenswert?

Guten Tag,
ich habe vor 2 Tagen angefangen mich mit der 
Mikrocontroller-Programmierung
zu beschäftigen und habe nun versucht ein Lauflicht zu Programmieren 
welches hin und her läuft.
Das hin un her laufen habe ich hinbekommen, jedoch hat das Lauflich 
nachdem es einmal hin und her gelaufen ist eine kurze Verzögerung die 
ich nicht weg bekomme.
Könnt ihr mir evtl. sagen was ich falsch gemacht habe?
1
#include <util/delay.h>
2
#include <avr/io.h>  
3
4
int main(void)
5
{
6
7
int n, EINAUS=0;
8
9
DDRB = 0xFF; // Alle Pins in PORTB als Ausgang definieren
10
DDRD = 0x00; // Alle Pins in PORTD als Eingang definieren
11
PORTD = 0b00001100; // PULL-UP Widerstände für PD2 und PD3 setzen
12
13
14
15
while(1)
16
{
17
18
  if (!(PIND & (1<<PD2))) // Lauflicht einschalten
19
  {
20
  EINAUS = 1;
21
  }
22
23
  if (!(PIND & (1<<PD3))) // Lauflicht ausschalten
24
  {
25
  EINAUS = 0;
26
  }
27
28
  if (EINAUS == 1) 
29
  {
30
    for (n=0; n<=7; n++) // Pin 0-7
31
    {
32
      PORTB |= (1<<n); // Pin n im Port B setzen
33
      _delay_ms(1000); // Verzögerung von 1000ms
34
      PORTB &= ~(1<<n); // Pin n im Port B rücksetzen
35
    }
36
    
37
    for (n=7; n>=1; n--) // Pin 7-0
38
    {
39
      PORTB |= (1<<n); // Pin n im Port B setzen
40
      _delay_ms(1000); // Verzögerung von 1000ms
41
      PORTB &= ~(1<<n); // Pin n im Port B rücksetzen
42
    }
43
    
44
  }
45
  else
46
  {
47
  PORTB = 0x00; // Alle Pins im Port B auf 0 setzen
48
  }
49
}
50
51
}

Viele Grüße
Tim0

von Eric B. (beric)


Lesenswert?

Tipp: welche Werte nimmt n nacheinander an?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Tim0 schrieb:
> for (n=7; n>=1; n--) // Pin 7-0

 Und bit 0 ?

von Tobias (Gast)


Lesenswert?

Endlich kann ich mal helfen!
Die Antwort ist ganz einfach:

while(1)
{

  if (!(PIND & (1<<PD2))) // Lauflicht einschalten
  {
  EINAUS = 1;
  }

  if (!(PIND & (1<<PD3))) // Lauflicht ausschalten
  {
  EINAUS = 0;
  }

  if (EINAUS == 1)

Nach jedem Durchlauf wird geprüft, ob das alles zutrifft, das braucht
Zeit. Hatte damals am Anfang exakt das gleiche "Problem".
Eine interessante Lösung bieten die Interrupts, schon mal damit 
gespielt?
Ist wirklich einfach, man muss sich nur einmal durcharbeiten!

Grüße aus Wien!
Tobias

von jaja (Gast)


Lesenswert?

Tim0 schrieb:
>     for (n=0; n<=7; n++) // Pin 0-7
>     {
>       PORTB |= (1<<n); // Pin n im Port B setzen

eher die Frage wo PB8 ist.

von Peter II (Gast)


Lesenswert?

Tobias schrieb:
> Nach jedem Durchlauf wird geprüft, ob das alles zutrifft, das braucht
> Zeit.

und du glaubst irgend jemand sieht das? Die Abfrage geht in viel weniger 
als 1ms.

> Endlich kann ich mal helfen!
nicht wirklich.

von Torsten C. (torsten_c) Benutzerseite


Lesenswert?

Tim0 schrieb:
> jedoch hat das Lauflich
> nachdem es einmal hin und her gelaufen ist eine kurze Verzögerung die
> ich nicht weg bekomme.

Einmal von 0..7 und dann von 7..1.
Die 7 ist also 'doppelt' und leuchtet 2000ms.

Du willst vermutlich
1
for (n=0; n<=6; n++) // Pin 0-6 und
2
for (n=7; n>=1; n--) // Pin 7-1

von Walter S. (avatar)


Lesenswert?

jaja schrieb:
> eher die Frage wo PB8 ist.

das ist nicht die Frage denn es werden PB0 bis PB7 angesprochen

von Tim0 (Gast)


Lesenswert?

Danke für schnellen Antworten :)
Ich hatte gleich mehrere Fehler.
Eric B. schrieb:
> Tipp: welche Werte nimmt n nacheinander an?
Ich dachte die Verzögerung wäre nach einem Durchlauf, aber sie war 
mittendrin beim Wechsel zwischen den Schleifen.

Außerdem habe ich nur 6 LED's angeschlossen ^^'

Tobias schrieb:
> ...
> Nach jedem Durchlauf wird geprüft, ob das alles zutrifft, das braucht
> Zeit. Hatte damals am Anfang exakt das gleiche "Problem".
> Eine interessante Lösung bieten die Interrupts, schon mal damit
> gespielt?
> Ist wirklich einfach, man muss sich nur einmal durcharbeiten!
>
> Grüße aus Wien!
> Tobias

In diesem Fall war es wohl nicht der Fehler, aber das ist gut zu Wissen 
:)
Ich arbeite gerade die Videos von Stefan Wintgen durch, Interuppts sind 
tatsächlich das nächste Thema :)
https://www.youtube.com/watch?v=UpxemFUVnFI&index=5&list=PLg8rGAQEOsuh9ZCwP6aW5ycCM5PFFqoNe
Falls ihr noch weitere gute Tutorials zum Thema µC-Programmierung kennt, 
würde ich mich freuen wenn ihr diese hier Posten würdet :)

Marc V. schrieb:
> Tim0 schrieb:
>> for (n=7; n>=1; n--) // Pin 7-0
>
>  Und bit 0 ?

Bit 0 wird bei "Neustart" der If-Schleife wieder aufgerufen :)

Hier mein korrigierter Code
1
#include <util/delay.h>
2
#include <avr/io.h>  
3
4
int main(void)
5
{
6
7
int n, EINAUS=0;
8
9
DDRB = 0xFF; // Alle Pins in PORTB als Ausgang definieren
10
DDRD = 0x00; // Alle Pins in PORTD als Eingang definieren
11
PORTD = 0b00001100; // PULL-UP Widerstände für PD2 und PD3 setzen
12
13
14
15
while(1)
16
{
17
18
  if (!(PIND & (1<<PD2))) // Lauflicht einschalten
19
  {
20
  EINAUS = 1;
21
  }
22
23
  if (!(PIND & (1<<PD3))) // Lauflicht ausschalten
24
  {
25
  EINAUS = 0;
26
  }
27
28
  if (EINAUS == 1) 
29
  {
30
    for (n=0; n<=4; n++) // Pin 0-4 // bzw. LED 1-5
31
    {
32
      PORTB |= (1<<n); // Pin n im Port B setzen
33
      _delay_ms(1000); // Verzögerung von 1000ms
34
      PORTB &= ~(1<<n); // Pin n im Port B rücksetzen
35
    }
36
    
37
    for (n=5; n>=1; n--) // Pin 5-1 // bzw. LED 6-2
38
    {
39
      PORTB |= (1<<n); // Pin n im Port B setzen
40
      _delay_ms(1000); // Verzögerung von 1000ms
41
      PORTB &= ~(1<<n); // Pin n im Port B rücksetzen
42
    }
43
    
44
  }
45
  else
46
  {
47
  PORTB = 0x00; // Alle Pins im Port B auf 0 setzen
48
  }
49
}
50
51
}

Viele Grüße
Tim0

von Peter II (Gast)


Lesenswert?

Tim0 schrieb:
> PORTB |= (1<<n);

wenn man ganz genau sein will, dann darf man das auch so nicht 
schreiben. Bei einem Atmel wird (1<<n) in einer schleife berechnet. 
Damit hast du abhängig von n unterschiedliche Ausführungszeiten.

von Tobias (Gast)


Lesenswert?

Ach du meinst mit den eigenen Augen! Dachte du meinst am Oszi.
Da kann es kurz irritieren, aber eine LED zu vergessen ist auch gut.
Viel Erfolg weiterhin!

von Tim0 (Gast)


Lesenswert?

Peter II schrieb:
> Tim0 schrieb:
>> PORTB |= (1<<n);
>
> wenn man ganz genau sein will, dann darf man das auch so nicht
> schreiben. Bei einem Atmel wird (1<<n) in einer schleife berechnet.
> Damit hast du abhängig von n unterschiedliche Ausführungszeiten.

Wie könnte ich das denn alternativ schreiben?

Gruß
Tim0

von Peter II (Gast)


Lesenswert?

Tim0 schrieb:
> Wie könnte ich das denn alternativ schreiben?
1
uint8_t value = 1;
2
while( value != 128 )
3
{
4
      PORTB = value; // Pin n im Port B setzen
5
      _delay_ms(1000); // Verzögerung von 1000ms
6
      PORTB = 0;
7
      value = value << 1;
8
}
9
    
10
while( value != 1 )
11
{
12
      PORTB = value; // Pin n im Port B setzen
13
      _delay_ms(1000); // Verzögerung von 1000ms
14
      PORTB = 0;
15
      value = value >> 1;
16
}

aber den unterschied wirst du nicht sehen. Das geht dabei wirklich nur 
im ein paar Takte.

von Tim0 (Gast)


Lesenswert?

Peter II schrieb:
> Tim0 schrieb:
>> Wie könnte ich das denn alternativ schreiben?
> uint8_t value = 1;
> while( value != 128 )
> {
>       PORTB = value; // Pin n im Port B setzen
>       _delay_ms(1000); // Verzögerung von 1000ms
>       PORTB = 0;
>       value = value << 1;
> }
>
> while( value != 1 )
> {
>       PORTB = value; // Pin n im Port B setzen
>       _delay_ms(1000); // Verzögerung von 1000ms
>       PORTB = 0;
>       value = value >> 1;
> }
>
> aber den unterschied wirst du nicht sehen. Das geht dabei wirklich nur
> im ein paar Takte.

Danke :)
Auch wenn der Unterschied in dem Beispiel wohl kaum merkbar ist, wollte 
ich mir ganz gerne von vornherein angewöhnen sauberen Code zu schreiben. 
:)

Gruß
Tim0

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.