Forum: Mikrocontroller und Digitale Elektronik LED blinken lassen mit AVR-GCC


von Harald (Gast)


Lesenswert?

Hey,
will eine LED mit hilfe von AVR-GCC mit einem attiny2313 zum blinken 
bringen.Hab auch schon gegoogled aber nix passendes gefunden.Ist eig ein 
ganz simples problem .
Bin bisher soweit:
1
#include <avr/io.h>          
2
3
int main (void) {            
4
 
5
   DDRB  = 0xff;             
6
   PORTB = (1<<PB1);             
7
 
8
   while(1) {                
9
    
10
   }                         
11
 
12
  // will hier nen timer drin haben der 500ms wartet //
13
14
15
DDRB  = 0xff;             
16
   PORTB = (0<<PB1);
17
   return 0;                 
18
}
wie stell ich das nun an?

: Gesperrt durch Moderator
von Karl H. (kbuchegg)


Lesenswert?

Indem du zb im
AVR-GCC-Tutorial
den Abschnitt über die delay Funktion liest.

von tsag (Gast)


Lesenswert?

Die Stelle wo dein Kommentar steht wird nie erreicht, da davor eine 
Endlosschleife steht.
Lies dir doch mal das AVR-GCC-Tutorial hier durch, hat mir auch sehr 
geholfen.
Dort steht auch ein Codeschnipsel wie man den µC für einige Zeit 
anhalten, bzw nichts tun lassen kann: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#avr-libc_Versionen_ab_1.6

von Verwirrter Anfänger (Gast)


Lesenswert?

1
#include <avr/io.h>          
2
int main (void) {            
3
  DDRB  = 0xff;             
4
  PORTB = (1<<PB1);             
5
  while(1) {                
6
    // Das hier ist eine Endlosschleife
7
  }                         
8
  // Der Code hier wird nie erreicht...
9
  
10
  DDRB  = 0xff;             
11
  PORTB = (0<<PB1);
12
  return 0;                 
13
}

Das hier sollte funktionieren:
1
#include <util/delay.h>
2
#include <avr/io.h>          
3
int main (void) {            
4
  DDRB  = 0xff;             
5
  while(1) {                
6
    PORTB |= (1<<PB1);    //Bit setzen
7
    _delay_ms(500);       // halbe sekunde warten
8
    PORTB &= ~(1<<PB1);   // Bit loeschen
9
    _delay_ms(500);       // halbe sekunde warten
10
  }                         
11
 return 0;                 
12
}

von Harald (Gast)


Lesenswert?

aso danke :D wusste nich dass ich unter delay gucken muss :D
1
#include <avr/io.h>          
2
#ifndef F_CPU
3
#define F_CPU 3686400UL
4
#endif
5
#include <util/delay.h>
6
7
int main (void) {            
8
 
9
   DDRB  = 0xff;             
10
   PORTB = (1<<PB1);             
11
 
12
   while(1) {                
13
 
14
  _delay_ms(1000);
15
   }                         
16
 DDRB  = 0xff;             
17
   PORTB = (0<<PB1);
18
  
19
   return 0;                 
20
}

ist das so korrekt?

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> ist das so korrekt?

Jein. Der Compiler wird es ohne Mosern übersetzen. Aber es wird nicht 
das Erwartete machen. Was du übrigens auch in der AVR-Simulation 
leicht selbst prüfen kannst, wenn du mit dem AVR Studio arbeitest.

von Lukas K. (carrotindustries)


Lesenswert?

Harald schrieb:
> aso danke :D wusste nich dass ich unter delay gucken muss :D
...
> ist das so korrekt?
Nein
Die LED geht an und nach einer Sekunde aus. Dennoch ist das PORTB = 
(0<<PB1); nicht richtig, informiere dich über Bitmanipulation

von Karl H. (kbuchegg)


Lesenswert?

Harald schrieb:

> ist das so korrekt?

Lass uns dein Programm erst mal sauber einrücken
1
#include <avr/io.h>
2
#ifndef F_CPU
3
#define F_CPU 3686400UL
4
#endif
5
#include <util/delay.h>
6
 
7
int main (void) {
8
9
  DDRB  = 0xff;
10
  PORTB = (1<<PB1);
11
12
  while(1) {
13
    _delay_ms(1000);
14
  }
15
16
  DDRB  = 0xff;
17
  PORTB = (0<<PB1);
18
19
  return 0;
20
}

Jetzt habe ich ein paar Fragen an dich:

* Warum willst du DDRB ein zweites mal setzen. 1 mal reicht. Wenn der
  Port auf Ausgang geschaltet ist, dann vergisst der das nicht.

* while( 1 )
  Das ist eine Schleife, die von einer Bedingung abhängig ist.
  Die Schleife wird solange wiederholt, wie die Bedingung wahr ist

  while( i > 5 )
  wäre zb eine Schleife, die solange wiederholt wird, wie eben i
  größer als 5 ist.

  Hier lautet die bedingung: 1
  1 ist ein Ausdruck, der immer wahr ist.

  Das bedeutet: Diese Schleife kann gar nicht verlassen werden. Eine
  sogenannte Endlosschleife.

  Das ist prinzipiell schon ok. Genau das wollen wir haben.

  Aber: Innerhalb der SChleife steht nur die _delay_ms
  Das heißt: Das Warten wird wiederholt. Wieder und immer wieder.
  Wie soll denn da also jemals eine LED ein oder aus geschaltet werden,
  was ja wohl notwendig ist, um ein Blinken zu erzeugen?

  Wenn die LED Blinken soll, dann würde man ja wohl erwarten, dass
  innerhalb der Endlosschleife die LED ein und auch wieder ausgeschaltet
  wird.

von Floh (Gast)


Lesenswert?

Luk4s K. schrieb:
> Die LED geht an und nach einer Sekunde aus.

Die LED geht nur an, danach hängt er in der Endlosschleife.
Außerdem gibt bei den delays zeitliche Obergrenzen, die zu beachten 
sind.

von Lukas K. (carrotindustries)


Lesenswert?

Floh schrieb:
> Luk4s K. schrieb:
>> Die LED geht an und nach einer Sekunde aus.
>
> Die LED geht nur an, danach hängt er in der Endlosschleife.
> Außerdem gibt bei den delays zeitliche Obergrenzen, die zu beachten
> sind.

Ich überlas wohl das while(1) :(

von Hubert G. (hubertg)


Lesenswert?

PORTB = (0<<PB1);

Glaubst du das sich damit was ändert?

von Karl H. (kbuchegg)


Lesenswert?

Hubert G. schrieb:
> PORTB = (0<<PB1);
>
> Glaubst du das sich damit was ändert?

Doch, das tut es.

Zwar nicht ganz das was beabsichtigt war, aber PORTB ändert den Zustand.

Beitrag #5004215 wurde von einem Moderator gelöscht.
Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.