Forum: Mikrocontroller und Digitale Elektronik Lauflicht hin- und zurücklaufen


von Erna S. (ennaaa)


Lesenswert?

Das hier ist meine Programmierung für ein Lauflicht, welches durchläuft 
und immer wieder von vor beginnt.


;----------------------------------------------------------------------- 
------------
;-Programmheader-------------------------------------------------------- 
------------
;----------------------------------------------------------------------- 
------------
;Projekt   : Lauflicht soll hin- und zuruecklaufen
;Prozessor : AT90S8535
;Takt      : 8MHz
;
;Stand     :
;Fehler     :
;Hardware  :
;
;----------------------------------------------------------------------- 
------------
;-Deklarationen--------------------------------------------------------- 
------------
;----------------------------------------------------------------------- 
------------
.include "8535def.inc"    ; Prozessor ATmega8 einbinden

.def  vara = r16    ; Variable vara im ersten vollwertigen 8 Bit 
Register
.def  varb = r17    ; Variable varb im zweiten vollwertigen 8 Bit 
Register
.def  varc = r18    ; Variable varc im dritten vollwertigen 8 Bit 
Register
.def  lauflicht = r19  ; Variable für das Lauflicht

.cseg        ; Start eines Code Segments

rjmp RESET

RESET:
  ser vara
  out ddra, vara
  out ddrb, vara
  out ddrc, vara
  out ddrd, vara


RELOAD:
  ldi lauflicht, 0x01

START:
  cpi lauflicht, 0x00    ; Vergleicht, ob lauflicht den Wert "0" hat
  breq RELOAD        ; Wenn lauflicht "0" ist zu "RELOAD" springen, 
sonst weiter
  out porta, lauflicht
  rol lauflicht      ; Wert von lauflicht mit 2 multiplizieren








LOOP:
clr vara          ; Zähler dauert 0,5 sec.
clr varb
clr varc

LOOP1:
  inc vara
  cpi vara, 0x8C      ; innere Schleife = 153 Takte 99
  brne LOOP1
  clr vara


  inc varb
  cpi varb, 0x50      ; mittlere Schleife = 90 Takte 5A
  brne LOOP1
  clr varb


  inc varc
  cpi varc, 0x05      ; äußere Schleife = 29 Takte 1D
  brne LOOP1
  clr varc
  rjmp START









Nun möchte ich aber ein Lauflicht programmieren, welches durchläuft und 
vom Ende wieder zurückkommt, also quasi wieder rückwärts läuft.

Wie mache ich das???
Ich brauche dringend Hilfe!

von Frank E. (Firma: Q3) (qualidat)


Lesenswert?

- in einem Byte das niedrigste Bit auf 1 setzen
- das Byte 7x per BitShift Links oder Multiplikation mit 2 "behandeln", 
ausgeben
- das Byte 7x per Bitshift Rechts oder Division durch 2 "behandeln", 
ausgeben

von Erna S. (ennaaa)


Lesenswert?

Damit kann ich irgendwie nichts anfangen.

Also, wenn jemand mutig ist, kann er meinen Quellcode gern umschreiben.

von Peter D. (peda)


Lesenswert?

Nimm ne Tabelle, dann kannst Du beliebige Muster laufen lassen.


Peter

von Martin V. (oldmax)


Lesenswert?

Hi Anne
Du verwirrst mich ein wenig. Schau mal, das hast du geschrieben:
> Also, wenn jemand mutig ist, kann er meinen Quellcode gern umschreiben.
Nun, wenn das dein Quellcode ist, dann weißt du doch wie es geht. Ich 
mein, hier ist ja nun nicht die Mondlandung gefordert.
Daher meine Vermutung, der vorgelegte Code ist auch schon gekupfert und 
nun suchst du ein paar Deppen, die wieder deine Hausaufgaben machen. Na, 
dann man viel Erfolg ....
aber ich kann mich auch irren.......
Gruß oldmax

von Karl H. (kbuchegg)


Lesenswert?

Einen Hinweis geb ich dir aber (ich denke nämlich wie oldmax)

Das hier
1
RELOAD:
2
  ldi lauflicht, 0x01
3
4
START:
5
  cpi lauflicht, 0x00    ; Vergleicht, ob lauflicht den Wert "0" hat
6
  breq RELOAD        ; Wenn lauflicht "0" ist zu "RELOAD" springen,

musst du ersetzen. D.h. du musst nicht unbedingt, aber es ist einfacher 
wenn du es tust.

Bau das erst mal so um, dass es dieser Logik folgt

1
     ein Register mit 7 laden
2
     das Register 'lauflicht' mit 0x01 laden
3
4
Schleife
5
     lauflicht ausgeben
6
     lauflicht nach links schieben
7
8
     warten
9
10
     das 7-er Register um 1 runterzählen
11
     ist es jetzt zu 0 geworden?
12
     Nein -> Springe nach Schleife

dieser Code realisiert ziemlich offensichtlich die Beschreibung: 7 mal
schieben und ausgeben.

Wenn du das soweit hast, dann ist ein prinizpiell gleicher 2-ter Teil, 
der in die andere Richtung schiebt, nur noch ein Klacks.

von spess53 (Gast)


Lesenswert?

Hi

Bei rol/ror wird das Bit irgend wann ins Carry-Flag geschoben. Das 
reicht zu Ende-Erkennung. Ein zusätzlicher Zähler ist überflüssig.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Denk bitte drann, das Anna offenbar Anfängerin ist. Und das Wissen wie 
man programmtechnisch eine bestimmte Anzahl an Durchläufen abzählt für 
sie auch einen praktischen Nutzen hat. Denn lustigerweise hat sie das 
zwar in der Verzögerung benutzt, sieht sich aber ausserstande eine 
Schleife zu bauen, die eine Aktion genau 7 mal ausführt.

