Forum: Mikrocontroller und Digitale Elektronik Timer und Resetprobleme mit Mega16


von Chris (Gast)


Lesenswert?

Ich habe mein Projekt Regendusche nun endlich technisch umgesetzt.
Jetzt hapert es aber an einigen Stellen im Programmtext .
Folgende Eckdaten :
Mega16
Quarz 11059200 Hz
C++

Ich habe zwei Probleme .

Problem 1 (Reset) :
Aus irgendeinem Grund macht der Mega einen Reset ?! (denke ich) wenn ich 
von einer aktivierten Tropenregendusche auf den Taster Regen Mitte 
drücke .
Witzigerweise funktioniert es aber andersrum ohne diesen Reset .
Ich habe für mich alles durch komme hier aber auf keine Idee .
Brown out habe ich übrigens aus .
Kurzschluss etc ist ausgeschlossen .


Problem 2 (Timer) :
Ich habe alle 3 Timer im Gebrauch für die RGB Kanäle sowie den Dimmer 
der Halogenleuchten .
Für zb das Blinken der Taster wenn sie aktiviert sind brauche ich jedoch 
einen Takt idealerweise eine Sekunde .
Mit meiner Overflow Funktion scheine ich allerdings die PWM Frequenz 
erwischt zu haben ,sodass wenn sich die Farbe ändert auch die 
Schnelligkeit ändert wann der Overflow ausgelöst wird .
Hier habe ich auch noch keine Idee .


Zuletzt natürlich noch der Programmtext :( Sorry wenn hier und da 
verwirrend :S)

//----------------------------------------------------------------------
#define   F_CPU 11059200
#include  <avr\io.h>    Konstantendefinitionen
#include <inttypes.h>
#include <avr\interrupt.h>

//------------------------------------------------------------ Globale 
Variablen
#define MAGNET_KALT      1
#define MAGNET_WARM      0
#define MAGNET_TEIL      2
#define DUFT             3
#define LED_TROPENREGEN  0
#define LED_REGEN_MITTE  1
#define LED_ERFRISCHUNG  2
#define LED_VITALREGEN   3
#define LED_DUFT         6
#define LED_LED          5
char tropenregen_an = 0;
char regen_mitte_an = 0;
char erfrischung_an = 0;
char vitalregen_an = 0;
char duft_an = 1;
char led_an  = 1;
char dusche_an = 0;
char pressed = 0;
char led_active = 0 ;
char vital_active = 0;
char ledonoff = 1;
int timecount = 0;

//OCR1A = 20   ;        // blau
//OCR1B = 200  ;        // grün
//OCR0  = 255  ;        // rot

//----------------------------------------------------------------------
void pwmInit()
{

  TCCR0  = 0b01100001 ;  // Timer R  Prescaler 1024 / Phase Correct PWM

  TCCR1A = 0b10100001 ;  //  Timer G  Prescaler 1024 / Phase Correct PWM
  TCCR1B = 0b00000001 ;  //  Timer B  Prescaler 1024 / Phase Correct PWM

  TCCR2  = 0b01100001 ;  //  Timer DimmerPrescaler 1024 / Phase Correct 
PWM

  TIMSK  = 0b00000001;
}
//----------------------------------------------------------------------

void reset_all()
{
  tropenregen_an = 0;
  regen_mitte_an = 0;
  erfrischung_an = 0;
  vitalregen_an = 0;
  led_active = 0;
  ledonoff = 1;
}

//----------------------------------------------------------------------
void Dimmer (char updown)
{
  if (updown == 1)  // hochdimmmen
  {
    while (OCR2 < 255)
    {
      OCR2 = OCR2+1;
      waitMs(7);
    }

  }
  //----------------------------------------------------------------------
else if (updown == 0)
  {

    while (OCR2>40)   // runterdimmen
    {
      OCR2 = OCR2-1;
      waitMs(7);
    }
  }

}

//----------------------------------------------------------------------

void LED_Ausgabe (char anaus)
{
  if (anaus == 1)
  {
    if ( duft_an == 1)
    {
      PORTD |= (1 <<LED_DUFT);   // Duft LED an
    }

  else if (duft_an == 0)
    {
      PORTD &=~ (1 <<LED_DUFT);  // Duft LED aus
    }

    if ( led_an == 1)
    {
      PORTC |= (1 <<LED_LED);   // Duft LED an
    }

  else if (led_an == 0)
    {
      PORTC &=~ (1 <<LED_LED);  // Duft LED aus
    }

    if ( led_active == 0 )         // Standartlicht
    {
      PORTD |= ( (1 <<LED_TROPENREGEN) | (1 << LED_REGEN_MITTE) | (1 << 
LED_ERFRISCHUNG) | (1 << LED_VITALREGEN) ) ; //LED Tastenfeld an
      OCR1A = 20   ;        // blau
      OCR1B = 200  ;        // grün
      OCR0  = 255  ;        // rot
    }

  }

else if (anaus == 0)   // alle Lichter aus
  {
    PORTD &=~ ( (1 <<LED_TROPENREGEN) | (1 << LED_REGEN_MITTE) | (1 << 
LED_ERFRISCHUNG) | (1 << LED_VITALREGEN) | (1 << LED_DUFT) ) ;
    PORTC &=~ ( 1 << LED_LED ) ;
    OCR1A = 0   ; // blau
    OCR1B = 0  ; // grün
    OCR0  = 0  ; // rot
  }

}

