mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer nutzen beim ATmega16 für Stepper


Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

Ich hoffe, Ihr könnt mir weiterhelfen. Ich brauche einen sinnvollen 
Ansatz für mein Projekt:

Ich will den ATmega16 nutzen, um einen Stepper-Motor in ziemlich 
einfacher Betriebsart zu betreiben.

Ich brauche eigentlich "nur" eine Timer-Funktion, die folgende Features 
aufweist/zulässt:

- Ich drücke eine Taste, somit wird an einen Ausgang 6400 mal ein 
Rechtecksignal (ton/toff=1) ausgegeben und diese Schleife dann sofort 
beendet.
- Bei Betätigung einer anderen Taste wird der Puls am selben ausgang z. 
b. nur 1000 mal ausgegeben usw.

Ich habe nun das Datenblatt, das Tutorial usw. durchgearbeitet, 
anscheinend bin ich aber zu blöd.

Vielen Dank im Voraus.

Gruß

Tom

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schaffe Dir eine 16-Bit Zählvariable, die Du mit einem Wert Deiner Wahl 
lädst und in jedem Timerinterrupt um 1 verminderst, während Du den 
betreffenden Portpin umschaltest. Ist die Zählvariable bei 0 angekommen, 
stoppst Du die Zählerei.

Autor: Alexander Liebhold (lippi2000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na das klingt doch erst einmal recht einfach.
Ich nehme an du meinst einen Schrittmotor. Da solltest du dir als erstes 
einen Treiber bauen, der den entsprechenden Strom zur Verfügung stellt.
Anschließend brauchst du 4 Signalleitungen, die für die spezielle 
Ansteuerung der Phasen benötigt werden. Soweit die Hardware.

Software:

Du kannst mit deinem Taster einen beliebigen Port nehmen und diesen mit 
einer Endlosschleife abfragen lassen. Sinnvoller wäre den ext.Int. zu 
verwenden. In den Speicher musst du nun die benötigten Ansteuerwerte für 
Halb-,Viertel-Schritt,... hintereinander ablegen, die dann entsprechen 
oft durchlaufen und Ausgegeben werden.

Gruß Alexander

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Travel Rec.

erstmals vielen Dank für Deine schnelle Antwort. Anbei siehst Du einen 
kleinen Code.

Kannst Du mir hierzu kurz Hilfestellung bieten, wie ich diesen abändern 
muss, um meinem Ziel näher zu kommen?

Danke und Gruß

Tom




#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>

#define TAKT 8000000UL
#define TEILER 65535UL-(TAKT/4096UL)


typedef unsigned int uint16;
typedef signed int sint16;
typedef unsigned short uint8;
typedef signed short sint8;

uint16 step=0;

SIGNAL(SIG_OVERFLOW1)
{
  TCNT1 = TEILER;
  step++;
  PORTB = step;
}

int main (void)
{
  DDRB = 0x01;
  PORTB = step;
  TCNT1 = TEILER;
  TCCR1B = 0x05;
  TIMSK |= (1<<TOIE1);
  sei();
  while(1) {}
}

Autor: Alexander Liebhold (lippi2000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie schnell sollen die 6400 Schritte durchlaufen werden?
Bei nem Schrittmotor muss die Frequenz langsam (mit einer Rampe) 
hochgefahren werden.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Alexander,

Danke auch Dir für Deine Antwort.

Hardwareprobleme habe ich zum Glück keinerlei.

Ich benötige nur einen Code, der mir weiterhilft, bzw. auf den ich 
aufbauen kann. Ich brauche nur einen kurzen Anstoß, damit ich die 
Timer-Sache kapiere, dann kanns vermutlich losgehen.

Betreffend der Taster:
Ich will keine ext. Interrupts verwenden, sondern nur die Ports pollen.

Danke

Tom

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochmals an Alexander:

Die Geschwindigkeit ist sehr sehr langsam (eine Umdrehung > 5sec.). Das 
Haltemoment reicht völlig aus, somit ist auch keine Rampe nötig.

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, C ist nicht meins, bin ASM-Freak ;-)

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Travelrec,

trotzdem vielen Dank.

Ich bin mir sicher, dass in diesem Forum einige C-Cracks unterwegs sind.

Gruß

Tom

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tom wrote:
> #include <avr/signal.h>
signal.h ist veraltet. Wenn noch nicht geschehen, installier am besten 
erstmal ne aktuelle Version von WINAVR/AVR-GCC+AVR-libc.

> typedef unsigned int uint16;
> typedef signed int sint16;
> typedef unsigned short uint8;
> typedef signed short sint8;
Und sowas sollte man auch nicht machen. Dafür gibts typedefs in der 
stdint.h. Die heißen dann uint16_t, uint8_t, int16_t und int8_t. Und das 
ist dann auch portierbar...

> SIGNAL(SIG_OVERFLOW1)
Zum Thema "SIGNAL" siehe oben.

> {
>   TCNT1 = TEILER;
>   step++;
>   PORTB = step;
> }
>
> int main (void)
> {
>   DDRB = 0x01;
>   PORTB = step;
>   TCNT1 = TEILER;
>   TCCR1B = 0x05;
>   TIMSK |= (1<<TOIE1);
>   sei();
>   while(1) {}
> }
Timer-Zählregister vorladen ist Murks. Sowas macht man beim AVR mit 
einer Compare-Einheit z.B. im CTC-Modus. Schau Dir Datenblatt und 
AVR-GCC-Tutorial daraufhin mal an.

Autor: Alexander Liebhold (lippi2000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK. Bin auch bei ASM zu Haus. Aber logisch kann man ja mal rangehen.


Für den Timer-Int. benötigst du folgende Angaben:

TCCR1B --> Register für Taktvorteiler
TCNT1  --> Zählwert des Counters bis zum Überlauf
TIMSK  --> Interrupt Maske (Overflow_Int freigeben)

Also diese Register müssen zuerst beschrieben werden.

Die Interrupt-Routine existiert ja schon.

Du schaltest zu beginn den Overflow-Int. inaktiv und pollst deinen PORT.
Wird ein Wert  (also Tastendruck) am PORT registriert, beschreibst du 
ein Register mit dem Zählwert(Anzahl von Ausgangsimpulsen) und löscht 
den aktuellen Schritt ("step") . Dann wird die der Overflow_Int. 
aktiviert.
Die Schleife dafür ist vorhanden. Du vergleichst nun im Hauptprogramm 
ständig Ist und Soll, bis beide gleich sind. Anschließend wird der 
Overflow_Int deaktiviert und an den programmstart gesprungen.

Vielleicht hilf der grobe Ablauf ja weiter.

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

Bewertung
0 lesenswert
nicht lesenswert
Ich würde die Sache trotzdem immer noch umdrehen, wie es weiter oben
schon mal angesprochen wurde.

Anstatt den Zähler hochzählen zu lassen, würde ich ihn von
einem Startwert bis auf 0 herunterzählen lassen. Auf lange Sicht
gesehen funktioniert das meist besser unter anderem auch deshalb,
weil dann Änderungen im Zielwert leichter (mit weniger Code)
durchführbar sind, wenn im Zähler immer die Anzahl der noch
ausständigen Schritte enthalten ist. Auch ist das Beenden
der ganzen Zählerei (Notstop) einfacher möglich: Einfach den
Zähler auf 0 setzen und gut ists (Alles klar: Ein Notaus
sollte immer mit Hardware realisiert werden, es schadet aber
nichts, wenn die Software dafür auch eine einfache Möglichkeit
hat).
uint16_t StepsLeft;

ISR( .... )
{
  if( StepsLeft > 0 ) {
    ... Hardwareschritt ausführen
    StepsLeft--;
  }
}

int main()
{
  ....

  while( 1 ) {
    if( PINxx & ( 1 << irgendwas ) ) {  // das Polling der Taste
      cli();
      StepsLeft = 10000;
      sei();
    }

    if( PINxx & ( 1 << irgendwasanderes ) ) { // Polling der 2.ten Taste
      cli();
      StepsLeft = 3000;
      sei();
    }

    if( PINxx & ( 1 << nochwasanderes ) ) {   // sofort abschalten
      cli();
      StepsLeft = 0;
      sei();
    }
  }
}

Zum Thema Tasten-polling:
Keine gute Idee. Taster sind notorische Preller. Die Entprellroutine
von PeDa (Artikelsuche benutzen) ist die Ideallösung für die
Auswertung von Tasten. Was anderes braucht man nicht um eine 100%
funktionierende, zufriedenstellende, problemlose Lösung zu bekommen.

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.