Forum: Mikrocontroller und Digitale Elektronik Programm für Schrittmotor


von Manu B. (manu_b)


Lesenswert?

Hallo zusammen,
habe folgendes Problem.
Ich möchte mit einem Schrittmotor ein Linearsystem betreiben.
Ich habe an oberster und unterster Position ein Microschalter.
Programm und Microschalter laufen auch weitest gehend.
Sobald ich in der if Anweisung um den Motor zu stoppen das Flag auf 0 
setzte wird dieses nicht angenommen. Wird das vom Compiler weg 
optimiert?
Ich verstehe es nicht, das kann doch kein Hexenwerk sein.

Hier den Code welchen ich geschrieben habe:

#define F_CPU 16000000//16Mhz
#include <asf.h>
#include <util/delay.h>

void Stepper_init()
{
  //TCNT0 = 0x0023;

  TCCR0A = 1<<WGM00 | 1<<WGM01 | 1<<COM0A1 | 1<<COM0A0 ;
  TCCR0B = 1<<CS01 | 1<<CS00 ; // Vorteiler clk von 64 = 976Hz
  OCR0A = 200; //=  Pulsweite

}


int main (void)
{

  Stepper_init();
  volatile char Arm_oben = 1, Arm_unten =0;
  volatile char Micro_oben, Micro_unten;

  DDRD  |= 0b01000000;
  DDRC  |= 0b00000011;

        TIMSK0 |= 1<<TOIE0;
  sei();


  while(1){

    Micro_oben = PIND &  0b00000001;
    Micro_unten = PIND & 0b00000010;



    while (Arm_oben == 1)
    {

      PORTC |= 0b00000001;
      if (Micro_unten == 0 )
      {
        PORTC &= 0b11111100;
        Arm_oben = 0;


      }

    }


  }
}


Der Motor bleibt auch wie gewünscht stehen. Nur sobald ich den 
Microschalter wieder los lasse, dreht er wieder los.
Sprich das Flag für Arm_oben wurde nicht auf 0 gesetzt bzw. irgendwo 
wieder auf 1.

Hoffe das war halbwegs verständlich und jemand kann mir bei meinem 
Problem weiter helfen

von Walter T. (nicolas)


Lesenswert?

Manu B. schrieb:
> Ich möchte mit einem Schrittmotor ein Linearsystem betreiben.

Ohne eine irgendwie geartete Beschleunigungsrampe wird das allerdings 
ein sehr langsames Verfahren. Aber das Problem kannst Du ja später 
angehen.

Manu B. schrieb:
> Sprich das Flag für Arm_oben wurde nicht auf 0 gesetzt bzw. irgendwo
> wieder auf 1.

Micro unten wird bei Deiner Implementierung in jedem Schleifendurchlauf 
neu gesetzt. Es merkt sich nichts.

von Michael B. (laberkopp)


Lesenswert?

Manu B. schrieb:
> Nur sobald ich den Microschalter wieder los lasse, dreht er wieder los.

Ach.

Er tut nur das, was du programmiert hast.

Da du den Timer weiter laufen lässt, wird er Mikrosekunden nach dem du 
das Port "abgeschaltet" hast wieder Impulse geben. Du musst den Timer 
schon abschalten.

von Manu B. (manu_b)


Lesenswert?

Erstmal danke für die raschen Antworten, genial.

Walter T. schrieb:
> Ohne eine irgendwie geartete Beschleunigungsrampe wird das allerdings
> ein sehr langsames Verfahren. Aber das Problem kannst Du ja später
> angehen.

Das ist alles im kleineren Sinne ;) funktioniert auch alles.

Walter T. schrieb:
> Micro unten wird bei Deiner Implementierung in jedem Schleifendurchlauf
> neu gesetzt. Es merkt sich nichts.

Das ist nur die Maskierung. welchen PIN er abfragen soll. Das 
funktioniert auch alles einwandfrei. Nur das er dann wieder in die 
while( Arm_oben ==1)
springt, sprich der Motor läuft weiter.

Michael B. schrieb:
> Da du den Timer weiter laufen lässt, wird er Mikrosekunden nach dem du
> das Port "abgeschaltet" hast wieder Impulse geben. Du musst den Timer
> schon abschalten.

Ja der Timer kann weiter laufen der Motor lässt sich abschalten. PC0

von Manu B. (manu_b)


Lesenswert?

Im Debugger läuft es wie es soll, daher vermutete ich das es vom 
Compiler evtl kommt. Das er iwas optimieren möchte.

von M. K. (sylaina)


Lesenswert?

Manu B. schrieb:
> Im Debugger läuft es wie es soll, daher vermutete ich das es vom
> Compiler evtl kommt. Das er iwas optimieren möchte.

Du hast

Walter T. schrieb:
> Micro unten wird bei Deiner Implementierung in jedem Schleifendurchlauf
> neu gesetzt. Es merkt sich nichts.

aus der ersten Antwort gelesen?

von Manu B. (manu_b)


Lesenswert?

Stimmt!!

Manchmal sieht man den Baum vor lauter Wälder nicht mehr.
Oder so ;-)

Danke

von Manu (Gast)


Lesenswert?

Verstehe das nicht ganz...
Er merkt sich nichts.
Wie sollte ich das machen das er es sich mekt?

von Hubert G. (hubertg)


Lesenswert?

Ein Flag setzen das du erst zurücksetzt wenn der Motor wieder laufen 
soll.

von Walter (Gast)


Lesenswert?

Manu B. schrieb:
> TIMSK0 |= 1<<TOIE0;

einen Interupt freigeben ohne zugehörige Routine führt alsbald zurück 
auf LOS

volatile ist unnötig

von Manu B. (manu_b)


Lesenswert?

Walter schrieb:
> einen Interupt freigeben ohne zugehörige Routine führt alsbald zurück
> auf LOS

Genau das war auch das Problem.
Der uC startete die ganze Zeit neu.

Jetzt läuft alles wie es soll.
Danke für die zahlreichen Antworten.

MFG

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.