//------------------------------------------------------------

void Taster_abfragen () 
// Tastenabfrage
{
  switch (PINA & 0b11111111)
  {

    //------------------------------------------------------------
    case 0b10111110 : 
// Taster Tropenregen
    if (tropenregen_an == 0 & pressed != 1 & dusche_an == 1)
    {
      reset_all();
      pressed = 1;
      if (led_an == 1)
      {

        if (OCR2 == 255)
        {
          Dimmer (0);
        }
        led_active = 1;
        OCR1A = 0   ;        // blau
        OCR1B = 0  ;        // grün
        OCR0  = 255  ;        // rot
      }
      tropenregen_an = 1;
      PORTC |= ((1 << MAGNET_TEIL) | (1 << MAGNET_WARM)) ; 
//Magnetventile anschalten
      PORTC &= ~ ( (1 << MAGNET_KALT) ) ;
    }
  else if (tropenregen_an == 1 & pressed != 1 & dusche_an == 1 )
    {
      reset_all(); 
//Magnetventile und LED ausschalten
      pressed = 1;
      if (led_an == 1)
      {
        Dimmer (1);
      }
      PORTC &= ~ ( (1 << MAGNET_KALT) | (1 << MAGNET_WARM) | (1 << 
MAGNET_TEIL) ) ;
    }
    break;

    //------------------------------------------------------------

    case 0b10111101 : 
// Taster Regen Mitte
    if (regen_mitte_an == 0 & pressed != 1 & dusche_an == 1 )
    {
      reset_all();
      pressed = 1;
      if (led_an == 1 )
      {
        if (OCR2 == 255)
        {
          Dimmer (0);
        }
        led_active = 1;
        OCR1A = 0   ;        // blau
        OCR1B = 255  ;        // grün
        OCR0  = 0  ;        // rot
      }
      regen_mitte_an = 1;
      PORTC |= (1 << MAGNET_WARM) ;                                   // 
Magnetventile anschalten
      PORTC &= ~ ( (1 << MAGNET_KALT) | (1 << MAGNET_TEIL) ) ;
    }
  else if (regen_mitte_an == 1 & pressed != 1 & dusche_an == 1 )
    {
      reset_all();
      pressed = 1;
      if (led_an == 1)
      {
        Dimmer (1);
      }
      PORTC &= ~ ( (1 << MAGNET_KALT) | (1 << MAGNET_WARM) | (1 << 
MAGNET_TEIL) ) ;

    }

    break;

    //------------------------------------------------------------

    case 0b10111011 : 
// Taster Erfrischung
    if (erfrischung_an == 0 & pressed != 1 & dusche_an == 1 )
    {
      reset_all();
      pressed = 1;

      if (duft_an == 1)
      {
        PORTC |= (1 << DUFT) ;
      }

      if (led_an == 1)
      {
        Dimmer (0);
        led_active = 1;
        OCR1A = 255   ;        // blau
        OCR1B = 0  ;        // grün
        OCR0  = 0  ;        // rot
      }

      erfrischung_an = 1;
      PORTC |= ( 1 << MAGNET_KALT ); 
//Magnetventile anschalten
      PORTC &= ~ ( (1 << MAGNET_TEIL) | (1 << MAGNET_WARM) ) ;

    }
  else if (erfrischung_an == 1 & pressed != 1 & dusche_an == 1 )
    {
      reset_all(); 
//Magnetventile und LED ausschalten
      pressed = 1;
      if (led_an == 1)
      {
        Dimmer (1);
      }
      PORTC &= ~ ( (1 << MAGNET_KALT) | (1 << MAGNET_WARM) | (1 << 
MAGNET_TEIL) | (1 << DUFT)) ;
    }

    break;

    //------------------------------------------------------------

    case 0b10110111 :                                                 // 
Taster Vitalregen
    if (vitalregen_an == 0 & pressed != 1 & dusche_an == 1 )
    {
      reset_all();
      pressed = 1;
      if (led_an == 1)
      {
        Dimmer (0);
        led_active = 1;

      }

      vitalregen_an = 1;
      PORTC |= ((1 << MAGNET_TEIL) | (1 << MAGNET_WARM)) ;
      PORTC &= ~ ( (1 << MAGNET_KALT) ) ;

    }
  else if (vitalregen_an == 1 & pressed != 1 & dusche_an == 1 )
    {
      //Magnetventile und LED ausschalten
      reset_all();
      pressed = 1;
      if (led_an == 1)
      {
        Dimmer (1);
      }
      PORTC &= ~ ( (1 << MAGNET_KALT) | (1 << MAGNET_WARM) | (1 << 
MAGNET_TEIL) ) ;
    }

    break;

    //------------------------------------------------------------

    case 0b10101111 : 
// Taster Duftstoff
    if (duft_an == 0 & pressed != 1 & dusche_an == 1 )
    {
      pressed = 1;
      duft_an = 1;
    }
  else if (duft_an == 1 & pressed != 1 & dusche_an == 1 )
    {
      pressed = 1;
      duft_an = 0;
    }

    break;

    //------------------------------------------------------------

    case 0b10011111 : 
// Taster LED-Licht
    if (led_an == 0 & pressed != 1 & dusche_an == 1 )
    {
      pressed = 1;
      led_an  = 1;
      led_active = 0;
    }
  else if (led_an == 1 & pressed != 1 & dusche_an == 1 )
    {
      pressed = 1;
      led_an  = 0;
      led_active = 0;
    }
    break;

    //------------------------------------------------------------

    case 0b10111111 :       // Kontakt Dusche eingeschaltet
    waitMs(100);
    dusche_an = 1;
    pressed   = 0;
    break;

    //------------------------------------------------------------

    default :               // kein Taster gedrückt / dusche aus
    dusche_an = 0;
    LED_Ausgabe(0) ;
    waitMs(100);
    pressed   = 0;
    break;

  }
}

