Hallo,
Im Rahmen eines Schulprojektes baue ich gerade einen mobilen Roboter.
Nachdem ich es geschafft habe die Schrittmotoren anzeusteuern, möchte
ich nun deren gemachte Schritte im SRAM speichern, sowie die dazu
gehörende Richtung. In der angehängten Datei ist der Code für eine
Testversion mit einem Schrittmotor. Es gibt vereinfacht fünf Richtungen,
Vor1,Vor2... und STOP. Die Richtung soll im SRAM gespeichert werden, die
zwei folgenden Bytes im SRAM, nach der zugehörigen Richtung, sollen für
die Schrittzählung genutzt werden. Somit hat Jede Richtung mit ihren
Schritten 3 Bytes Reservierung. Aus irgendeinem Grund wird jedoch nichts
gespeichert. Warum speichert er nichts ab? Ich weiß nicht mehr weiter,
habe schon alles durchsucht. HILFE!
Danke im Voraus!
Sry für die zwei Fehler im Programm, das eigentliche Programm ist größer
und ich habe es nur auf das Nötigste um den Fehler zu finden reduziert.
Im Anhang nochmal die Datei als ASM.
Hi
Ohne das nochmal angesehen zu haben, stellt sich die Frage, warum du den
Zirkus mit dem Z-Pointer veranstaltest. Lege einfach Speicherplätze mit
passenden Labels für deine Variablen im RAM an. Auf die kannst du mit
'sts/lds' einfach darauf zugreifen.
MfG Spess
da der Code nicht so lange ist hänge ichs mal direkt an, war ein sehr
frühes Projekt von mir und ich habe da mit Variablennamen gearbeitet.
Wenn du aber mit Pointern arbeitest kannst du es ja auch ab
Speicherstelle X direkt reinschreiben.
.DSEG ;Reserve jeweils 1 Byte / Variabl eim SRAM
Voll1: .byte 1
Voll2: .byte 1
Voll3: .byte 1
Voll4: .byte 1
Halb1: .byte 1
Halb2: .byte 1
Halb3: .byte 1
Halb4: .byte 1
Halb5: .byte 1
Halb6: .byte 1
Halb7: .byte 1
Halb8: .byte 1
.CSEG
.ORG 0x00
rjmp init
init: ;Stackpointer initialisieren
ldi temp, RAMEND
out SP, temp
ldi temp, 0b10100000 ;Speichere Schrittfolge im SRAM um Register zu
sparen
sts Voll1, temp
ldi temp, 0b10010000
sts Voll2, temp
ldi temp, 0b01010000
sts Voll3, temp
ldi temp, 0b01100000
sts Voll4, temp
ldi temp, 0b10100000
sts Halb1, temp
ldi temp, 0b10000000
sts Halb2, temp
ldi temp, 0b10010000
sts Halb3, temp
ldi temp, 0b00010000
sts Halb4, temp
ldi temp, 0b01010000
sts Halb5, temp
ldi temp, 0b01000000
sts Halb6, temp
ldi temp, 0b01100000
sts Halb7, temp
ldi temp, 0b00100000
sts Halb8, temp
oder halt
.dseg
Tabelle: .byte 12 und mittels Pointer auf die 12 letzten Bytes im SRAM
wandern also immer + - für einen Schritt oder eben keinen neuen Schritt
übertragen
Sry ich glaube ich habe mich missverständlich ausgedrückt oder etwas
nicht verstanden. Ich möchte später mit dem Roboter eine Strecke fahren,
und dan wieder abrufen können. das bedeutet z.B. 1567 Schritt geradeaus,
67 Schritt links, 405 nach hinten uns, nur ganz grob dergestellt. Die
richtung und die schrittanzahl soll jeweils gespeichert werden. der code
im anhang ist nur ein test mit einem moter.
das heist dein Roboter hat 2 Räder mit Schrittmotoren wodurch man auch
wie beim Panzer lenken kann.
Dann benötigst du 2 weitere Tabellen also für jedes Rad eine, wenn da
jetzt drinsteht beide Räder 255 Schritte drehen um nach vorne zu fahren,
musst du deinen Pointer z.B. 255 nach rechts über meine Tabelle wandern
lassen und immer den ausgelesenen Wert an die Schrittmotortreiber
ausgeben. Wenn du andersherum fahren willst musst du links über meine
Tabelle wandern.
Hi
>Sry ich glaube ich habe mich missverständlich ausgedrückt oder etwas>nicht verstanden.
Die Bitmuster würde ich auch nicht im RAM speichern. Aber -Z/Z+ sind
nicht unbedingt das geeignete Mittel um auf bestimmter RAM-Zellen
zuzugreifen. Das ist sehr unübersichtlich.
Besser du benutzt die Adressierung über Index:
1
; Offsets
2
3
.equ steps_low = 0
4
.equ steps_high = 1
5
.equ direction = 2
6
7
.dseg
8
9
Motor1: .Byte 3
10
Motor2: .Byte 3
11
12
.cseg
13
14
; Schritte für Motor1 speichern
15
16
ldi ZL,Low(Motor1)
17
ldi ZH,High(Motor1)
18
19
std Z+steps_low,r16
20
std Z+Steps_high,r17
21
22
; Schritte für Motor2 speichern
23
24
ldi ZL,Low(Motor2)
25
ldi ZH,High(Motor2)
26
27
std Z+steps_low,r16
28
std Z+Steps_high,r17
29
30
; Schritte für Motor1 laden
31
32
ldi ZL,Low(Motor1)
33
ldi ZH,High(Motor1)
34
35
ldd r16,Z+steps_low
36
ldd r17,Z+Steps_high
37
38
; und so weiter
Die Bitmuster für die Schritte würde ich im Flash ablegen:
Ja, das mit dem Flash werde ich wohl übernehmen. Jedoch weiß ich nicht,
wie das mit den 3 Bytes für jeden Motor funktionieren soll, da eine
Strecke aus mehreren Abschnitten besteht, in denen der Roboter
verschiedene Richtungen fährt. Es werden für eine Stecke mit 40
Richtungswechseln also 40x 3 Bytes für jeden Motor benötigt, einmal die
Richtung und die dazu gehörige Anzahl an Schritten. Das wären dann mal
eben 240 Bytes, die reserviert sein müssten, um eine einfache Stecke zu
speichern.
Hi
Dann muss ich mal dumm fragen, wie du die Strecke in den Roboter
bekommst und wo du die speichern willst?
Das Ganze lässt sich übrigens auch auf eine Streckenliste im RAM
anwenden. Du musst nur aus der Länge der Parameter und der Nummer des
Streckensegments die Adresse für Z ausrechnen.
MfG Spess
Wie die Stecke in den Roboter kommt ist erstmal belanglos. Gedacht war
es, dass der Roboter ferngesteuert wird und beim manuellen Betrieb die
Strecke abspeichert und dann zurück fahren kann. Das kann aber auch
erstmal über die serielle Schnittstelle simuliert werden.
Ich denke dein Hauptfehler besteht darin, dass du relativ planlos an die
Sache herangehst und aufs geratewohl losprogrammierst. Das geht mit
etwas Übung in C, in Assmbler ist sowas aber tödlich.
Fang damit an, dir deine Datenstruktur im Speicher zu formulieren. Und
als nächstes beschreibst du deinen Programmaufbau in Prosa, ohne dich
zunächst um die konkrete Implementierung zu kümmern.
1
-- Voraussetzung: Z-Pointer zeigt auf den Anfang einer 3 Byte
2
-- Sequenz
3
-- die ersten beiden Bytes beschreiben die Anzahl der Schritte
4
-- das dritte Byte gibt die Richtung, in die gefahren werden soll
5
-- ist die Anzahl der Schritte gleich 0, dann bedeutet das:
6
-- Ende der Tabelle
7
8
9
10
-- Z-Pointer vorbereiten, in dem er an den Anfang der
11
-- Beschreibung aller Teilstrecken gesetzt wird.
12
13
-- Punkt B: den Schrittzähler laden (über den Z-Pointer)
14
15
-- Anzahl Schritte 0 ?
16
-- Ja --> Ende der Strecke, gehe zu Punkt C
17
18
-- Punkt A: mache diese Anzahl von Schritten
19
-- Dazu UP "1-Schritt aufrufen", welches 1 Schritt durchführt
20
21
-- Schrittanzahl um 1 verringern
22
23
-- Anzahl gleich 0 geworden?
24
-- Nein: gehe zu Punkt A
25
26
27
-- offenbar ist dieses Teilstück abgearbeitet, nächstes Teilstück
28
-- vorbereiten, indem der Z-Pointer auf den Anfang dieses Teil-
29
-- stückes gesetzt wird. Da der Z-Pointer immer auf den Anfang
30
-- zeigt, und ein Teilstück durch 3 Bytes beschrieben wird,
31
-- reicht es daher den Z-Pointer um 3 zu erhöhen
32
33
34
-- der Z-Pointer steht jetzt richtig
35
-- Teilstück abarbeiten lassen, dazu
36
-- gehe zu Punkt B
37
38
39
-- Punkt C:
40
-- alle Teilstrecken abgearbeitet, fertig
Das ist jetzt nicht die einzgie Möglichkeit, wie man das organisieren
kann. Ja nachdem kann man das auch ganz anders machen, wenn zb
Interrupts ins Spiel kommen. Richtungswechsel sind auch nicht
eingearbeitet (ist ja schliesslich dein Projekt).
Der springende Punkt ist aber: Bereite dir erst mal in derartigen groben
Plänen, die durchaus als Kommentare in deinen Code kommen können, kommen
sollen, deine Arbeit vor! Du kannst zb ruhig erst mal den geplanten
Ablauf in Form von Kommentaren in dein Programm schreiben. Diesen Ablauf
gehst du dann auf logischer Ebene ein paar mal durch und siehst zu, dass
du Fehler in der Logik findest.
Und erst dann, wenn deine Logik soweit steht, fängst du an, in den
Zwischenräumen zwischen den Kommentaren, den jeweiligen Code einzufügen,
der die Aktion des vorhergehenden Kommentares implementiert.
Abgesehen von kleinen Assemblerprogrammen, musst du eine derartige
Vorgehensweise benutzen, wenn du dich nicht in selber in der Komplexität
deines Programmes verlieren willst. Erst muss der Plan stehen, dann kann
man ihn implementieren. Und nein. Gerade als Neuling reicht es nicht,
wenn man so ungefähr eine vage Vorstellung davon hat, wie das ganze
funktionieren soll. SChreib dir die Dinge auf, geh sie durch, wieder und
immer wieder. Bis du keinen logischen Fehler mehr entdecken kannst. Da
sind dann immer noch Fehler drinnen, aber zumindest das logische Konzept
ist dann zumindest soweit gediehen, dass die noch verbleibenden Fehler
korrigierbar sind und keine allzugroße Auswirkungen auf das
Gesamtkonzept mehr haben, wenn man sie in der Simulation erst mal
gesehen hat.
Und noch was. Wenn dein SChrittzähler als 16-Bit Zähler ausgeführt ist,
dann arbeite auch mit 16 Bit!