Forum: Mikrocontroller und Digitale Elektronik ATMega 32 2xMotor + Lichtsensor


von Daniel M. (danielmo)


Lesenswert?

Hallo Liebe Programmierkollegen

Erstmal bin ich neu in diesem Forum, deshalb möchte ich mal alle hier 
begrüßen.

Kurz zu mir, programmiere seit einem halben Jahr im Laufe meiner 
Diplomarbeit an avr-controllern.

Leider wird die Zeit langsam knapp, und ich brauche dringend hilfe.

Mein Problem ist(was eigentlich ganz einfach sein sollte), ich habe 2 
Schrittmotoren, mit einem Lichtsensor

Programmablauf: Motor 1 startet, bis Lichtsensor unterbrochen wird, 
dannach stopt Motor 1, motor 2 läuft für 1sekunde an, stoppt dann 
wieder, und Motor 1 läuft wieder an, Lichtsensor wird wieder frei, und 
der Kreislauf fängt von vorne an.

Beide Motoren + Lichtsensor funktionieren alleine einwandfrei.

mein Problem: sobald Lichtsensor unterbrochen wird, stoppt zwar Motor 1, 
und Motor 2 beginnt sich dann zu drehen, nur läuft er dann ins 
unendliche und kommt anscheinend aus meiner Schleife nicht mehr heraus.

Im Simulator funktioniert es aber einwandfrei...

Hier meine Programmzeilen

Ich weiß es ist einfach ein wenig viel Prpgrammcode auf 1x, aber ich 
hoffe es ist nur eine kleinigkeit, und für einen Experten kein Problem

Ich hoffe auch das ich nicht irgendwelche Foren Regeln verletze, wenn ja 
bitte einfach melden, damit ich das ändern kann.

Habe auch im Forum gesucht, komme aber mit einem anderen P-Stil nicht 
zusammen.

Wäre sehr dankbar, wenn mir einer helfen kann

mfg

PS: die inkludierten Funktionen wie motor1_EIN(), habe ich nicht 
hinzugefügt, sie laufen aber alleine alle ohne Probleme

1) Main()
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <io.h>
#include <iom32.h>
#include <util/delay.h>
#include <avr/io.h>
#include <inttypes.h>
#include <avr/delay.h>



#include <Init_Blister.h>

#include <Timer0.h>

#include <Motor1_EIN.h>
#include <Motor1_AUS.h>

#include <Motor2_EIN.h>
#include <Motor2_AUS.h>

#include <MV1_HOCH.h>
#include <MV1_RUNTER.h>

#include <Step_Motor.h>

volatile int Cnt = 0;      //für Timer
unsigned char clock =0;    //füt Timer Takt

int Motor1_ON=0;
int Motor2_ON=0;

int freigabe=0;



void main(void)
{
  Init_Blister();
  Timer0();
  SREG=SREG|0x80;        // Interrupts freigeben


  while(1)
  {
    //_delay_us(10);

    if(!(PINA &(1<<PA0 )))
      freigabe=0;



    if(PINA &(1<<PA0 )&& freigabe==0)         //wenn Lichtschranke 1 
unterbrochen wird,
                            // wird Motor 1 gestoppt

    {
      Motor1_AUS();
      MV1_RUNTER();
      Step_Motor(2);




    }
    else
    {
    Motor1_EIN();
    MV1_HOCH();
    }
  }

}









int TIMER0_OVF_vect (void)    //beim Überlauf des Timers
{


  Cnt++;

  if(Motor1_ON==1)
  {
    if(Cnt>=10)
    {

      clock^=1;
      Cnt=0;

      if(clock==1)       // bei jeden überlauf des Timers wird der
        PORTC|=2;      //clock einmal auf 1 bzw beim nächsten Überlauf
      if(clock==0)     // auf 0 gesetzt, um einen Takt für die 
Motor_clock
        PORTC&=0xFD;   // Leitung zu erzeugen



    }
  }

  if(Motor2_ON==1)
  {
    if(Cnt>=10)
    {

      clock^=1;
      Cnt=0;

      if(clock==1)
        PORTC|=8;
      if(clock==0)
        PORTC&=0xF7;


    }
  }




  SREG=SREG|0x80;


  return(0);
}



2.)Hier setze ich meine Ein u Ausgänge:
void Init_Blister(void)
{


  DDRA=0x00;   //Einänge  SUB25pol
  DDRC=0xFF;   //Ausgänge SUB25pol

  PORTC=0xFF;  //alles auf 1 setzten = invertierte ausgänge
  PORTA=0xFF;   //Pull-Up Widerstände aktivieren

  MV1_HOCH();

}

3)step_motor funktion

