mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik bitoperation im halbschlaf


Autor: leif (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

die letzte Frage für heute, ich seh's nicht.

wie löse ich das:

port     0b10101010

maske    0b01011100
werte   0b01010000
        ------------
port neu 0b11010010

also port mit maske auf wert setzen.

Ist das überhaupt effizient, um einen Schrittmotor anzutreiben?

Ich hatte mir das nämlich so gedacht:
// bit mask for stepper motor outputs (current setup: 0b01011100)
step_mask = 1<<MCa1 | 1<<MCa2 | 1<<MCb1 | 1<<MCb2;
// contains active coils
step[0] =  1<<MCa1 | 1<<MCb2;
step[1] =  1<<MCa1 | 1<<MCb1;
step[2] =  1<<MCa2 | 1<<MCb1;
step[3] =  1<<MCa2 | 1<<MCb2;

Ich vermute, daß ich leider noch eine Hilfsvariable benötige. So etwa
HilfeV=port
HilfeV mit maske löschen
HilfeV mit step[] setzen
port=hilfe

und hoffe, jemand ist pfiffiger als ich und sagt es mir :-)
danke schonmal!

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm...

Also professionelle Schrittmotorsteuerung macht man mit
Spezialschaltkreisen. Da werden die Spulen im Chopperbetrieb bestromt.
Gute, aber nicht ganz billige Lösungen gibt es z.B. von Trinamic.

Einfache Schrittmotorsteuerungen mache ich mit einer Tabelle mit
Bitmuster (Auszug aus Programm):

;Schrittmotor an PortD, Pins PD7, PD6, PD5, PD4
.equ smp=portd             ;Schrittmotor-Port (PORTx)
.equ smm=0b11110000        ;Schrittmotor-Bitmaske

stellmot:
 ldi zl,low(bimu*2)        ;Zeiger auf
 ldi zh,high(bimu*2)       ;Motor-Bitmuster
 mov wl,posi               ;Kopie von Position zwecks
 andi wl,7                 ;Ausblendung der oberen Bits
 add zl,wl                 ;Offset dazu,
 adc zh,null               ;Übertrag auch
 lpm wl,z                  ;Bitmuster holen
 andi wl,smm               ;eventuell ungültige Bits ausblenden
 in wh,smp                 ;Schrittmotor-Port einlesen
 andi wh,255-smm           ;Schrittmotor-Bits löschen
 or wh,wl                  ;neue Schrittmotor-Bits dazu
 out smp,wh                ;und an Port ausgeben
 rjmp fertig               ;fertig...

bimu:                      ;Bitmuster für Schrittmotor
.db 0b10000000,0b11000000  ;
.db 0b01000000,0b01100000  ;
.db 0b00100000,0b00110000  ;
.db 0b00010000,0b10010000  ;

Das Ganze läuft dann in einem Timer-Interrupt.

...

Autor: leif (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bringt das irgendwelche Vorteile:

Port=(Port& ~maske) | step[];

oder so:

port ^= step[i] | step[i+1] ;

(aber das geht nur gut, wenn der Motor bereits läuft)

Mhh.

Autor: leif (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh, da war ja doch noch einer..danke schonmal, aber asm verstehe ich
jetzt mit sicherheit nicht mehr. aber morgen ist ja auch noch ein tag!

;-)
Obwohl, Du machst es ja auch so:

Schrittmotor-Port einlesen
Schrittmotor-Bits löschen
neue Schrittmotor-Bits dazu
und an Port ausgeben

und was passiert, wenn zwischen einlesen und ausgeben sich etwas an
einem eingang desselben ports ändert? chaos & mayhem? oder ist es eher
unwahrscheinlich, daß sich in 1/1000000 sekunde was ändert ?

Autor: Hannes Lux (hannes)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Da kann sich in meinem Fall nix ändern, da das gesamte Programm aus
einer einzigen ISR (Timer-Int) besteht und in der Mainloop nur gepennt
wird. - Gepennt noch nicht, da das Programm noch nicht endgültig fertig
ist. Die Mainloop ist also (noch) eine leere Endlosschleife.

Ich häng das Programm mal an. Es entspricht zwar nicht den von Bolle
genannten Kriterien, aber vielleicht hlft es dir trotzdem.

...

Autor: leif (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen Hannes,

danke dafür. Werde ich mir aber aus Vernunftgründen erst bei Tageslicht
ansehen..

Ich habe jetzt meinen Einzeiler mal verwendet, in einer an Bolles
angelehnten Programmstruktur. Also TimerInt setzt Flag.Bit, Main()
klappert die Schrittmotorfunktion ab, wo je nach Flag.Bit dann der Port
umgeschaltet wird.

Aus dem, was Du in 4 (?) Befehlen schaffst, macht der Compiler das
Folgende:
PORTD=(PORTD& ~step_mask) | step[currentstep];
  84:  80 91 64 00   lds  r24, 0x0064
  88:  80 95         com  r24
  8a:  92 b3         in  r25, 0x12  ; 18
  8c:  98 23         and  r25, r24
  8e:  20 91 66 00   lds  r18, 0x0066
  92:  e2 2f         mov  r30, r18
  94:  ff 27         eor  r31, r31
  96:  e0 5a         subi  r30, 0xA0  ; 160
  98:  ff 4f         sbci  r31, 0xFF  ; 255
  9a:  80 81         ld  r24, Z
  9c:  98 2b         or  r25, r24
  9e:  92 bb         out  0x12, r25  ; 18

Man kommt um Assembler also nicht drumherum.
Versuch ich jetzt aber nicht mehr zu verstehen..

Erfreulicherweise läuft der Motor sogar, wenn auch nicht so rund wie
bei meiner ersten Softwarelösung mit delay()s. Auch dafür gibt es einen
Grund, aber auch der geht jetzt erstmal schlafen..

Gute Nacht!

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hochsprachen bringen eigentlich erst etwas, wenn man ASM begriffen hat.
Wer Hochsprachen nutzt um sich vor dem Erlernen von ASM zu drücken, der
hat schlechte Karten...

...

Autor: leif (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was ich über die 4 befehle gesagt habe ist ja quatsch, das bitmuster
berechnest du ja vorher auch noch.

so jetz aber.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die berechne ich nicht, die stehen im Flash in einer Tabelle...

Gute N8...

...

Autor: Mark Struberg (struberg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
humm, ein kleines Gedankenexperiment

Was ist, wenn man das Bitmuster des oberen Nibble einfach im unteren
Nibble wiederholt? Dann kann man die einfach nach rechts durchrotieren,
oder hab ich da was nicht bedacht?

Also aus
0b10000000,0b11000000
machen wir
0b10001000 und 0b11001100

durch das Rotieren (ohne Carry!) kommt automatisch das untere,
gleichlautende Nibble wieder in das oberste rein und man erspart sich
eventuell die Tabelle, wie auch das Laden der Tabelle.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richtig...

Aber wie wird das, wenn z.B. aus Gründen des Layouts die
Spulenanschlüsse nicht in der richtigen Reihenfolge sind oder garnicht
innerhalb eines Nibbles?

Bitschieben ist auf jeden Fall schneller. Aber Tabelle ist flexibler,
lässt sich jederzeit anpassen.

...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.