Forum: Mikrocontroller und Digitale Elektronik Speichern von Schrittmotoren Schritten im SRAM - Assembler


von Jabu (Gast)


Angehängte Dateien:

Lesenswert?

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!

von spess53 (Gast)


Lesenswert?

Hi

Poste bitte ein assemblierbares Programm. Und nicht als *.txt sonder als 
*.asm.

MfG Spess

von Jabu (Gast)


Angehängte Dateien:

Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Thomas (kosmos)


Lesenswert?

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

von Jabu (Gast)


Lesenswert?

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.

von Thomas (kosmos)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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:
1
; Schrittnummer in r16        
2
; Richtung in r17       1        vorwärts
3
;                       -1 ($FF) rückwärts      
4
5
6
        ldi ZL,Low(steps<<1)
7
        ldi ZH,High(steps<<1)
8
9
        add r16,r17
10
        andi r16,0b00000011
11
        clr r17
12
        add ZL,r16
13
        adc ZH,r17
14
        lpm r16,Z     ; nächstes Bitmuster
15
                      ; in r16
16
17
18
steps:  .db   0b11000000,0b01100000,0b00110000,0b10010000

MfG Spess

von Jabu (Gast)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

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

von Jabu (Gast)


Lesenswert?

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.

von spess53 (Gast)


Lesenswert?

Hi

Eigentlich wollte ich dir nur zeigen, wie man von einer Basisadresse in 
Z verschiedene Werte in einem 'Datensatz' ausliest.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

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!

von Jabu (Gast)


Lesenswert?

Danke für deine Hilfe, ich werde das Programm nochmal neu strukturieren. 
Bei Bedarf melde ich mich nochmal.

Danke auch für alle anderen Beiträge!

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.