Mein Lauflicht :) Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte
Autor |
Mein Lauflicht :) |
|
|
|
|
BID = 274330
Alex86 Schreibmaschine
Avatar auf fremdem Server ! Hochladen oder per Mail an Admin
Beiträge: 1840
|
|
Hi @all
Ich hab mal ein Lauflicht programmiert.
Wenn ich es ohne Bremsschleife mache ist es kein Problem :)aber mit funktioniert es nicht richtig.
Vielleicht seht ihr ja meine Fehler
Hier erstmal ohne Bremssschleife:
Code :
|
ldi r17, 1 ; Register 17 ist der Zähler für die Bremsschleife
ldi r18, 3 ; Reg. 18 ist die Anzahl der Durchläufe für die Bremsschleife
ldi r19, 1 ; Reg. 19 ist die Schrittgröße mit der Reg 17 erhöht wird
ldi r16, 0xFF ; Port B auf
out DDRB, r16 ; Ausgang setzen
ldi r16, 0b00000001 ; Bits zuweisen
com r16 ; und komplementieren
out PORTB, r16 ; dann auf den Port geben
schleife: ; Hauptprogramm Schleife
rol r16 ; LED einen nach links
out PORTB, r16 ; auf Port ausgeben
rjmp schleife ; dann zum Hauptprogramm zurückspringen
|
|
Das geht auch alles:
11111110
11111101
11111011
11110111
etc.
so nun mit Bremsschleife:
Code :
|
ldi r17, 1 ; Register 17 ist der Zähler für die Bremsschleife
ldi r18, 3 ; Reg. 18 ist die Anzahl der Durchläufe für die Bremsschleife
ldi r19, 1 ; Reg. 19 ist die Schrittgröße mit der Reg 17 erhöht wird
ldi r16, 0xFF ; Port B auf
out DDRB, r16 ; Ausgang setzen
ldi r16, 0b00000001 ; Bits zuweisen
com r16 ; und komplementieren
out PORTB, r16 ; dann auf den Port geben
schleife: ; Hauptprogramm Schleife
rol r16 ; LED einen nach links
out PORTB, r16 ; auf Port ausgeben
bremse: ; Bremsschleife anfang
add r17,r19 ; Zähler um einen erhöhen
cp r17,r18 ; wenn Zähler = 3 (nur für Debugging, sonst = 8.000.000 = ca. 1 sec)
breq Zaehleraufeins ; dann zum Unterprogramm springen um das Zahlerreg. auf 1 zu setzen
rjmp bremse ; sonst Bremsschleife weiter ausführen
Zaehleraufeins:
ldi r17,1 ; R17 auf 1 setzen, damit die Bremseschleife wieder losgehen kann
rjmp schleife ; dann zum Hauptprogramm zurückspringen
|
|
Da siehts so aus:
11111110
11111101
11111010
11110100
11101000
Woran liegt das? Wisst ihr das?
(die Includes hatte ich auch richtig, hab ich jetzt nur im mom nicht, da dieses Beispiel aus einem emulator war (da gings genausowenig)
Danke schonmal im Voraus
LG Alex
_________________
|
|
BID = 274343
clembra Inventar
Beiträge: 5404 Wohnort: Weeze / Niederrhein
|
|
Mit ROL wird das Bit aus dem Carry-Bit rechts angefügt. Dieses wird aber durch die Bremse geändert.
Vor den Schleifen und nach dem Schieben
IN tempSREG,SREG
Vor dem Schieben
OUT SREG,tempSREG
tempSREG muss als ein Register definiert sein.
sollte das Problem temporär beheben.
Wenn es ein sichtbares Lauflicht werden soll und du mit dem uC nichts anderes machst kannst du doch sicher auch einen Timer einsetzten.
Gruß clembra
_________________
Reboot oder be root, das ist hier die Frage. |
|
BID = 274459
Jornbyte Moderator
Beiträge: 7178
|
Ich verwende für dieses Beispiel nur Befehle die für alle Atmel (mit Ram) anwendbar sind
Um einen anderen Prozz ans Laufen zu bringen muss nur der Includeeintrag und die Interrupttabelle geändert werden.
Zuerst sagen wir dem Assembler mal was da für ein µController Verwendung findet.
Das wird mit der Assembler Directive .include gemacht. In jedem Prozz sind paar Dinge vorhanden, wie zum Beispiel D/A-Wandler, Timer, Uart, bla bla...... .Diese Komponenten können sich über einen Interrupt melden. Dies führt dazu, das der Prozz zu einer festgelegten Adresse in der Interrupttabelle springt (Interrupt Vector Address). Vor dieser Tabelle ist noch Platz für einen einzigen Befehl. Damit soll es nun Losgehen. rjmp losgehts springt an den Anfang des Programm und da sagen wir dem Prozz was er alles verwenden soll. Der Stackpointer wird an das Ende vom Ram eingerichtet. Der braucht für dieses Beispiel nur wenig Platz Weiter geht’s mit PortB, der wird benötigt um paar LED blinken zu lassen. Dazu wird das Register 16 verwendet. Da steht eine 0x55 drin, Binär ist das 01010101. Dieses Muster wird an PortB ausgegeben.
Danach kommt der Befehl ror (Rotiere nach Rechts) . Nach dem warten (0,5 s) geht es zurück zur Marke main. Was passiert bei warten, das ist auch einfach. Es handelt sich um 3 Programmschleifen, die ineinander geschachtelt sind. Diese Schleifen werden erst beendet, wenn alle Register (r17, r18, r19) den Wert 0 erreicht haben.
Was kannst du ändern um andere Muster zu bekommen?
1, der Eintrag ldi r16,0x55 spiele mit werten von 0x01 bis 0xFE.
(bei 0x00 oder 0xFF sind alle LED an oder aus)
2, ror ändere den Befehl in rol , swap , inc oder dec
Da der PortD noch nicht benutzt ist, könntest du da noch Schalter anbringen um festgelegte Muster zu bekommen oder die Geschwindigkeit zu ändern.
.include "2313def.inc"
rjmp losgehts
reti ;INT0addr=$001 External Interrupt0 Vector Address
reti ;INT1addr=$002 External Interrupt1 Vector Address
reti ;ICP1addr=$003 Input Capture1 Interrupt Vector Address
reti ;OC1addr =$004 Output Compare1 Interrupt Vector Address
reti ;OVF1addr=$005 Overflow1 Interrupt Vector Address
reti ;OVF0addr=$006 Overflow0 Interrupt Vector Address
reti ;URXCaddr=$007 UART Receive Complete Interrupt Vector Address
reti ;UDREaddr=$008 UART Data Register Empty Interrupt Vector Address
reti ;UTXCaddr=$009 UART Transmit Complete Interrupt Vector Address
reti ;ACIaddr =$00a Analog Comparator Interrupt Vector Address
losgehts:
ldi r16,RAMEND ;Init Stack Pointer
out SPL,r16
ldi r16,0xFF ;Init PortB (0=In / 1=Out)
out ddrb,r16 ;alle Leitungen sind Ausgänge
ldi r16,0x55 ;in r16 steht das Bitmuster (01010101)
main:
out portb,r16 ;ausgeben
ror r16 ;01010101 zu 10101010
rcall warte ;ne halbe sekunde warten
rjmp main ;und wieder von vorn
; warte 0,5 sekunden bei 4 MHz Takt
warte:
ldi R17, 0x12
LOOP0:
ldi R18, 0xBC
LOOP1:
ldi R19, 0xC4
LOOP2:
dec R19
brne LOOP2
dec R18
brne LOOP1
dec R17
brne LOOP0
ret
/Edit Programmcode einfügen geht nicht, das wird ja Ellenlang
[ Diese Nachricht wurde geändert von: Jornbyte am 27 Nov 2005 22:31 ]
|
BID = 274466
Alex86 Schreibmaschine
Avatar auf fremdem Server ! Hochladen oder per Mail an Admin
Beiträge: 1840
|
Erstmal Danke an Clembra und Jorn
Ich hab heute nochmal das versucht was Clembra sagte.
Nun hab ich das Problem mit dem Carry Bit auch in den Griff gekriegt.
Ich poste nochmal den geänderten Source (mit dem Lauflicht was nun auch funktioniert) Delay zwischen dem Rol ist 1 Sec. (hab in dem Emulator nochmal getestet, haut sogar hin):) Das läuft jetzt wie in Echt ab
Hier nochmal die Version, die mit der Bremsschleife nun auch funktioniert:
Code :
|
.include "2313def.inc"
start:
ldi r17, 1 ; Register 17 ist der Zähler für die Bremsschleife
ldi r18, 8000000 ; Reg. 18 ist die Anzahl der Durchläufe für die Bremsschleife
ldi r19, 1 ; Reg. 19 ist die Schrittgröße mit der Reg 17 erhöht wird
ldi r16, 0xFF ; Port B auf
out DDRB, r16 ; Ausgang setzen
ldi r16, 0b00000001 ; Bits zuweisen
com r16 ; und komplementieren
out PORTB, r16 ; dann auf den Port geben
ldi r23, 00000001
schleife: ; Hauptprogramm Schleife
out sreg,r23
rol r16 ; LED einen nach links
out PORTB, r16 ; auf Port ausgeben
in r23,sreg
bremse: ; Bremsschleife anfang
add r17,r19 ; Zähler um einen erhöhen
cp r17,r18 ; wenn Zähler = 3 (nur für Debugging, sonst = 8.000.000 = ca. 1 sec)
breq Zaehleraufeins ; dann zum Unterprogramm springen um das Zahlerreg. auf 1 zu setzen
rjmp bremse ; sonst Bremsschleife weiter ausführen
Zaehleraufeins:
ldi r17,1 ; R17 auf 1 setzen, damit die Bremseschleife wieder losgehen kann
rjmp schleife ; dann zum Hauptprogramm zurückspringen
|
|
Dann werde ich mir als nächstes mal Jorns Version reinziehen, die ja wesentlich resourcenschonender mit dem Atmel umgeht, da Interrupt-Benutzung.
Sieht nicht ganz einfach aus der Programm aber ich schau mal, ob ich da mithilfe der guten Erklärung von Jorn durchsteige
Danke für das Listing Jorn
_________________
|
BID = 274467
Alex86 Schreibmaschine
Avatar auf fremdem Server ! Hochladen oder per Mail an Admin
Beiträge: 1840
|
So hab nochmal in der "Bremssschleifen-Version" von Clembra versucht.
Nun geht das auch (mit diesem VMLab-Emulator sogar in Echtzeit *lob*)
Hier mal der korrekte Code:
Code :
|
.include "2313def.inc"
start:
ldi r17, 1 ; Register 17 ist der Zähler für die Bremsschleife
ldi r18, 8000000 ; Reg. 18 ist die Anzahl der Durchläufe für die Bremsschleife
ldi r19, 1 ; Reg. 19 ist die Schrittgröße mit der Reg 17 erhöht wird
ldi r16, 0xFF ; Port B auf
out DDRB, r16 ; Ausgang setzen
ldi r16, 0b00000001 ; Bits zuweisen
com r16 ; und komplementieren
out PORTB, r16 ; dann auf den Port geben
ldi r23, 00000001
schleife: ; Hauptprogramm Schleife
out sreg,r23
rol r16 ; LED einen nach links
out PORTB, r16 ; auf Port ausgeben
in r23,sreg
bremse: ; Bremsschleife anfang
add r17,r19 ; Zähler um einen erhöhen
cp r17,r18 ; wenn Zähler = 3 (nur für Debugging, sonst = 8.000.000 = ca. 1 sec)
breq Zaehleraufeins ; dann zum Unterprogramm springen um das Zahlerreg. auf 1 zu setzen
rjmp bremse ; sonst Bremsschleife weiter ausführen
Zaehleraufeins:
ldi r17,1 ; R17 auf 1 setzen, damit die Bremseschleife wieder losgehen kann
rjmp schleife ; dann zum Hauptprogramm zurückspringen
|
|
So als nächstes guck ich mir mal Jorns Listing an, das ja - dank Interruptbenutzng - viel ressourcenschonender sein dürfte.
Durch seine gute Erklärung werde ich da wohl auch, nach paar mal angucken durchsteigen
Viel Dank Jorn Und vielen Dank Clembra, für deine "Bremsschleifen-Version-Hilfe"
Melde dann später ob ich das die Version von Jorn hin gekriegt hab
Vielen Dank
LG Alex
_________________
|
BID = 274468
Alex86 Schreibmaschine
Avatar auf fremdem Server ! Hochladen oder per Mail an Admin
Beiträge: 1840
|
So hab nochmal in der "Bremssschleifen-Version" von Clembra versucht.
Nun geht das auch (mit diesem VMLab-Emulator sogar in Echtzeit *lob*)
Hier mal der korrekte Code:
.include "2313def.inc"
start:
ldi r17, 1 ; Register 17 ist der Zähler für die Bremsschleife
ldi r18, 8000000 ; Reg. 18 ist die Anzahl der Durchläufe für die Bremsschleife
ldi r19, 1 ; Reg. 19 ist die Schrittgröße mit der Reg 17 erhöht wird
ldi r16, 0xFF ; Port B auf
out DDRB, r16 ; Ausgang setzen
ldi r16, 0b00000001 ; Bits zuweisen
com r16 ; und komplementieren
out PORTB, r16 ; dann auf den Port geben
ldi r23, 00000001
schleife: ; Hauptprogramm Schleife
out sreg,r23
rol r16 ; LED einen nach links
out PORTB, r16 ; auf Port ausgeben
in r23,sreg
bremse: ; Bremsschleife anfang
add r17,r19 ; Zähler um einen erhöhen
cp r17,r18 ; wenn Zähler = 3 (nur für Debugging, sonst = 8.000.000 = ca. 1 sec)
breq Zaehleraufeins ; dann zum Unterprogramm springen um das Zahlerreg. auf 1 zu setzen
rjmp bremse ; sonst Bremsschleife weiter ausführen
Zaehleraufeins:
ldi r17,1 ; R17 auf 1 setzen, damit die Bremseschleife wieder losgehen kann
rjmp schleife ; dann zum Hauptprogramm zurückspringen
So als nächstes guck ich mir mal Jorns Listing an, das ja - dank Interruptbenutzng - viel ressourcenschonender sein dürfte.
Durch seine gute Erklärung werde ich da wohl auch, nach paar mal angucken durchsteigen
Viel Dank Jorn Und vielen Dank Clembra, für deine "Bremsschleifen-Version-Hilfe"
Melde dann später ob ich das die Version von Jorn hingekriegt hab
Vielen Dank
LG Alex
_________________
|
BID = 274469
Alex86 Schreibmaschine
Avatar auf fremdem Server ! Hochladen oder per Mail an Admin
Beiträge: 1840
|
test
_________________
|
BID = 274565
clembra Inventar
Beiträge: 5404 Wohnort: Weeze / Niederrhein
|
Jornbytes Code läuft nicht mit Interrupts!
Er hat lediglich die Interruptvektoren den RETI-Befehl geschrieben, welcher besagt, dass wenn ein Interrupt aufgerufen wird keine unkontrolliere Aktion ausgeführt wird, wie das Neustarten des Programmes z.B. ab der 5. Zeile, sondern nichts getan wird und zurück zum normalen Programmablauf gesprungen wird.
Für den Wartebefehl hat er ein Unterprogramm geschrieben.
Wenn du SWAP durch ROR ersetzt, wird es da wahrscheinlich auch nicht funktionieren.
Im übrigen ist es Unklug, etwas über die komplette Prozedur (Hauptschleife) nur im SREG-Bit (Carry) zu speichern, da ein Befehl genügt um diesen zu ändern und nichts funktioniert mehr.
Für ein "gutes" Programm hab ich noch einige Fragen:
Wie sieht deine Hardware aus (Schaltbild)?
Soll der Controller nur für das 8-Bit-Lauflicht sein?
Hast du eigentlich schon geschrieben, welchen uC du verwendest oder steht das noch offen?
Der AT90S2313 ist für neue Layouts schlecht, da er nicht mehr produziert wird.
Gruß clembra
_________________
Reboot oder be root, das ist hier die Frage.
|
BID = 274618
Alex86 Schreibmaschine
Avatar auf fremdem Server ! Hochladen oder per Mail an Admin
Beiträge: 1840
|
Hab meinen Code mit Bremsschleife auch fertig.
Wollte um 16 Uhr schon posten ging aber nicht.
So hier mal mit Bremsschleife:
Code :
|
.include "2313def.inc"
start:
ldi r17, 1 ; Register 17 ist der Zähler für die Bremsschleife
ldi r18, 8000000 ; Reg. 18 ist die Anzahl der Durchläufe für die Bremsschleife
ldi r19, 1 ; Reg. 19 ist die Schrittgröße mit der Reg 17 erhöht wird
ldi r16, 0xFF ; Port B auf
out DDRB, r16 ; Ausgang setzen
ldi r16, 0b00000001 ; Bits zuweisen
com r16 ; und komplementieren
out PORTB, r16 ; dann auf den Port geben
ldi r23, 00000001
schleife: ; Hauptprogramm Schleife
out sreg,r23
rol r16 ; LED einen nach links
out PORTB, r16 ; auf Port ausgeben
in r23,sreg
bremse: ; Bremsschleife anfang
add r17,r19 ; Zähler um einen erhöhen
cp r17,r18 ; wenn Zähler = 3 (nur für Debugging, sonst = 8.000.000 = ca. 1 sec)
breq Zaehleraufeins ; dann zum Unterprogramm springen um das Zahlerreg. auf 1 zu setzen
rjmp bremse ; sonst Bremsschleife weiter ausführen
Zaehleraufeins:
ldi r17,1 ; R17 auf 1 setzen, damit die Bremseschleife wieder losgehen kann
rjmp schleife ; dann zum Hauptprogramm zurückspringen
|
|
Das funzt dann auch.
Ich werde einen AT90S2313 verwenden mit 8 Bit.
Also im Emulator lief das Programm
Danke für die Tipps Clembra und auch danke an Jorn
Werd mir das alles morgen oder so nochmal reinziehen
_________________
|
BID = 274647
Jornbyte Moderator
Beiträge: 7178
|
@clembra
Alex86 steht am Anfang mit µC. Wir ackern oftmal im Chat. Das hier ist nur eine kleine Hilfe.
/Edit für den ersten versuch hat er es schon gut gemacht, auch wenn da noch Fehler sind. Haben wir nicht alle klein angefangen
_________________
mfg Jornbyte
Es handelt sich bei dem Tipp nicht um eine Rechtsverbindliche Auskunft und
wer Tippfehler findet, kann sie behalten.
|
BID = 274665
tixiv Schreibmaschine
Beiträge: 1492 Wohnort: Gelsenkirchen
|
Das wird so leider nicht klappen, denn die Rergister beim AVR können nur Werte von 0 bis 255 halten. 8 bit halt. Wenn man mehr Schleifendurchläufe möchte, dann muss man so wie Jornbyte mehrere verschachtelte Schleifen verwenden.
|
BID = 274810
clembra Inventar
Beiträge: 5404 Wohnort: Weeze / Niederrhein
|
Ich hab das ganze mal schön verpackt.
Wenn es Probleme beim Verständnis gibt, immer raus damit.
Die Ports benenne ich mit soundso-rein, soundso-ddr, ... damit ich nicht für jede IO-Adresse einen eigenen Namen brauche und bei Eingängen grundsätzlich die Pull-Ups angesprochen habe
Der Wartecode ist von Jornbyte übernommen worden.
Wenn die Leerphase (zw. Bit0 und Bit7) gewollt war, bitte Melden, dann ändere ich das wieder. Ich glaube dass es ohne schöner aussieht
Gruß clembra
_________________
Reboot oder be root, das ist hier die Frage.
|
BID = 283458
Jornbyte Moderator
Beiträge: 7178
|
Fehler in ID = 283453 wurden im Chat besprochen.
_________________
mfg Jornbyte
Es handelt sich bei dem Tipp nicht um eine Rechtsverbindliche Auskunft und
wer Tippfehler findet, kann sie behalten.
|
BID = 283647
Alex86 Schreibmaschine
Avatar auf fremdem Server ! Hochladen oder per Mail an Admin
Beiträge: 1840
|
start:
ldi r17, 12
ldi r16, 0
.def lpm_reg = r0
Matrix:
.db 0b10000001
.db 0b01000010
.db 0b00100100
.db 0b00011000
.db 0b00100100
.db 0b01000010
.db 0b10000001
ldi r16, 0xFF ; Port B auf
out DDRB, r16 ; Ausgang setzen
ldi ZH,high(2*Matrix)
ldi ZL,low(2*Matrix)
weiter:
lpm
out PORTB, r0 ; auf Port ausgeben
adiw ZL,1
inc r16
cp r16,r17
brne weiter
ldi ZH,high(2*Matrix)
ldi ZL,low(2*Matrix)
ldi r16,0
rjmp weiter ; dann zum Hauptprogramm zurückspringen
_________________
|
|
Zum Ersatzteileshop
Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum
Datenschutz
Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland
gerechnet auf die letzten 30 Tage haben wir 20 Beiträge im Durchschnitt pro Tag heute wurden bisher 12 Beiträge verfasst © x sparkkelsputz Besucher : 182399630 Heute : 6828 Gestern : 7548 Online : 742 25.11.2024 21:31 6 Besucher in den letzten 60 Sekunden alle 10.00 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
|
xcvb
ycvb
0.0548350811005
|