mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LED blinken lassen - Falscher Rhytmus


Autor: blabla (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Freude herrscht, ich habe gerade mein erstes LED blinken lassen. Nur 
leider überhaupt nicht im Takt den ich wollte. Eigtnlich wollte ich 
immer eine Sekunde Licht und eine Sekunde dunkel.

Kann mir jemand sagen wieso das LED viel schneller wechselt?
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>

void sleep_ms(uint16_t ms);

#define LED_DDR    DDRB
#define LED_PORT  PORTB
#define LED_PORTPIN  PB0

int main(void){
  LED_DDR |= (1<<LED_PORTPIN);
  
  while(1){
    LED_PORT |= (1<<LED_PORTPIN);
    sleep_ms(1000);
    LED_PORT &= ~(1<<LED_PORTPIN);
    sleep_ms(1000);
  }
}

void sleep_ms(uint16_t ms){
  while(ms){
    ms--;
    _delay_ms(1);
  }
}

Ausgeführt wird das ganze auf dem STK500 mit einem Atmeag8515.

MFG

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Statt dieser seltsamen while-Schleife verwendest mal besser for ;)
Die Makros funktionieren natuerlich nur richtig, wenn erstens F_CPU 
korrekt gesetzt ist und Deine Taktquelle entsprechend genau ist.

Was heisst "viel schneller"? Und wie ist F_CPU definiert?

