mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Bitmanipulation zu langsam?


Autor: Crazy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
und zwar möcht ich mit einem ATM32 (10Mhz) einen Schrittmotor (unipolar) 
mit Bitmanipulation steuern. Am Anfang habe ich den Port "direkt" 
gesetzt durch Portx = 00000001,00000010,00000100,00001000 benutzt und 
diese nun durch diese Bitkombinationen ersetzt:

Auszug:
[            if (zaehler == 0) {
                SchrittmotorPort |= (1<< 0);
                SchrittmotorPort &= ~(1<< 1) | (1<< 2) | (1<< 3);
            };
            if (zaehler == 1) {
                SchrittmotorPort |= (1<< 1);
                SchrittmotorPort &= ~(1<< 0) | (1<< 2) | (1<< 3);
            };
            if (zaehler == 2) {
                SchrittmotorPort |= (1<< 2);
                SchrittmotorPort &= ~(1<< 0) | (1<< 1) | (1<< 3);
            };
            if (zaehler == 3) {
                SchrittmotorPort |= (1<< 3);
                SchrittmotorPort &= ~(1<< 0) | (1<< 1) | (1<< 2);
            };
]

nun bewegt sich aber gar nix mehr, der Schrittmotor wackelt nur noch auf 
der Stelle. Ist meine Bitkombination falsch oder ist der ATM zu langsam? 
Kann ich die Bitkombi noch anderst schreiben, dass sie schneller wird?

Noch eine minderwichtige Frage:
mit wechem Bitmuster könnte ich den Schrittmotor noch ansteuern. Mit 
1001,1010,0110,0101 ? Weil ich bekomme den so, einfach nicht zum laufen.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zählst Du denn "zaehler" auch hoch?

Und ich würde mal eine Klammer mehr setzen:

~((1<< 1) | (1<< 2) | (1<< 3));

Natürlich in allen 4 Zeilen.

Autor: Crazy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke! das mit der Klammer hat funktioniert. Kann man auch gleichzeitig 
mit einem Befehl setzen und löschen

Autor: Robert S. (razer) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Crazy wrote:
> Danke! das mit der Klammer hat funktioniert. Kann man auch gleichzeitig
> mit einem Befehl setzen und löschen

Jo, is zwar nicht ganz schön:

port |= ((1 << bit0) | (0 << bit1));

Gruß Robert

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
War das eine Frage? Falls ja:

SchrittmotorPort=(SchrittmotorPort&0xF0)|(1<<zaehler);

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Robert
Wie? Eine 0 shiften gibt immer 0..und zwar in allen Bits

Autor: M. V. (-_-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
1. Wie/Wann zählst du den 'zaehler' hoch?
2. Um was für einen Schrittmotor handelt es sich?
3. Wie ist selbiger angeschlossen?

Ohne diese Informationen wird dir hier keiner wirklich weiterhelfen 
können.

>mit wechem Bitmuster könnte ich den Schrittmotor noch ansteuern.

Wie's scheint, fehlen dir die absoluten Grundlagen.
Einfach mal mit der Forensuche und Google n bisschen was suchen und 
durchlesen. Gibt schon haufenweise Threads zu dem Thema, hilfreiche 
Wikiartikel, auch auf roboternetz.de, nicht zu vergessen.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jemand
Und mal wieder einer dieser Sorte: "schon wieder...gähn"...

Es spielt keine Rolle, welchen Schrittmotor er verwendet, denn in seiner 
Frage steht schon drin, wie es anders bereits funktioniert hat.

Googeln und hier Grundlagenforschung betreiben muss er auch nicht.

Und geholfen werden kann ihm...entgegen Deiner netten Behauptung...und 
es ist auch bereits geholfen worden. Mehr als nur eine Zeile zu lesen 
soll doch manchmal nützen...gelle...

Warum bloß werden nette Fragesteller in diesem Forum immer so barsch 
angefahren und zu Deppen degradiert? Habt Ihr alle Komplexe und müsst 
Euch hier mal austoben? Kann man nicht mal einfach nur freundlich 
helfen?

Autor: M. V. (-_-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Es spielt keine Rolle, welchen Schrittmotor er verwendet, denn in seiner
>Frage steht schon drin, wie es anders bereits funktioniert hat.

Bitte wo soll das stehn? Er schreibt nur, dass der Schrittmotor 
lediglich wackelt, ansonsten nichts tut.

>Mehr als nur eine Zeile zu lesen
>soll doch manchmal nützen...gelle...

Ich habe durchaus den gesamten Thread gelesen.

>Warum bloß werden nette Fragesteller in diesem Forum immer so barsch
>angefahren und zu Deppen degradiert?

Wenn das nun so geklungen hat, möchte ich mich dafür entschuldigen.
Was aber definitiv der Fall ist, dass bei den meisten Fragen, einfach 
viel zu wenige Informationen gegeben werden, um die Frage sinnvoll 
beantworten zu können. Und wenn eben entsprechende Informationen fehlen, 
muss man Vermutungen anstellen, die dann natürlich auch absolut falsch 
gewesen sein können.

>Und geholfen werden kann ihm...entgegen Deiner netten Behauptung..

Wie willst du denn bitte

>mit wechem Bitmuster könnte ich den Schrittmotor noch ansteuern. Mit
>1001,1010,0110,0101 ? Weil ich bekomme den so, einfach nicht zum laufen.

ohne die von mir geforderten Informationen sinnvoll beantworten? 
Richtig, gar nicht.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jemand
Lesen scheint echt Dein Problem...

Es wurde Ihm bereits geholfen. Man lese mal den dritten Beitrag!

Und mit "Am Anfang habe ich den Port direkt gesetzt durch Portx = 
00000001,00000010,00000100,00001000 benutzt und diese nun durch diese 
Bitkombinationen.."
Mit etwas Nachdenken kann man verstehen, dass er damit sagen wollte, 
dass es so schon funktioniert hat, aber jetzt mit seiner neuen 
Software-Version eben nicht mehr tut.

Autor: M. V. (-_-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Mit etwas Nachdenken kann man verstehen, dass er damit sagen wollte,
>dass es so schon funktioniert hat, aber jetzt mit seiner neuen
>Software-Version eben nicht mehr tut.

Das ist lediglich eine Vermutung. Nicht mehr.

Was mich stört ist lediglich, dass, wie schon gesagt, zu wenige 
Informationen gegeben wurden. Wenn man genau schreibt, was wie wo wann 
(nicht) funktioniert, dann ist die Frage entsprechend schnell 
beantwortet.
Wenn du dagegen unbedingt alle Fragen lediglich aufgrund von Vermutungen 
beantworten willst, ich hindere dich nicht daran, ich habe nur nach 
weiteren Informationen gefordert, wenn sein Problem mittlerweile gelöst 
ist, stört's mich auch nicht.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jemand
Ich frage mich, was sollen solche Beiträge, eine viertel Stunde nachdem 
das Problem bereits gelöst wurde?

>wenn sein Problem mittlerweile gelöst ist, stört's mich auch nicht.
Er wird Dir sicherlich sehr dankbar für Deine Großzügikkeit sein.

Autor: Crazy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also Vielen Dank erstmal an "alle" Antworten.

@ Frank
Da dieser Vorschlag ja nicht zu funktionieren scheint:
port |= ((1 << bit0) | (0 << bit1));
frage ich mich wie es mit diesem geht:
SchrittmotorPort=(SchrittmotorPort&0xF0)|(1<<zaehler);
oder wie das überhaupt funktioniert.
Kann man mit diesem Befehl gleichzeitig bestimmte bits setzen und 
löschen?

Nun nochmal zu meinen Bitmuster. Ich benutze einen unipolaren 
Schrittmotor mit 6 Kabeln dran! Wie bereits erwähnt funktioniert er 
super mit dem Bitmuster 0001,0010,0100,1000. Aber würde er nicht ein 
höheres Drehmoment erzeugen wenn ich ihn mit dem Bitmuster 
1001,1010,0110,0101 ansteuere, wie es der L297 benutzt und auch auf 
http://www.roboternetz.de/wissen/index.php/Schrittmotor nachzulesen ist? 
Aber bei mir will und will das nicht funktionieren, hab schon etliche 
male versucht die Kabel zu vertauschen. Gibt es nur eine möglichkeit sie 
so anzuordnen das es funktioniert? Er steht immer auf der Stelle und 
wackelt umher.

Autor: Crazy (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ganz vergessen hier is es mein Programm. Wenn jemand 
Verbesserungsvorschläge hat. Ich brauch halt des höchstmögliche 
Drehmoment. Darum frag ich wegen dem anderen Bitmuster.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also mit diser einzigen Zeile

SchrittmotorPort=(SchrittmotorPort&0xF0)|(1<<zaehler);

kannst Du Deinen Programmteil, den Du in Deiner Frage gepostet hast, 
komplett ersetzen.

Autor: Crazy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
achso dannn setzt der den Port gleich dem zaehler und die anderen 4 Bits 
sind nicht betroffen?

Autor: Crazy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hmm moment meins kann nich stimmen da der zaehler ja in Binär mit 1 2 4 
8 zaehlen müsste. wie funktioniert der Befehl denn dann?

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also:

SchrittmotorPort=(SchrittmotorPort&0xF0)|(1<<zaehler);

Er holt sich den SchrittmotorPort, löscht die unteren 4 Bits und dann 
setzt der das eine Bit, das mit zaehler bestimmt wird. Anschließend wird 
das Ergebnis wieder auf den Port geschrieben.

zaehler muss dabei den Wert 0,1,2 oder 3 haben, so wie es in Deinem 
Programmausschnitt vorgesehen ist.

Autor: M. V. (-_-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich frage mich, was sollen solche Beiträge, eine viertel Stunde nachdem
>das Problem bereits gelöst wurde?
Jaja, das Problem sieht sehr gelöst aus, wunderbar gemacht, Frank.

>Nun nochmal zu meinen Bitmuster. Ich benutze einen unipolaren
>Schrittmotor mit 6 Kabeln dran! Wie bereits erwähnt funktioniert er
>super mit dem Bitmuster 0001,0010,0100,1000.

Gut, demnach musst du die Kabelanschlüsse so lassen, wie sie dort sind.

>Aber würde er nicht ein
>höheres Drehmoment erzeugen wenn ich ihn mit dem Bitmuster
>1001,1010,0110,0101 ansteuere, wie es der L297 benutzt und auch auf
>http://www.roboternetz.de/wissen/index.php/Schrittmotor nachzulesen ist?

In dem Fall erhöhst du das Drehmoment dadurch, dass zwei Spulen parallel 
verwendet werden, und demnach ein doppelt so grosser Strom fliesst.
Allerdings hast du immernoch nur 4 Schritte.
Wenn du diese Methode mit der oberen kombinierst, also dann 8 Schritte 
hast, hast du ein nochmals grösseres Drehmoment.
Allerdings stimmt die Bitfolge wohl noch nicht. Es müssen immer die zwei 
Spulen, die 'nebeneinander' liegen bzw. aufeinander folgen angesteuert 
werden. D.h. wenn die obige Folge (0001,0010,0100,1000) funktioniert, 
müsste die Folge mit zwei Spulen 0011, 0110, 1100, 1001 lauten.

Die kombinierte Version wäre dann 0001, 0011, 0010, 0110, 0100, 1100, 
1000, 1001.
Nennt sich 'Halbschrittansteuerung'.

>Aber bei mir will und will das nicht funktionieren, hab schon etliche
>male versucht die Kabel zu vertauschen. Gibt es nur eine möglichkeit sie
>so anzuordnen das es funktioniert? Er steht immer auf der Stelle und
>wackelt umher.

Ja, es hat owhl nur die Bitfolge nicht zur Anschlussbelegung gepasst.
Wobei die Tatsache, dass die obige Folge funktioniert hat, nicht 
unbedingt heissen muss, dass die Anschlussbelegung schon so stimmt.
Im Prinzip muss es so sein, dass du wenn du an eine Spule Strom legst, 
sich die Achse eine Position weiterbewegt. Du könntest zum Überprüfen 
der Bitfolge als die Spulen 'von Hand' schalten. Dann sieht man ja grob, 
wie weit sich die Achse weiterbewegt.
Wenn die Bitfolge stimmt, hört man das dann auch (bei einer Ansteuerung 
durch den uC): Das Drehgeräusch ist dann recht regelmäszig.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jemand
Also wenn hier geschrieben wird, dass es jetzt funktioniert, dann ist 
das Problem gelöst! Natürlich kann man noch wochenlang dran rummrögeln, 
dazu haben wir ja Dich.

Und wenn er dann im Laufe der zeit weitere Fragen stellt, dann hat das 
mit der Lösung der ersten Frage rein garnix zu tun. Du kannst hier 
schreiben soviel Du willst, Du hast einfach nicht Recht. ists chwer 
zuzugeben, kann ich mir schon vorstellen.

Und seine Verständnisprobleme von "C" gehören auch nicht zur 
ursprünglich gestellten Frage.

Und wo bitte ist übrigens Deine Superlösung? Nur viel Text, der nicht 
wirklich hilft. Bravo!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da Crazy anscheinend mit den Bitoperationen in C auf
Kriegsfuss steht:

http://www.mikrocontroller.net/articles/Bitmanipulation

In Kürze:
Mit  ( 1 << n )  kann man eine Binärzahl erzeugen, welche
an der Bitposition n eine 1 stehen hat. << ist der Links-Schiebe
Operator. Er verschiebt ein angegebenes Bitmuster um n Stellen
nach links.

Aus einer binären 1, also 00000001, wird so durch linksschieben
um 4 Stellen  00010000, oder in C-Schreibweise ( 1 << 4 )

  01000111 << 3  liefert als Ergebnis   00111000


&  ist das binäre UND. Jeweils korrespondierende binäre Stellen
zweier Zahlen werden miteinander UND-verknüpft.

    a    b     a UND b
   --------------------
    0    0        0
    0    1        0
    1    0        0
    1    1        1

Wir stellen fest: Nur dann, wenn a und b 1 sind, taucht auch im Ergebnis
eine 1 auf. In allen andern Fällen ist das Ergebnis sicher 0.
Oder anders ausgedrückt: Ist b 0, dann ist auch das Ergebnis 0.
Ist b aber 1, dann ist das Ergebnis identisch zu a.
Das kann man ausnutzen: Hat man 2 Zahlen (in binärer Schreibweise)

        abcdefgh    ( a bis h seien binäre Ziffern)
    &   00010101
        --------
        000d0f0h

so überleben im Ergebnis nur diejengigen Bits, bei denen in der
zweiten Zahl (der Maske) eine 1 war. Alle anderen Bits sind im
Ergebnis auf jeden Fall 0 (weil in der Maske eine 0 war und laut
Wahrheitstabelle: wenn b 0 ist, dann ist auch das Ergebnis auf
jeden Fall 0, unabhängig von a)

| ist das binäre ODER


     a   b     a ODER B
   ---------------------
     0   0        0
     0   1        1
     1   0        1
     1   1        1


Mit einem ODER kann man gezielt ein Bit auf 1 setzen.

      abcdefgh
  |   01001100
      --------
      a1cd11gh

An den Stellen an denen in der Maske eine 1 war, ist im Ergebnis
auf jeden Fall eine 1. An den anderen Stellen hängt es von der
Bitposition der ersten Zahl ab, was im Ergebnis (0 oder 1) auftaucht.

~  ist die binäre Negierung


   a    ~a
  ---------
   0     1
   1     0


Alle Bits werden ganz einfach umgedreht. Aus 0 wird 1, aus 1 wird 0.

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.