Probleme beim Programmieren mit STK500 Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte
Autor |
Probleme beim Programmieren mit STK500 Suche nach: stk500 (120) |
|
|
|
|
BID = 339809
Jornbyte Moderator
Beiträge: 7178
|
|
Na will ich mal zerpflücken
Es ist ein 3-Fach Schleife, damit ist es mit wenigen Befehlen möglich eine lange Zeit zu warten.
ldi r16,0xff ;warte-wert
w1:
dec r16 ; r16 = r16 - 1
brne w1 ;teste ob r16 NULL ist, wenn nicht springe zu w1
In der schleife steht der Prozz für 255 durchläufe auf der Stelle. Da ist die Wartezeit, anhängig von der Taktfrequenz, relativ kurz. Nun wird geschachtelt:
ldi R17, 0x0F
|--wait0:
|.ldi R18, 0x37
|.|--wait1:
|.|..ldi R19, 0xC9
|.|.|--wait2:
|.|.|..dec R19
|.|.|--brne wait2 ;hier wird f x 37 x c9 gewartet, wenn alle 3 Register NULL sind, wird die Schleife beendet.
|.|..dec R18
|.|--brne wait1
|.dec R17
|--brne wait0
Denke dir die Punkte weg, sind nur Platzhalter. Nun sind die Schleifen zu erkennen.
_________________
mfg Jornbyte
Es handelt sich bei dem Tipp nicht um eine Rechtsverbindliche Auskunft und
wer Tippfehler findet, kann sie behalten. |
|
BID = 339891
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
|
Zitat :
|
der Befehl brne steht doch für ungleich, oder?
|
Im Prinzip schon. Der Befehl springt zum angegebenen Label, wenn Z 0 ist, also die vorhergegangene Operation nicht 0 als Ergebnis hatte.
_________________
|
|
BID = 339909
clembra Inventar
Beiträge: 5404 Wohnort: Weeze / Niederrhein
|
Einfach übersetzen:
BRanch if Not Equal
Springe wenn nicht gleich
_________________
Reboot oder be root, das ist hier die Frage.
|
BID = 340179
Humus Aus Forum ausgetreten
|
mit dem: "Springe wenn nicht gleich"
Wird das immer auf Null bezogen?
Oder kann man dafür auch einen Wert definieren?
|
BID = 340191
perl Ehrenmitglied
Beiträge: 11110,1 Wohnort: Rheinbach
|
Zitat :
| Wird das immer auf Null bezogen?
Oder kann man dafür auch einen Wert definieren? |
Die ganzen Conditional Branches (bedingte Verzweigungen) BRxy fragen lediglich die Flags im Statusregister ab.
Diese werden durch die vorhergehenden logischen oder arithmetischen Operationen beeinflusst.
BREQ oder BRNE fragt also lediglich das Z-Flag im Statusregister ab.
Das würde auch gesetzt, wenn bei einer Addition oder Subtraktion 0 herauskommt, oder zum Beispiel AND 01010101 mit 10101010 .
Um Werte miteinander zu vergleichen, gibt es die Compare CP.. (Vergleiche) Instruktionen.
Mathematisch sind das Subtraktionen, bei denen das Ergebnis weggeworfen wird, und nur die Flags entsprechend dem Ergebnis gesetzt werden.
Eine Ausnahme gibt es, das ist der CPSE Compare and Skip if Equal (Vergleiche und Überschlage den nächsten Befehl, wenn die Operanden gleich (bzw. das Ergebnis der Subtraktion =0) war).
Da hat man den Vergleich und den Sprung um 1 Instruktion vorwärts zu einer unteilbaren Einheit zusammengebaut.
Der dann übersprungene Befehl kann alles mögliche, auch eine Verzweigung, sein.
_________________
Haftungsausschluß:
Bei obigem Beitrag handelt es sich um meine private Meinung.
Rechtsansprüche dürfen aus deren Anwendung nicht abgeleitet werden.
Besonders VDE0100; VDE0550/0551; VDE0700; VDE0711; VDE0860 beachten !
|
BID = 340262
DonComi Inventar
Beiträge: 8605 Wohnort: Amerika
|
Zitat :
|
Im Prinzip schon. Der Befehl springt zum angegebenen Label, wenn Z 0 ist, also die vorhergegangene Operation nicht 0 als Ergebnis hatte.
|
Wie perl sagte, damit werden lediglich die SREG-Bits ausgewertet.
_________________
|
BID = 340665
Humus Aus Forum ausgetreten
|
@Perl
Dankeschön für die Erklärung!
|
BID = 341118
Humus Aus Forum ausgetreten
|
Moin,
also ich habe mich gestern Abend und heute Vormittag mal wieder an das Assembler programmieren gesetzt. Ich bin eigentlich auch recht zufrieden mit dem resultat. Danke eurer Hilfe hat das alles Super geklappt, dafür noch einmal ein riesen großes Dankeschön
So eine Frage hätte ich noch, könntet ihr euch vielleicht mal meinen Sourcecode anschauen, und mir eventuell Tipps geben was ich da vielleicht verändern sollte vom Aufbau und den Kommentaren. Also einfach nur ein paar Tipps wie ich den Code besser übersichtlicher oder vielleicht auch effektiver gestalten kann.
Angefangen vom Kopf bis zum Ende...
Wäre echt super Nett von euch! =)
Hier der Code
Schon mal ein großes Dankeschön vorweg
Code :
|
; ***********************************************************************************
; * LED-Steuerung.asm Version: 1.1 *
; * *
; * Hardware anforderung: ATtiny2313 *
; * *
; * Software funktion: Jede LED mit einem Taster An- und Ausschalten, beim An- *
; * schalten alle LEDs 10 mal blinken lassen, beim Ausschalten *
; * mit Taster 7 LED 0 und 7 3 mal blinken lassen *
; * *
; * Erstellt von: Dominic Hain *
; * Erstellt am: 14.06.2006 Letzte Änderung am: 15.06.2006 *
; * *
; * (c)Copyright 2006 by Dominic Hain *
; ***********************************************************************************
; Prozessor definieren
.NOLIST
.INCLUDE "tn2313def.inc" ; ATtiny2313
.LIST
; Register definieren
.DEF mg = R16
.DEF mc = R17
.DEF dl = R18
.DEF dc = R19
.DEF zaehl = R20
; Reset
rjmp main
; Hauptprogramm
main:
ldi mg, LOW(RAMEND) ; Stackpointer inizialisieren
out SPL, mg
ldi mg, 0xFF
out DDRB, mg ; PORTB 0-8 als Ausgang festlegen
ldi mg, 0x00
out DDRD, mg ; PORTD 0-8 als Eingang festlegen
ldi mg, 0xFF
out PORTB, mg ; Alle LEDs aus
; loop
loop:
sbis PIND, 0 ; Überspringe nächsten befehl wenn PIND, 0 Eins ist
rcall delay ; Springe zu Unterprogramm delay um den Taster zu entprellen
sbis PIND, 0 ; Überspringe nächsten befehl wenn PIND, 0 Eins ist
rcall taster_1 ; Springe zu Unterprogramm taster_1
sbis PIND, 1 ; Überspringe nächsten befehl wenn PIND, 1 Eins ist
rcall delay ; Springe zu Unterprogramm delay um den Taster zu entprellen
sbis PIND, 1 ; Überspringe nächsten befehl wenn PIND, 1 Eins ist
rcall taster_2 ; Springe zu Unterprogramm taster_2
sbis PIND, 2 ; Überspringe nächsten befehl wenn PIND, 2 Eins ist
rcall delay ; Springe zu Unterprogramm delay um den Taster zu entprellen
sbis PIND, 2 ; Überspringe nächsten befehl wenn PIND, 2 Eins ist
rcall taster_3 ; Springe zu Unterprogramm taster_3
sbis PIND, 3 ; Überspringe nächsten befehl wenn PIND, 3 Eins ist
rcall delay ; Springe zu Unterprogramm delay um den Taster zu entprellen
sbis PIND, 3 ; Überspringe nächsten befehl wenn PIND, 3 Eins ist
rcall taster_4 ; Springe zu Unterprogramm taster_4
sbis PIND, 4 ; Überspringe nächsten befehl wenn PIND, 4 Eins ist
rcall delay ; Springe zu Unterprogramm delay um den Taster zu entprellen
sbis PIND, 4 ; Überwspringe nächsten befehl wenn PIND, 4 Eins ist
rcall taster_5 ; Springe zu Unterprogramm taster_5
sbis PIND, 5 ; Überspringe nächsten befehl wenn PIND, 5 Eins ist
rcall delay ; Springe zu Unterprogramm delay um den Taster zu entprellen
sbis PIND, 5 ; Überspringe nächsten befehl wenn PIND, 5 Eins ist
rcall taster_6 ; Springe zu Unterprogramm taster_6
sbis PIND, 6 ; Überspringe nächsten befehl wenn PIND, 6 Eins ist
rcall delay ; Springe zu Unterprogramm delay um den Taster zu entprellen
sbis PIND, 6 ; Überspringe nächsten befehl wenn PIND, 6 Eins ist
rcall LEDs_aus ; Springe zu LEDs_aus
rjmp loop ; Endlosschleife
; taster_1
taster_1:
sbic PORTB, 0 ; Überspringe nächsten befehl wenn PORTB, 0 Null ist
rcall blinken ; Sprung zu Unterprogramm blinken
ldi mc, 0b11111110 ; Schalte LED an
sbis PORTB, 0 ; Überspringe nächsten befehl wenn PORTB, 0 Eins ist
ldi mc, 0xFF ; Schalte LED aus
out PORTB, mc ; Gebe an PORTB aus
ret
; taster_2
taster_2:
sbic PORTB, 1 ; Überspringe nächsten befehl wenn PORTB, 1 Null ist
rcall blinken ; Sprung zu Unterprogramm blinken
ldi mc, 0b11111101 ; Schalte LED an
sbis PORTB, 1 ; Überspringe nächsten befehl wenn PORTB, 1 Eins ist
ldi mc, 0xFF ; Schalte LED aus
out PORTB, mc ; Gebe an PORTB aus
ret
; taster_3
taster_3:
sbic PORTB, 2 ; Überspringe nächsten befehl wenn PORTB, 2 Null ist
rcall blinken ; Sprung zu Unterprogramm blinken
ldi mc, 0b11111011 ; Schalte LED an
sbis PORTB, 2 ; Überspringe nächsten befehl wenn PORTB, 2 Eins ist
ldi mc, 0xFF ; Schalte LED aus
out PORTB, mc ; Gebe an PORTB aus
ret
; taster_4
taster_4:
sbic PORTB, 3 ; Überspringe nächsten befehl wenn PORTB, 3 Null ist
rcall blinken ; Sprung zu Unterprogramm blinken
ldi mc, 0b11110111 ; Schalte LED an
sbis PORTB, 3 ; Überspringe nächsten befehl wenn PORTB, 3 Eins ist
ldi mc, 0xFF ; Schalte LED aus
out PORTB, mc ; Gebe an PORTB aus
ret
; taster_5
taster_5:
sbic PORTB, 4 ; Überspringe nächsten befehl wenn PORTB, 4 Null ist
rcall blinken ; Sprung zu Unterprogramm blinken
ldi mc, 0b11101111 ; Schalte LED an
sbis PORTB, 4 ; Überspringe nächsten befehl wenn PORTB, 4 Eins ist
ldi mc, 0xFF ; Schalte LED aus
out PORTB, mc ; Gebe an PORTB aus
ret
; taster_6
taster_6:
sbic PORTB, 5 ; Überspringe nächsten befehl wenn PORTB, 5 Null ist
rcall blinken ; Sprung zu Unterprogramm blinken
ldi mc, 0b11011111 ; Schalte LED an
sbis PORTB, 5 ; Überspringe nächsten befehl wenn PORTB, 5 Eins ist
ldi mc, 0xFF ; Schalte LED aus
out PORTB, mc ; Gebe an PORTB aus
ret
; LEDs_aus
LEDs_aus:
rcall blinken_aus ; Sprung zu Unterprogramm blinken_aus
ldi mc, 0xFF ; Schalte LEDs aus
out PORTB, mc ; Gebe an PORTB aus
ret
; delay 31,875ms
delay:
ldi dl, 0xFF ; lade 0xFF in dl
ldi dc, 0xFF ; lade 0xFF in dc
; wait
wait:
dec dl ; dl - 1
brne wait ; wenn dl nicht Null, dann Sprung zu wait
dec dc ; dc - 1
brne wait ; wenn dc nicht Null, dann Sprung zu wait
ret ; zurück
; delay_1
delay_1:
ldi dl, 0xFF ; dl definieren
; wait0
wait0:
dec dl ; dl - 1
brne wait ; wenn dl nicht Null, dann Sprung zu wait
ret ; zurück
; blinken
blinken:
ldi zaehl, 0xA ; zaehl definieren, LEDs 10 mal blinken lassen
;wait1
wait1:
ldi mc, 0b00000000 ; Schalte LED an
out PORTB, mc ; Gebe an PORTB aus
rcall delay_1 ; Springe zu Unterprogramm delay_1
ldi mc, 0xFF ; Schalte LED aus
out PORTB, mc ; Gebe an PORTB aus
rcall delay_1 ; Springe zu Unterprogramm delay_1
dec zaehl ; zaehl - 1
brne wait1 ; wenn zaehl nicht Null, dann Sprung zu wait
ret ; zurück zu taster_1 - 6
; blinken_aus
blinken_aus:
ldi zaehl, 0x3 ; zaehl definieren, LEDs 3 mal blinken lassen
; wait2
wait2:
ldi mc, 0b01111110 ; Schalte LED0 und 7 an
out PORTB, mc ; Gebe an Port aus
rcall delay_1 ; Spring zu Unterprogramm delay_1
ldi mc, 0b11111111 ; Schalte LEDs aus
out PORTB, mc ; Gebe an PORTB aus
rcall delay_1 ; Spring zu Unterprogramm delay_1
dec zaehl ; zaehl - 1
brne wait2 ; wenn zaehl nicht Null, dann Sprung zu wait2
ret ; zurück zu LEDs_aus
|
|
[ Diese Nachricht wurde geändert von: Humus am 15 Jun 2006 12:40 ]
|
BID = 341129
perl Ehrenmitglied
Beiträge: 11110,1 Wohnort: Rheinbach
|
Ein paar Empfehlungen für Schönheitsreparaturen also:
Derartiges ".DEF mg = R16" usw. solltest du auch in einer Include-Datei tun, dann kannst du sie bei ähnlichen Projekten einfach wiederverwenden.
Im Programm verstreute Konstanten wie " ldi mg, 0x00" machen eine Programmwartung nahezu unmöglich.
Der Assembler kann so nicht merken, wenn sich vielleicht deine Pinbelegung geändert hat, und diese Stellen von Hand im Programm zu suchen und zu ändern, ist mühsam und fehlerträchtig.
Deshalb auch dafür sprechende Namen verwenden und nur einmal an zentraler Stelle, am besten auch in separaten Include-Dateien definieren.
Auch Unterprogramme solltest du in separate Dateien schreiben.
Dann kann man sie leicht mal durch eine andere Version ersetzen, oder wenn nötig an eine andere Stelle im Speicher verschieben.
Und selbstverständlich erleichtert das auch die Wiederverwendung in neuen Programmen.
Hier
" sbis PIND, 0 ; Überspringe nächsten befehl wenn PIND, 0 Eins ist"
ist der Kommentar eigentlich überflüssig, denn er sagt nichts anderes aus, als der Assemblerbefehl.
Wenn Dir als Anfänger das hilft, ist es aber ok.
Grundsätzlich lieber zu viel kommentieren als zu wenig.
_________________
Haftungsausschluß:
Bei obigem Beitrag handelt es sich um meine private Meinung.
Rechtsansprüche dürfen aus deren Anwendung nicht abgeleitet werden.
Besonders VDE0100; VDE0550/0551; VDE0700; VDE0711; VDE0860 beachten !
|
BID = 341183
Humus Aus Forum ausgetreten
|
Danke Perl für deine Tipps! =)
Habe das Programm dem entsprechend mal ein bisschen abgeändert.
Code :
|
; ***********************************************************************************
; * LED-Steuerung.asm Version: 1.2 *
; * *
; * Hardware anforderung: ATtiny2313 *
; * *
; * Software funktion: Jede LED mit einem Taster An- und Ausschalten, beim An- *
; * schalten alle LEDs 10 mal blinken lassen, beim Ausschalten *
; * mit Taster 7 LED 0 und 7 3 mal blinken lassen *
; * *
; * Erstellt von: Dominic Hain *
; * Erstellt am: 14.06.2006 Letzte Änderung am: 15.06.2006 *
; * *
; * (c)Copyright 2006 by Dominic Hain *
; ***********************************************************************************
; Prozessor definieren
.NOLIST
.INCLUDE "tn2313def.inc" ; ATtiny2313
.LIST
; Register definieren
.INCLUDE "register.asm"
; Reset
rjmp main
; Hauptprogramm
main:
ldi mg, LOW(RAMEND) ; Stackpointer inizialisieren
out SPL, mg
ldi mg, 0xFF
mov aus, mg
ldi mg, 0x00
mov an, mg
out DDRB, aus ; PORTB 0-8 als Ausgang festlegen
out DDRD, an ; PORTD 0-8 als Eingang festlegen
out PORTB, aus ; Alle LEDs aus
; Unterprogramme
.INCLUDE "loop.asm" ; Endlosschleife, Taster abfragen
.INCLUDE "taster_1.asm"
.INCLUDE "taster_2.asm"
.INCLUDE "taster_3.asm"
.INCLUDE "taster_4.asm"
.INCLUDE "taster_5.asm"
.INCLUDE "taster_6.asm"
.INCLUDE "lauflicht.asm"
.INCLUDE "delay.asm" ; delay zum Taster Entprellen
.INCLUDE "delay_1.asm" ; delay für das Blinken der LEDs
.INCLUDE "blinken.asm" ; LEDs beim Anschalten blinken lassen
.INCLUDE "blinken_aus.asm" ; LEDs beim Ausschalten blinken lassen
|
|
Meintest du das so?
|
BID = 341188
clembra Inventar
Beiträge: 5404 Wohnort: Weeze / Niederrhein
|
Die Endlosschleife sollte nicht in eine andere Datei ausgelagert werden, da du von der Sprungmarke einiges abarbeitest, dann in die Include-Datei gehst und von da zur Sprungmarke in der anderen Datei zurückspringst, und das immer wieder (daher Endlosschleife )
Da die Taster_?-Unterprogramme alle relativ ähnlich sind kann man diese auch in eine Datei auslagern, es muss nicht für jedes UP eine eigene Datei vorhanden sein. Das wird dann nämlich mit der Zeit ehr unübersichtlich statt übersichtlich.
Ebenso die beiden Delay-Schleifen.
Dann kann man sich nämlich einen Ordner mit einigen Include-Dateien anlegen in denen direkt einige zusammenhängende Up drin sind und wenn man mal ein Up aus einer Datei nicht braucht löscht man es (in der Kopie im Projekt-Ordner) raus (spart Flash-Platz).
_________________
Reboot oder be root, das ist hier die Frage.
|
BID = 341286
perl Ehrenmitglied
Beiträge: 11110,1 Wohnort: Rheinbach
|
Zitat :
| ldi mg, 0xFF
mov aus, mg
ldi mg, 0x00
mov an, mg |
Das entspricht immer noch nicht der Empfehlung keine Konstanten ins Programm zu schreiben. Vermutlich hast du es nur übersehen. Daran erkennst du aber, wie schwer es ist, solche im Programm verstreute Konstanten vollzählig zu finden.
Daß du die gleichen Werte später für verschiedene Ports und sogar für die DDR verwendest, ist auch gefährlich.
Wenn weitere Portbits für andere Ausgabezwecke verwendet werden, kann ein "Aus" für Port B ganz anders aussehen, als eines, das nach Port D geschickt wird. Soetwas kann sogar an Portbits, die als Input verwendet werden, Fehler verursachen, weil dabei der interne Pullup-Widerstand ein- und ausgeschaltet wird.
Deshalb ist es zweckmäßig Werte wie "RotAus" und "GrünAus" zu definieren, und diese aber nicht für die DDR zu verwenden, sondern dort nochmals andere Namen zu erfinden.
Mit ein bischen Überlegung kann man solche miteinander verknüpften Konstanten den Assembler mittels NOT, AND und OR und Bitoperationen aus den anderen Definitionen ableiten lassen. Das verbraucht dann nur Platz auf dem Papier, nicht aber im Speicher.
@clembra:
Zitat :
| und wenn man mal ein Up aus einer Datei nicht braucht löscht man es (in der Kopie im Projekt-Ordner) raus |
Besser noch, man erledigt das per conditional assembly.
Dann braucht man nicht immer nachzuschauen und zu ändern.
Für Humus ist das aber noch zwei Nummern zu groß, und die Macrofähigkeiten, die ich bisher bei Atmel und Microchip gesehen habe, sind so umwerfend auch nicht.
_________________
Haftungsausschluß:
Bei obigem Beitrag handelt es sich um meine private Meinung.
Rechtsansprüche dürfen aus deren Anwendung nicht abgeleitet werden.
Besonders VDE0100; VDE0550/0551; VDE0700; VDE0711; VDE0860 beachten !
|
BID = 341297
clembra Inventar
Beiträge: 5404 Wohnort: Weeze / Niederrhein
|
Aus dem Grund hab ich geschrieben, einfach rauslöschen
Also meine Programme haben für gewöhnlich R16=Temp, R24=TempL, R25=TempH. Dann kann man Temp wunderbar für sowas nehmen. Einfach setzten bzw. Konstante zuweisen, an den entsprechenden DDR-Port ausgeben (der natürlich auch einen Namen hat, mit .equ led_port=portb) und dann kann man damit wieder machen was man will. TempL/H sind entweder für 16bit Sachen oder als zwei zusätzlich 8bit-Speicher verwendbar.
Wenn Temp in UP benutzt wird aber am Anfang ein "push temp" und vor dem ret ein "pop temp", damit der Wert fürs Hauptprogramm erhalten bleibt.
_________________
Reboot oder be root, das ist hier die Frage.
|
|
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 19 Beiträge im Durchschnitt pro Tag heute wurden bisher 17 Beiträge verfasst © x sparkkelsputz Besucher : 182423523 Heute : 2565 Gestern : 5459 Online : 532 29.11.2024 14:26 6 Besucher in den letzten 60 Sekunden alle 10.00 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
|
xcvb
ycvb
0.0378248691559
|