Autor: blabla (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,


Ich würde mal sagen das ganze läuft etwa 4 mal so schnell....
Wie mein F_CPU ist kann ich dir nict sagen. Ich arbeite mit dem AVR 
Studio und musste das nie angeben. Wo finde ich das?

MFG

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wozu eigendlich die funktion mit der schleife um den _delay_ms(1) und 
nicht direkt _delay_ms(ms) - hab ich schon öfter gesehen?

Abgesehen davon dass es bei eine sekunde besser wär, den µc in einen 
energiesparmodus zu schicken und ihn per watchdog wieder aufzuwecken.

Autor: blabla (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank, aber das ist so etwa mein erstes Programm. Also bitte noch 
keine Tipps wie man das ganze effizienter machen könnte...:)

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du F_CPU, also die Systemfrequenz des Controllers richtig im 
Projekt angegeben?

Autor: blabla (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo finde ich diese Einstellung in AVR-Studio?

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
in den projekteinstellungen, auf der seite, wo du die ziehlplattform 
auswählst. da gibts nen feld, wo man die Taktfrequenz eintragen muss.

Autor: and (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi blabla,
da du F_CPU nicht definiert hast wird eine Frequenz von 1000000 Hz 
angenommen.


#ifndef F_CPU
/* prevent compiler error by supplying a default */
# warning "F_CPU not defined for <util/delay.h>"
# define F_CPU 1000000UL
#endif

Du musst F_CPU deinen Takt anpassen.

Servus Andreas

Autor: blabla (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut habe ich gefunden.. Und was muss ich dort eintragen? 16mHz?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"16mHz" - Bloss nicht. Du müsstest fast 16s auf einen Wechsel warten!

Wenn 1 MHz (1000000 Hz) viermal zu schnell ist, würde ich als 
Schnellschuss mal 4000000 Hz (4 MHz) einstellen...

Autor: blabla (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank. Es stimmt nun mehr oder weniger. Gibt es auch ein System 
wie man diese Zahl genau heraus findet und nicht nur abschätzt? Das 
Programm habe ich von: 
http://www.rn-wissen.de/index.php/LED-Blinken_ohne_Timer

Dort verwenden sie 16MHz...

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
blabla schrieb:

> Vielen Dank. Es stimmt nun mehr oder weniger. Gibt es auch ein System
> wie man diese Zahl genau heraus findet und nicht nur abschätzt?

Man schaut sich seine Schaltung an und identifiziert die Taktquelle. 
Wenn es ein Quarz oder ein Oszillator ist, ist die Frequenz in MHz 
aufgedruckt. Wenn nicht kommt man mit einfachen Mitteln nicht weiter; 
man bräuchte einen Frequenzmesser oder ein Oszilloskop um die 
Taktfrequenz zu messen.

Wenn zusätzlich die AVR Fuses richtig auf diese externe Taktquelle 
eingestellt ist, ist man fertig: Die abgelesene Angabe in Hz trägt man 
als F_CPU ein.

Wenn die AVR Fuses noch in Werkseinstellung sind, dann passt 1000000 
Hz.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
blabla schrieb:

> Vielen Dank. Es stimmt nun mehr oder weniger.

Das mehr oder weniger liegt daran, dass du 1000x einen Funktionsaufruf 
und weiteren Code um die Wartefunktion (_delay_ms()) gepackt hast.

Ändere 1000x1ms Delay zum Spass mal in 1x1000ms oder 20*50ms oder 
10x100ms...

Autor: and (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi blabla,
welchen Takt verwendest du denn?
Extern oder intern?

Wenn du einen externen Takt verwendest wirf ein Blick auf den 
verwendeten Quarz, bzw. Resonator. Wenn du den internen Takt verwendet 
solltest du die FUSE Bits checken. Das können wir von hier nicht 
machen:)

Wenn sie in diesen Beispiel 16MHz verwenden liegt es daran das dort ein 
16MHz Quarz verwendet wird.

Servus
Andreas

Autor: blabla (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also wie gesagt ich bin zeimlicher Neuling. Also das einzige das mich an 
einen Quarz erinnert ist der Clock-Generator im Register HW Settings.

Dieser Wert ist auf 3.686 MHz....

Autor: and (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wird's sein. Stell mal diese Frequenz ein.
#define F_CPU 3686000

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du ein STK500?

Autor: blabla (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja hab ich nun gemacht. Nun scheint es ziemlich genau zu stimmen. Vielen 
Dank euch allen...

Benutze ich nun einen externen Quarz oder einen internen? :)

Autor: blabla (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Simon K.:

Ja.

Autor: and (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du benutzt einen externe Taktquelle.

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welchen Takt der Controller benutzt siehst Du bei den Fuses.

Connecte zum Board, dann waehl den Reiter 'Fuses' und check SUT_CKSEL. 
Steht dort 'Ext. Clock', dann benutzt Du den Taktgeber des STK500 
(dessen Frequenz Du unter HW Settings einstellen kannst).

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Unter SUT_CKSEL kannst Du natuerlich auch den internen Oscillator 
einstellen... Mit Frequenzwahl.

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:
> blabla schrieb:
>
>> Vielen Dank. Es stimmt nun mehr oder weniger.
>
> Das mehr oder weniger liegt daran, dass du 1000x einen Funktionsaufruf
> und weiteren Code um die Wartefunktion (_delay_ms()) gepackt hast.

Naja ne daran liegt es sicher nicht, sondern dass hier nicht klar ist, 
mit welchem Takt die MCU nun ueberhaupt laeuft.

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch als Ergaenzung: Die Controller sind im Auslieferungszustand auf 
einen internen Takt gestellt, der 8515, der mit dem Board mitgeliefert 
wird, steht schon auf extern (und wird somit vom Board getaktet). Wenn 
Du nichts verstellt hast, mit oben genannter Frequenz.

Das Board liefert den Takt uebrigens ueber einen Controller, nicht ueber 
ein Quarz oder Oszillator.. deswegen kann man den auch so prima 
verstellen. ;)

Ansonsten kann ich Dir nur das AVR Tutorial an's Herz legen. Da sind 
viele Fragen schon beantwortet.

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael G. schrieb:
> Stefan B. schrieb:
>> blabla schrieb:
>>
>>> Vielen Dank. Es stimmt nun mehr oder weniger.
>>
>> Das mehr oder weniger liegt daran, dass du 1000x einen Funktionsaufruf
>> und weiteren Code um die Wartefunktion (_delay_ms()) gepackt hast.
>
> Naja ne daran liegt es sicher nicht, sondern dass hier nicht klar ist,
> mit welchem Takt die MCU nun ueberhaupt laeuft.

Wieso nicht? Er meint sicher den Schleifenoverhead. Aber den merkt man 
wahrscheinlich nicht.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.