www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LED Blinken / Lauflicht


Autor: Sheester (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute

Wollt mir mit meinem STK500 und mienem ATMega8515 ein Lauflicht basteln. 
Da dies aber nicht so funktionierte wie ich wollte, hab ich mich 
entschlossen zuerst mal die LED's blinken zu lassen, da dies einfacher 
ist.

Beim ersten versuch mit folgendem code hats nicht geklappt:

//Codebeginn
.include "8515def.inc"

;PortB als ausgang deginieren
ser r16
out DDRB, r16

ser r18

Main:

ldi r16, 0xFF
out PortB, r16

Loop1:

dec r18
brne Loop1

clr r16

ldi r16, 0x00
out PortB, r16

Loop2:

dec r18

brne Loop2

rjmp Main
//Codeende

als ich dann aber dec r18 durch sbiw r30, 1 ersetzt habe, funktionierte 
es.

Ich frage mich aber warum? bei dec r18 wird doch von 0xFF bis 0x00 
runtergezählt bevor weitergemacht wird. Bei sbiw wird doch vom r30 
welches mit 0xFF geladen ist immer eins abgezogen, bis es ebenfalls auf 
0x00 ist. Seh ich das falsch? denn in meinen augen sollte beides das 
selbe bewirken.

So nun hab ich mienen zuvor erstellten Lauflichtcode ebenfalls mit sbiw 
"erweitert" jedoch passiert nun nichts anderes, als dass ein led nach 
dem andern zu leuchten anfängt, bis alle leuchten.

//Codeanfang
.include "8515def.inc"

ser r16
out ddrb, r16

ldi r16, 0xFF

Main:

sbiw r30, 1

brne main

ror r16

out PortB, r16

sbiw r30, 1

brne main

rjmp main
//Codeende

Was mache ich falsch?

Hoffe ihr könnt mir meine beiden fragen beantworten;)

Gruss

Sheester

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
dec dekrementiert ein Register, zählt also eins ab. sbiw zählt von einem 
RegisterPAAR eins ab. Dein Blinklicht sollte schon mit dem ersten Code 
funktionieren, allerdings blinkt das so schnell, dass du es nicht 
siehst. Wenn du da jetzt sbiw reinhaust, dekrementierst du damit einen 
16-Bit-Wert und deine Schleife läuft damit nicht nur 256, sondern 65536 
Takte lang. Das wirst du schon eher wahrnehmen können.
Für sowas solltest du aber einen Timer verwenden (Siehe Tutorial und 
Datenblatt).

Dein Lauflicht hat einige Fehler drin:
1. Deine zweite Schleife ist Blödsinn (Die springt ja sofort wieder zu 
main, da wird also gar keine Zeit vertrödelt).
2. Nach brne main ist in jedem Fall das Carry-Bit gesetzt, was ror dazu 
veranlasst, eine 1 in das Register zu schieben. Wenn du das nicht willst 
musst du entweder lsr (logical shift right) verwenden oder aber vor dem 
schieben noch clc (clear carry) ausführen.
3. Sobald du einmal ganz durchgeschoben hast ist das Register leer, bzw. 
voll, dann passiert beim Schieben nix mehr. Du solltest also nach dem 
Schieben prüfen, ob das Carry-Bit gesetzt ist (Ist der Fall wenn ein Bit 
"rausfällt") und dieses dann gleich wieder reinschieben.
Z.B.
brcc PC + 1   ;Branch if carry clear
  sbr r16, 1
(Ungetestet)

Autor: Christian Erker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weiterhin benutzt du die falsche Includedatei..

Die 8515def.inc ist für den AT90S8515, du brauchst die m8515def.inc.
Noch mag es gehen aber wenn du mehr machen willst kann sowas die 
absurdesten Fehler machen dank falscher I/O-Adressen.

Gruß,
Christian

Autor: Sheester (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen dank für die schnelle antwort

Also das mit der schlaufe hab ich geändert, war wirklich sinnlos;)

nun hab ich die weiteren tipps versucht umzusetzen, jedoch nicht 
wirklich mit erfolg.

Also ich hab mal ne grundätzliche frage zum befehl ror bzw rol.
Ich fülle ein register mit dem wert 0xFE das entspricht ja 11111110
Da beim board ja die LED's bei 0 leuchten leuchtet nur das Bit bzw LED 
0.

Soweit sogut. Wenn ich doch jetzt den befehl rol für das mit 0xFE 
gefüllte register andwende, sollte doch nichts anderes geschehen ausser 
dass alle bits nach links geschoben werden oder? das heisst es steht nun 
11111101 im register, oder seh ich das falsch? Also müsste doch nun das 
LED 1 leuchten. Wenn ich aber das Programm durchlaufen lassen, fängt 
eines nach dem anderen zu leuchten an...

Hoffe ihr könnt miene unklarheiten bzw. eventuelle fehlinterpretationen 
beseitigen.

Autor: Sheester (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
schieb;)

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sheester wrote:
> Also ich hab mal ne grundätzliche frage zum befehl ror bzw rol.
> Ich fülle ein register mit dem wert 0xFE das entspricht ja 11111110
> Da beim board ja die LED's bei 0 leuchten leuchtet nur das Bit bzw LED
> 0.
So weit noch richtig...
>
> Soweit sogut. Wenn ich doch jetzt den befehl rol für das mit 0xFE
> gefüllte register andwende, sollte doch nichts anderes geschehen ausser
> dass alle bits nach links geschoben werden oder?
So weit auch noch im Prinzip richtig...

> das heisst es steht nun
> 11111101 im register, oder seh ich das falsch?
Das siehst Du tatsächlich falsch. Es werden zwar alle Bits im Register 
nach links geschoben. Allerdings wird das höchstwertige Bit (also das 
ganz links) ins Carry-Flag geschoben und das, was vorher im Carry stand, 
wird von rechts ins Register reingeschoben. Wenn im Carry aber vorher ne 
Null stand, dann wird von hinten auch eine Null reingeschoben. Konkret:

       C   Register
       0   11111110
rol -> 1   11111100
usw...
Das Carry ist vor dem rol nur dann gesetzt, wenn bei der vorhergehenden 
Operation ein Überlauf aufgetreten ist.

> Also müsste doch nun das
> LED 1 leuchten. Wenn ich aber das Programm durchlaufen lassen, fängt
> eines nach dem anderen zu leuchten an...
Und das ist dann der Effekt davon.

EDIT:
Wenn Du mal in die Befehlssatz-Dokumentation schaust (entweder das 
Pamphlet mit dem Titel "Instruction Set Manual" von der ATMEL-Homepage 
oder die AVRStudio-Hilfe), dann steht da bei dem Befehl rol die 
Beschreibung "rotate left through carry" und weiter unten ist auch ein 
schönes Bildchen von der Prozedur. Das sollte eigentlich keine Fragen 
offenlassen.

Autor: Philipp Burch (philipp_burch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sry, da hatte ich mich oben wohl geirrt. Ich dachte, du willst eine 
einzelne 1 durchschieben, nicht einen 0. Ich ziehe es jedoch vor, LED 
EIN als 1 zu betrachten und erst direkt vor der Ausgabe die Daten mit 
com rxx umzudrehn.
;...
ldi r16, 1
loop:
  lsr r16
  brcc loop_a
    sbr r16, 128
  loop_a:

  ;Bits umdrehen und ausgeben
  com r16
  out PORTB, r16
  ;Und wieder zurückdrehen, damit es nachher wieder aufgeht
  com r16

  ;Mach mal 'ne Pause...
  rcall delay_100ms
rjmp loop
;...

Das könnte irgendwie so aussehn. Zugegeben, das doppelte umkehren ist 
etwas sinnlos, aber auf das kommt es im Allgemeinen ja nicht an. Falls 
doch:
;...
ldi r16, 254
loop:
  sec     ;Carry setzen, sonst wird eine 0 reingeschoben
  ror r16
  brcs loop_a
    cbr r16, 128
  loop_a:

  out PORTB, r16

  ;Mach mal 'ne Pause...
  rcall delay_100ms
rjmp loop
;...

Ist alles ungetestet.

Achja, diese Variante funktioniert auch mit anderen Mustern als 
einzelnen LEDs.

Autor: Holger Krull (krulli) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Original Demo-Soft für das STK hat doch schon alles was du 
brauchst...
... Guck mal ins User Guide vom STK500... Abschnitt 9
http://www.atmel.com/dyn/resources/prod_documents/...

und hier...

Beitrag "Re: Kann man einen AVR auch "auslesen" ??"

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.