int freigabe;
unsigned long int i=0;

int Step_Motor(int Motor)
{



  if (Motor==1)
  {


  }

  if (Motor==2)
  {


    Motor2_EIN();




      _delay_ms(1000); //Programm wartet 1000ms mit dem vorigen Zustand


    Motor2_AUS();






    freigabe=1;

    return(freigabe);
  }
}

4.) Timer init
void Timer0(void)
{


TCNT0=0x00;                  //Timer Laden bzw. Vorladen

TCCR0=0x02;                     //Vorteiler
TIMSK=TIMSK | 0x01;             //Interrupt erlauben

                //1600000/1024=15625
                //15625/256= 61,03515 Interrupts pro sekunde
}

von Tom M. (Gast)


Lesenswert?

Bitte hänge doch den Source Code an oder versieh in mit den 
entsprechenden Tags, ich tu mir sehr schwer mit lesen.

Was mir auf die Schnelle auffällt:
*Du fummelst am SREG rum. Das ist nicht nötig, dazu gibt's die 
Funktionen/Makros sei() und cli().
*Die Datentypen würd ich auch explizit definieren, damit auf Anhieb die 
Wertbereiche klar sind (uint8_t & Konsorten).
*return(0) in einer void Funktion ist auch sinnfrei.
*Wenn du Stati abbildest, könntest du dir auch überlegen, eval-Typen zu 
deklarieren und switch/case Konstrukte zu verwenden. das erhöht die 
Lesbarkeit enorm, zu Lasten von etwas PGMEM.

Zum Verständnis des Code hilft auch, wenn man die Verdrahtung der HW 
kennt. Wo ist was wie angeschlossen?

von Daniel M. (danielmo)


Angehängte Dateien:

Lesenswert?

Hallo Tom

Danke für die rasche Antwort, hab das komplette programm in einer Datei 
im Anhang

zu den Anschlüssen

Motor 1

Enable PC0
clock  PC1

Motor 2

Enable PC2
clock  PC3

direkten ist bei beiden Motoren nicht angesclossen, da er sich nur in 
eine Richung drehen muss.

Lichtschranke

PA0

danke im Voraus

von Tom M. (Gast)


Lesenswert?

Was ist mit der Variablen "freigabe", die sollte wahrscheinlich global 
definiert sein bzw. in der einen Datei als extern - oder?

von Daniel M. (danielmo)


Lesenswert?

ist sie mit int freigabe;

vor der Schleife nicht global?????

oder wo gehört sie genau hin, bitte ganz einfach erklären, wie gesagt 
bin sehr neu, und komm mit der ganzen Programmiersprache nicht zusammen.


sie dient dazu sobald der Sensor unterbrochen wurdem und er in die 
step_motor funktion geht, wird sie auf 1 gesetzt, somit kommt er beim 
rücktritt in der main nicht mehr in die if(PINA &(1<<PA0 )&& 
freigabe==0)

von Tom M. (tomm) Benutzerseite


Lesenswert?

Daniel Morassi schrieb:
> ist sie mit int freigabe;
>
> vor der Schleife nicht global?????

Nein, die beiden Variablen haben nix miteinander zu tun. Jedes Modul 
kennt zwar eine Variable namens "freigabe", aber sie ist eben zweimal 
vorhanden.

Was du möchtest, erreichst du, indem du in einem Modul (.c File) die 
Variable wie gewohnt deklarierst, und in jedem weiteren, in welchem du 
sie verwenden willst, sie so deklarierst:
1
extern int freigabe; // Globale Variable, definiert in blabla.c

Lies mal hier:
http://crasseux.com/books/ctutorial/External-variables.html

Alles klar? :)

von Flo (Gast)


Lesenswert?

Bin mal neugierig und frag, was das für eine Diplomarbeit wird?
;-)

von Daniel M. (danielmo)


Lesenswert?

ok danke einmal

habe das jetzt so verstanden

ich lege in .c file an z.B globalea_variablen.c

in das ich schreibe

#include <stdio.h>
int freigabe;

in den anderen .c files wo ich es verwenden möchte, schreibe ich

nach den
#include <blablabla.h>

extern int freigabe // ohne =0 bzw 1

und in den Programmen selbst

ganz normal
if(PINA &(1<<PA1 )&& freigabe==0)

ich hoffe ich hab das jetzt richtig verstanden

mfg

von Karl H. (kbuchegg)


Lesenswert?

machs so

http://www.mikrocontroller.net/articles/FAQ#Globale_Variablen_.C3.BCber_mehrere_Dateien

wie dort im Unterkapitel "Prakitsche Durchführung" beschrieben.
(Aber lies dir alles durch!)

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.