Forum: Mikrocontroller und Digitale Elektronik uC LEDs blinken lassen


von Roland N. (eroli)


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:
1
.INCLUDE <m8def.inc>     ; Für den Controller die pass. Konstanten (z.B. RAMEND)
2
.CSEG                    ; Hinweis an Assembler: Ab hier alles in den FLASH-
3
                         ; Programmspeicher und NICHT z.B. in den EEPROM-Bereich
4
;------------------------------------------------------
5
;     Start-Adresse: 0000
6
;------------------------------------------------------
7
RESET:        ; entspricht .ORG 0000
8
  rjmp INIT   ; springe zum Hauptprogramm
9
10
;------------------------------------------------------
11
;     Interupt-Vektoren
12
;------------------------------------------------------
13
;    .....    Die Sprungadressen für die Interrupts:
14
;             In diesem Bereich sollte kein Programmcode stehen,
15
;             der nichts mit Interrupts zu tun hat.
16
17
.ORG INT_VECTORS_SIZE    ; Dadurch wurde Platz für die Vektoren reserviert
18
19
INIT:
20
; ----- INITIALISIERUNG ---------
21
  ldi r24,high(RAMEND)     ; Stack Pointer setzen
22
  out SPH,r24              ; "RAMEND" ist in m8def.inc (s.o.) festgelegt
23
  ldi r24,low(RAMEND)      ;
24
  out SPL,r24              ;
25
26
; ----- HAUPTPROGRAMM ------------
27
  ldi r16,0
28
  ldi r17,0xff
29
    out DDRB,r17              ; Portpins als Output konfigurieren
30
Hauptschleife:
31
  eor r16,r17
32
  out PORTB,r16
33
  ldi r20, 0xFF
34
  rjmp warte
35
  rjmp Hauptschleife        ; Hauptschleife endet nie
36
37
warte:
38
  dec r20
39
  cpi r20, 0x00
40
  breq end
41
  rjmp warte
42
end:
43
  rjmp Hauptschleife

von Karl H. (kbuchegg)


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
1
  ldi r20, 0xFF
2
3
warte:
4
  dec r20
5
  cpi r20, 0x00
6
  breq end
7
  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?

von Michael Z. (Gast)


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

von Roland N. (eroli)


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?

von Karl H. (kbuchegg)


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.
1
 ldi r20, 0xFF
2
3
....
4
5
warte:
6
  ldi r21, 0xFF
7
8
warte_1:
9
  dec r21
10
  brne warte_1
11
12
  dec r20
13
  cpi r20, 0x00
14
  breq end
15
  rjmp warte

von Roland N. (eroli)


Lesenswert?

Danke, das reicht tatsächlich!

von achja (Gast)


Lesenswert?

Da liebe ich doch mein BASCM:

Do

Toggle LED

Waitms 500

loop

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.