//------------------------------------------------------------
void led_blinken()
{
  if (tropenregen_an == 1 & ledonoff == 0 )        // LED Tropenregen 
blinken
  {
    PORTD |= (1 <<LED_TROPENREGEN);
    ledonoff = 1;
  }
else if (tropenregen_an == 1 & ledonoff == 1 )
  {
    PORTD &=~ (1 <<LED_TROPENREGEN);
    ledonoff = 0;
  }

  if (regen_mitte_an == 1 & ledonoff == 0 )        // LED regen mitte 
blinken
  {
    PORTD |= (1 <<LED_REGEN_MITTE);
    ledonoff = 1;
  }
else if (regen_mitte_an == 1 & ledonoff == 1 )
  {
    PORTD &=~ (1 <<LED_REGEN_MITTE);
    ledonoff = 0;
  }

  if (erfrischung_an == 1 & ledonoff == 0 )        // LED Erfrischung 
blinken
  {
    PORTD |= (1 <<LED_ERFRISCHUNG);
    ledonoff = 1;
  }
else if (erfrischung_an == 1 & ledonoff == 1 )
  {
    PORTD &=~ (1 <<LED_ERFRISCHUNG);
    ledonoff = 0;
  }

  if (vitalregen_an == 1 & ledonoff == 0 )        // LED Vitalregen 
blinken
  {
    PORTD |= (1 <<LED_VITALREGEN);
    ledonoff = 1;
  }
else if (vitalregen_an == 1 & ledonoff == 1 )
  {
    PORTD &=~ (1 <<LED_VITALREGEN);
    ledonoff = 0;
  }

}

//------------------------------------------------------------

SIGNAL(SIG_OVERFLOW0)
{
  timecount = timecount+1 ;  // zähler erhöhen
  if (timecount == 10000)       // wenn 1 sec
  {
    timecount = 0;
    led_blinken();
  }

}

//----------------------------------------------------------------------

main ()
{
  DDRA  = 0b00000000 ;
  PORTA = 0b11111111 ;
  DDRB  = 0b00001000 ;
  PORTB = 0b11110111 ;
  DDRC  = 0b11111111 ;
  PORTC = 0b00000000 ;
  DDRD  = 0b11111111 ;
  PORTD = 0b00000000 ;
  pwmInit();
  reset_all();
  sei();
  OCR2 = 255;
  do

  {
    Taster_abfragen () ;

    if (dusche_an == 1 )
    {
      LED_Ausgabe(1) ;
    }

  }
  while (true);
}
//----------------------------------------------------------------------


Vielen Dank im vorraus schon für jede Hilfe :-)

von Hubert G. (hubertg)


Lesenswert?

Schön wäre es wenn du noch schreiben würdest welchen Compiler du 
verwendest und die Code Tags verwenden.

von Chris (Gast)


Lesenswert?

Das ganze hab ich mit dem MyAVR Workpad programmiert und nutze also auch 
dessen Ressourcen .
Hat denn keiner eine Idee was die Fehler verursachen könnte ? .
Vor allem der "Reset" ist besonders schlecht .

von Chris (Gast)


Lesenswert?

if ((tropenregen_an == 0) && (pressed != 1) &&  (dusche_an == 1))

das wäre so wohl besser .Hatte wohl falsch im Kopf das ein normales & 
die beiden mehr oder weniger verbindet und nicht als Einzelbedingung 
annimmt.


Ich ändere das mal im PText

von Chris (Gast)


Angehängte Dateien:

Lesenswert?

Hier die neue Funktion.
Alle Probleme aber wie bisher.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Hier ist eine Sackgasse. Dort geht es weiter:
Beitrag "Unerklärlicher Reset AtMega16 nach Tastendruck"

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.