mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Eine bestimmte Anzahl von Impulsen erzeugen


Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Hintergrund ist der Folgende. Ich baue eine Schrittmotorsteuerung mit 
der L297/L298 Kombination. Es wird ein Schritt ausgeführt, wenn der L297 
eine steigende Flanke am Takteingang bekommt.
Die Steuerung soll dann von einem anderen Board via I2C angesteuert 
werden.
Folgendes habe ich mir als Konzept überlegt. Zunächst einmal benötige 
ich eine Art Befehlswarteschlange. Denn wenn nacheinander mehrere 
Anweisung kommen, x-Schritte auszuführen, sollen alle der Reihe nach 
abgearbeitet werden. Wie kann man so etwas geschickt in C realisieren? 
Hier fehlt ja leider die Objektorientierung der Sprache.
Dann zur eigentlichen Impulserzeugung. Ich habe mal schnell diesen Code 
geschrieben, und er scheint auch zu funktionieren. Hier ein relevanter 
Ausschnitt.
LCLK ist der Pin OC2A. Und alle in der ISR verwendetn Varriablen sind 
als volatile definiert.

Hier wird der Befehl angenommen x-Schritte zu machen:
lcounter=2*steps;
lready=false;
LPORT &= ~(1<<LCLK);
TCNT2=0;
TCCR2A |= (1<<COM2A0);

und hier die ISR:
ISR(TIMER2_COMPA_vect) {
  if(lready==false){
    if(lcounter==1) {
      lready=true;
      TCCR2A &= ~(1<<COM2A0);
    } else {
      --lcounter;
    }
  }
}


Der Timer läuft die ganze Zeit im Hintergrund durch, und erzeugt somit 
den Takt. Eventuell setze ich nach erhalten des Befehls ein wenig viel 
zurück. Da bin ich mir nicht genau sicher, ob das nötig ist.
Ansonsten wäre es noch möglich, erst nach erhalten des Befehls den 
Compare Interrupt zu aktivieren, und wenn die Erzeugung der Impulse 
beendet ist, diesen wieder zu deaktivieren?

Viele Grüße

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

Bewertung
0 lesenswert
nicht lesenswert
Florentin S. schrieb:

> Folgendes habe ich mir als Konzept überlegt. Zunächst einmal benötige
> ich eine Art Befehlswarteschlange. Denn wenn nacheinander mehrere
> Anweisung kommen, x-Schritte auszuführen, sollen alle der Reihe nach
> abgearbeitet werden. Wie kann man so etwas geschickt in C realisieren?
> Hier fehlt ja leider die Objektorientierung der Sprache.

Für eine Schleife und einen Zähler fehlt dir die Objektorientierung?
Mach die Dinge nicht komplizierter als notwendig!

Du machst dir eine Struktur, mit der du 1 Befehl beschreiben kannst. In 
deiner Warteschlange hast du derartige Befehls-'Objekte' der Reihe nach 
gesammelt und wenn das Kommando kommt "5 Befehle abarbeiten", nimmst du 
1 Befehls-"Objekt" nach dem nächsten aus der Warteschlange (solange bis 
die 5 erreicht sind oder keine Befehls-Objekte mehr in der Warteschlange 
sind) und übergibst es einer Funktion, die sich die Objektinternals 
ansieht und den Befehl ausführt.

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut. Also das mit der Struktur klingt schon mal nicht schlecht. Ich 
müsste mir nur noch überlegen, wie ich die "codiere". Da ich noch andere 
Befehle habe wie z.B. Drehrichtung festlegen etc. Nur möchte ich nicht 
z.B. 5 Befehle abarbeiten, sondern es soll einfach ein Befehl nach dem 
anderen abgearbeitet werden. Und welche die neu reinkommen, sollen 
gepuffert werden.
Dafür müsste sich doch eigentlich ein Ringpuffer eignen. Da hatte ich 
mal was schönes für den UART.
Ist die eigentliche Impulserzeugung eigentlich ok so, oder könnte man da 
noch etwas verbessern?

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

Bewertung
0 lesenswert
nicht lesenswert
Florentin S. schrieb:
> Gut. Also das mit der Struktur klingt schon mal nicht schlecht. Ich
> müsste mir nur noch überlegen, wie ich die "codiere". Da ich noch andere
> Befehle habe wie z.B. Drehrichtung festlegen etc. Nur möchte ich nicht
> z.B. 5 Befehle abarbeiten, sondern es soll einfach ein Befehl nach dem
> anderen abgearbeitet werden. Und welche die neu reinkommen, sollen
> gepuffert werden.

OK, dann mach das doch so.

> Dafür müsste sich doch eigentlich ein Ringpuffer eignen.

Recht viel was anderes wirst du auch nicht kriegen :-)

> Ist die eigentliche Impulserzeugung eigentlich ok so, oder könnte man da
> noch etwas verbessern?

Wozu lready?

Lass doch den Counter einfach bis auf 0 runterzählen. Bei 0 stoppt er 
und die 0 sagen dem Rest des Codes, dass die entsprechende Anzahl Pulse 
abgearbeitet wurden. Zudem brauchst du dann auch den Timer nicht dauern 
stoppen und neu starten
ISR(TIMER2_COMPA_vect)
{
  if( lcounter > 0 ) {
    if (lcoutner % 2 == 0)
      LPORT &= ~(1<<LCLK);   // Pin auf 0
    else
      LPORT |=  (1<<LCLK);   // Pin auf 1

    lcoutner--;
  }
}

Willst du x Pulse generieren lassen.
  lcounter = 2 * x;

Willst du wissen ob die Anzahl der Pulse schon erzeugt wurden
  if( lcounter > 0 )
    // Pulserzeugung ist noch im Gange

Autor: Flo S. (tuxianer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok das sieht natürlich übersichtlicher aus. Nur bei dir müsste der Takt
nach der letzten Flanke auf High bleiben. Das dürfte dem L297 eigentlich
egal sein, ich habe aber trotzdem mal die Pegel vertauscht.
Ansonsten werde ich mich als nächstes an die Implementierung des Puffers
machen.

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.