mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik uC LEDs blinken lassen


Autor: Roland M. (eroli)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich benutze den ATmega8 uC auf einem STK 500. Ich bin wirklich verdammt 
neu in dieser Materie. Vielleicht erinnern sich ja einige noch an meinen 
epischen Startthread ;-)

Ich habe mir einige HowTos angeschaut und weiß nun auch schon wie man 
LEDs an und ausschaltet, auf Schalter reagiert und natürlich, wie ich 
den uC programmieren kann.

Allerdings ist es mir immer noch ein Rätsel, wie ich eine LED blinken 
lassen kann?

Gibt es einen "Warte-Befehl"? Oder muss ich eine bestimmte Anzahl von 
NOPS durchführen, um ein blinken zu erhalten? Wenn ja, wieviele müssten 
das sein?

Hat vielleicht jemand sogar einen ASM-Snippet parat (aber bitte erstmal 
ohne Timer und Interrupts)?

Vielen Dank für eure Hilfe!

Ciao,
Eroli

PS: Ich hatte mir das so irgendwie gedacht, allerdings leuchten alle 
LEDs nur:
.INCLUDE <m8def.inc>     ; Für den Controller die pass. Konstanten (z.B. RAMEND)
.CSEG                    ; Hinweis an Assembler: Ab hier alles in den FLASH-
                         ; Programmspeicher und NICHT z.B. in den EEPROM-Bereich
;------------------------------------------------------
;     Start-Adresse: 0000
;------------------------------------------------------
RESET:        ; entspricht .ORG 0000
  rjmp INIT   ; springe zum Hauptprogramm

;------------------------------------------------------
;     Interupt-Vektoren
;------------------------------------------------------
;    .....    Die Sprungadressen für die Interrupts:
;             In diesem Bereich sollte kein Programmcode stehen,
;             der nichts mit Interrupts zu tun hat.

.ORG INT_VECTORS_SIZE    ; Dadurch wurde Platz für die Vektoren reserviert

INIT:
; ----- INITIALISIERUNG ---------
  ldi r24,high(RAMEND)     ; Stack Pointer setzen
  out SPH,r24              ; "RAMEND" ist in m8def.inc (s.o.) festgelegt
  ldi r24,low(RAMEND)      ;
  out SPL,r24              ;

; ----- HAUPTPROGRAMM ------------
  ldi r16,0
  ldi r17,0xff
    out DDRB,r17              ; Portpins als Output konfigurieren
Hauptschleife:
  eor r16,r17
  out PORTB,r16
  ldi r20, 0xFF
  rjmp warte
  rjmp Hauptschleife        ; Hauptschleife endet nie

warte:
  dec r20
  cpi r20, 0x00
  breq end
  rjmp warte
end:
  rjmp Hauptschleife


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Roland Moch schrieb:

> Allerdings ist es mir immer noch ein Rätsel, wie ich eine LED blinken
> lassen kann?

mache endlos
  LED einschalten
  warten
  LED ausschalten
  warten

> Gibt es einen "Warte-Befehl"?

nein

> Oder muss ich eine bestimmte Anzahl von
> NOPS durchführen

ja.

>, um ein blinken zu erhalten? Wenn ja, wieviele müssten
> das sein?

Wie wärs mit: ausrechnen?

Rechne dir doch mal aus, in welcher Zeit dein µC das hier
  ldi r20, 0xFF

warte:
  dec r20
  cpi r20, 0x00
  breq end
  rjmp warte

durchgehechelt hat.
So schnell kannst du nicht schauen :-)

Zuer Vereinfachung kannst du annehmen: 1 Befehl == 1 Taktzyklus
Dein µC arbeitet zb mit 1 Mhz. D.h er arbeitet in 1 Sekunde 1 Million 
Taktzyklen ab. Der zentrale Punkt deiner Warteschleife sind die 3 
Befehle

  dec r20
  cpi r20, 0x00
  rjmp warte

die 255 mal abgearbeitet werden. Wenn also 1 Befehl 1 Millionstel 
Sekunde dauert, wie lange dauert es dann bis das 255 mal durch ist?

Autor: Michael Z. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Kann es sein dass die LED dunkler leuchtet als davor? Wenn du nur von 
255 runter zählst macht das bei 8Mhz und den paar Warte-Befehlen eine 
Frequenz von über 1kHz, das sieht man mit dem Auge nicht mehr.

Wenn du ein Messgerät hast, das Frequenzen messen kann, versuch mal die 
frequenz an der LED zu messen, dann siehst du ob sie blinkt.

Um sie langsamer (sichtbar) blinken zu lassen brauchst du eine Frequenz 
von wenigen Hz. Dazu soltest du also bis mindestens 10000 in deinen 
Warteschleifen zählen. Gug mal im Datenblatt des AtMegas, dort gibt es 
einige schöne 16bit befehle, mit denen das leicht geht.

Gruß, Michael

Autor: Roland M. (eroli)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn also 1 Befehl 1 Millionstel
> Sekunde dauert, wie lange dauert es dann bis das 255 mal durch ist?

4 Millionstel Sekunden * 255 = 1020 Millionstel Sekunden

Das ist natürlich viel zu kurz, aber wie kann ich denn länger zählen? 
Der ATmega8 hat doch nur 8 Bit-Register...oder muss ich 2 ineinander 
verschachtelte SChleifen benutzen? Dann käme ich doch auf ungefähr 
255*255 = 65025 Befehle, aber auch das wird nict reichen, oder? (Und 
schön ist es auch nicht)

Wie kann man das anders realisieren?

> Gug mal im Datenblatt des AtMegas, dort gibt es
> einige schöne 16bit befehle, mit denen das leicht geht

Sorry, ich habe mir die InstructionSetSummary angeguckt, aber irgendwie 
finde ich nichts, dass mir da helfen könnte...

Wie kann man das denn hinkriegen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Roland Moch schrieb:

> 4 Millionstel Sekunden * 255 = 1020 Millionstel Sekunden
>
> Das ist natürlich viel zu kurz, aber wie kann ich denn länger zählen?
> Der ATmega8 hat doch nur 8 Bit-Register...

Du könntest ja zb die Funktionalität, die dir 1020 Millionstel Sekunden 
= ~ 1 tausendstel Sekunden wartet, wiederrum 255 mal aufrufen.

> oder muss ich 2 ineinander
> verschachtelte SChleifen benutzen? Dann käme ich doch auf ungefähr
> 255*255 = 65025 Befehle, aber auch das wird nict reichen, oder?

Wieder: rechnen!

> (Und
> schön ist es auch nicht)

Warum nicht?

OK, Warten in diesen Größenordnungen ist generell nicht schön. Aber 
solange du nichts mit Timern am Hut hast, geht es nicht anders.

> Sorry, ich habe mir die InstructionSetSummary angeguckt, aber irgendwie
> finde ich nichts, dass mir da helfen könnte...

Du brauchst die auch noch nicht.
Verschachtle 2 Schleifen ineinander und gut ists. Register hast du 
ohnehin noch genügend.
 ldi r20, 0xFF

....

warte:
  ldi r21, 0xFF

warte_1:
  dec r21
  brne warte_1

  dec r20
  cpi r20, 0x00
  breq end
  rjmp warte

Autor: Roland M. (eroli)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, das reicht tatsächlich!

Autor: achja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da liebe ich doch mein BASCM:

Do

Toggle LED

Waitms 500

loop

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.