von Ro R. (rond_es)


Lesenswert?

Also wenn sie das oben wirklich selber gemacht hat, erwarte ich 
zumindest einen Versuch von ihr. Hausaufgaben werden hier nicht 
gemacht....aber es wird geholfen ;-)

von Erna S. (ennaaa)


Lesenswert?

Martin Vogel schrieb:
> Hi Anne
> Du verwirrst mich ein wenig. Schau mal, das hast du geschrieben:
>> Also, wenn jemand mutig ist, kann er meinen Quellcode gern umschreiben.
> Nun, wenn das dein Quellcode ist, dann weißt du doch wie es geht. Ich
> mein, hier ist ja nun nicht die Mondlandung gefordert.
> Daher meine Vermutung, der vorgelegte Code ist auch schon gekupfert und
> nun suchst du ein paar Deppen, die wieder deine Hausaufgaben machen. Na,
> dann man viel Erfolg ....
> aber ich kann mich auch irren.......
> Gruß oldmax



Hallo Martin,

nein, der Quellcode ist nicht "gekupfert", sondern ich bin gerade dabei 
die Assembler-Programmierung zu lernen. Das ist nach einer halben Woche 
intensive Beschäftigung rausgekommen und nun wollte ich mich einfach mal 
nicht im Denken anstrengen.
Aber das Vor- und Zurücklaufen des Lichtes habe ich jetzt schon 
hinbekommen.

Gruß
Anne

von Erna S. (ennaaa)


Lesenswert?

Vielen Dank an die, die hier etwas geholfen haben.
Leider bin ich wirklich Anfängerin auf dem Gebiet "Assembler" und das 
Verständnis für diese Sprache fehlt noch etwas.
Das normale Lauflicht entstand nach einer halben Woche, aber auch nicht 
ganz ohne Hilfe gebe ich zu.
Mittlerweile bin ich auf die Sache mit dem Vor- und Rücklauf gekommen, 
falls es euch beruhigt.
Jeder Anfang ist schwer, aber ich hoffe, dass ich noch weiterhin einige 
Hilfestellungen bei unerklärlichen Fragen bzw. Verständnisproblemen 
bekomme.

Gruß
Anne

von Martin V. (oldmax)


Lesenswert?

Hi Anne
Nun, wenn dem so ist kann ich dir natürlich auch helfen. Schau mal bei 
AVR-Praxis nach. Da ist ein ziemlich umfangreicher Beitrag "Keine Angst 
vor Assembler" im FAQ Bereich. Denke, er wird dir ein wenig 
weiterhelfen, auch das Verständnis für einige Vorgänge wecken.
Gruß oldmax

von M2 (Gast)


Lesenswert?

Und morgen fährt Anne wie in Night Rider rum ;)

von olli (Gast)


Lesenswert?

schönes projekt fuer anfaenger...
ich hab's mal eben "quick and dirty" in C51 geschrieben.


        MOV   p0,#1       ;startwert fuer port 0
        CLR   C           ;carry auf null

left:   MOV   A,p0        ;wert von port 0 in accu kopieren.
        RLC   A           ;accu-wert nach links durchs carry schieben.
        MOV   p0,A        ;geschobenen wert an port 0 ausgeben.
        JC    right       ;wenn carry=1, springe zu "right",
        ACALL delay       ;ansonsten rufe "delay" auf.
        SJMP  left        ;beginne wieder bei "left"

right:  MOV   A,p0        ;wert von port 0 in accu kopieren.
        RRC   A           ;accu-wert nach rechts durchs carry schieben.
        MOV   p0,A        ;geschobenen wert an port 0 ausgeben.
        JC    left        ;wenn carry=1, springe zu "left",
        ACALL delay       ;ansonsten rufe "delay" auf.
        SJMP  right       ;beginne wieder bei "left"

delay:  MOV   R0,#ffh     ;verzoegerungsschleife aussen
delay0: MOV   R1,#ffh     ;verzoegerungsschleife innen
delay1: DJNZ  R1,delay1   ;verzoegerungsschleife innen
        DJNZ  R0,delay0   ;verzoegerungsschleife aussen
        RET               ;funktion "delay" verlassen

von Erna S. (ennaaa)


Lesenswert?

M2 schrieb:
> Und morgen fährt Anne wie in Night Rider rum ;)

Das war mein Plan. ;D

von Christian B. (casandro)


Lesenswert?

Mach doch mal folgendes. Schreibe ein Lauflicht, welches einmal von 
links nach rechts läuft, und dann stehen bleibt, dann eines welches von 
rechts nach links läuft, und dann stehen bleibt, und schreibe beide 
hintereinander.

Im Pseudocode sieht das beispielsweise so aus:

hinlaufen:
x=1
schleife_hin:
  gebe x aus
  warte
  x verschieben nach links (nimm LSL, nicht ROL)
  ist x=0 (bit ganz hinaus geschoben)
  nein, dann zu schleife_hin
x=$40
schleife_zurück:
  gebe x aus
  warte
  x verschieben nach rechts (LSR)
  ist x=0 (bit ganz hinaus geschoben)
  nein, dann zu schleife_zurück
gehe zu hinlaufen:

Du schiebst somit Dein Bit ganz hinaus, und prüfst dass dann mit der 
Abfrage nach 0 ab. Da Du vor dem Verschieben das Bit ja schon ausgegeben 
hast, gibt es nie eine Phase in der 0 ausgegeben wird.

Übungsfrage:
Warum heißt die Zeile beim zurücklaufen x=$40 und nicht x=$80?

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.