Programm springt falsch

Gast #1294520
Lesenswert?

Hallo zusammen,

ich bin gerade mit der AVR Programmierung angefangen und versuche ein 
Markisen Steuerung zu programmieren.

Quelltext:

// Port Definition
// PC0 -> Eingang -> rein / raus umschalter & motor bewegen
// PC1 -> Eingang -> Wind blockieren
// PC2 -> Eingang -> blockieren nicht möglich
// PC3 -> Ausgang -> durch Winde blockiert
// PC4 -> Ausgang -> rein / raus
// PC5 -> Ausgang -> Motor ein

#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>



struct
{
   unsigned wind:1; // 1 Bit für bStatus_1
   unsigned manuellbetrieb:1; // 1 Bit für bStatus_2
   unsigned motor_bewegung:1; // Und hier noch mal ein Bit
   unsigned richtung_raus:1;    // Dieses Feld ist 2 Bits breit
   // All das hat in einer einzigen Byte-Variable Platz.
   // die 3 verbleibenden Bits bleiben ungenutzt
} status;

int motor_ein()
{
  status.motor_bewegung = 1;
  PORTC |= (1<<PC5);

  return 0;
};

int motor_aus(void)
{
  PORTC &= ~(1<<PC5);
  status.motor_bewegung = 0;

  return 0;
};

volatile unsigned int Counter;
ISR( TIMER0_OVF_vect )
{
  Counter++;

  if(Counter == 2)
  {
    Counter = 0;
  TCCR0 &= ~((1<<CS00)|(1<<CS01)|(1<<CS02));  //Timer deaktivieren

  cli();
  motor_aus();
  }
};



int bewegungsrichtung_change()
{
  //Richtung invertieren
  PORTC = PINC ^ ( 1 << PC4 );

  return 0;
};

int markise_fahren()
{
  bewegungsrichtung_change();
  motor_ein();

  TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 ); // Teiler: 1024
  TIMSK = ( 1 << TOIE0 );         // Overflow Interrupt einschalten
  sei();                          // Interrupt generell zulassen

  return 0;
};


int markise_ein_fahren()
{
  //Bewegungsrichtung rein
  PORTC &= ~(1<<PC4);
  motor_ein();

  TCCR0 = ( 1 << CS02 ) | ( 1 << CS00 ); // Teiler: 1024
  TIMSK = ( 1 << TOIE0 );         // Overflow Interrupt einschalten

  return 0;
};


int init()
{
  //Datenrichtung bestimmen
  DDRC = 0b00111000;  //Ausgänge & Eingänge setzen


  status.wind = 0;
  status.manuellbetrieb = 1;
  status.motor_bewegung = 0;
  status.richtung_raus = 1;


  //Markiese einfahren
  markise_ein_fahren();

  return 0;
};

int main (void) {

  init();

  //markise_fahren();




  while(1)
  {
    if ( PINC & (1<<PINC0) )
    {
      markise_fahren();
    }

  }
  return 0;
};



Mein Problem ist, dass das Programm erst in die main() springt, dann in 
die init(). Soweit ist auch alles ok. Aber in der init() ruft er 
markise_ein_fahren(). Von dort führt er auch alles aus aber springt dann 
irgendwann in bewegungsrichtung_change() und anschließend in 
markise_fahren(). Aber warum?

Gruß,
Tobi
Gast #1294995
Lesenswert?

Hi, ibot,

"TIMSK = ( 1 << TOIE0 );         // Overflow Interrupt einschalten
  sei();                          // Interrupt generell zulassen"

Hier gibt Du Interrupts frei.
Bei jedem Überlauf springt der Programmzähler auf die Adresse, wo er den 
Sprungvektor für die Interrupt-Routine ISR(SIG_OVERFLOW0) (oder so 
ähnlich) erwartet - und dort rastet er aus.

Schau in das Datenblatt, welche ISR genau benötigt wird, füge sie hinzu, 
und schon ist dieser Fehler behoben - und der nächste taucht auf....;-(


Ciao
Wolfgang Horn

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren