mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Unerklärlicher Reset AtMega16 nach Tastendruck


Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe das Problem das mein Mega sich ständig resettet .
Wenn ich Tropenregen aktiviert habe und beim aktivierten Tropenregen den 
Taster Regen Mitte drücke wechselt das Programm nicht in dessen Aufrufe 
sondern macht einen kompletten Reset wie beim anlegen der 
Betriebsspannung .
Es handelt sich hier um einen AtMega16.
Brown out ist auch aus .
Irgendjemand eine Idee ?.
Das bringt mich etwas zum Verzweifeln :S

//----------------------------------------------------------------------
#define  F_CPU 11059200  // Taktfrequenz des myAVR-Boards
#include <avr\io.h>    // AVR Register und 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_wechsel()
{

}
//------------------------------------------------------------

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);      
}
//----------------------------------------------------------------------


Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist das ein Spaßbad?

Vielleicht beim Schalten, daß die Versorgungsspannung zumzapelt und es 
einen Reset auslöst.

Autor: Leo ... (-headtrick-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ist das ein Spaßbad?
Eher ne Spaßdusche.

Schaltplan wäre nützlicher als das Programm.
Störquellen sind meist Hardwarebedingt.

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jap eine Regendusche um genau zu sein .
Hmm also die betroffenen Ausgänge schalten zwar Relais allerdings über 
ein ULN2003A ,sodass hier eigentlich die Spannung nicht schwanken kann 
?! .
Gibt's sonst noch Quellen die den Reset auslösen ? .

Folgendes habe ich auch beobachtet :
Schalte ich von einer aktiven Tropendusche auf Regen Mitte löst das 
einen Reset aus .
Umgedreht also von Regen Mitte auf Tropenregen nicht .

Bei Tropenregen werden 2 Relais geschaltet bei Regen Mitte nur 1 .

Vielleicht sind die Zugriffe auf den Port auch zu dicht aufeinander ?

Zb hier .
{c]
PORTC |= (1 << MAGNET_WARM) ;
PORTC &= ~ ( (1 << MAGNET_KALT) | (1 << MAGNET_TEIL) ) ;
[c\]


Wieso das aber einen Reset auslösen sollte ?!

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kommt mir doch irgendwie bekannt vor.  Und täglich grüßt das 
Murmeltier ...
Beitrag "Timer und Resetprobleme mit Mega16"

Hier wie dort wurde das nicht beachtet:
o Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klar den Code gibt's beim anderen Thread als Anhang .(ganz unten)

Neuer Status jetzt ist aber das  ganz sicher ein kompletter Reset vom 
Mega durchgeführt wird .
Soweit wäre ich also schonmal

Autor: Captain Subtext (captainsubtext)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist denn der Tropenregen?
Etwas in Richtung Relais, das eine Pumpe ansteuert?

Dann empfehle ich eindeutig einen Snubber!

Ich schlage zum Test pauschal die Artikelnummern 456128, 456152 oder 
456144 von Conrad vor. Die findest Du aber auch bei Reichelt und Co.

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

Bewertung
0 lesenswert
nicht lesenswert
Chris schrieb:

> Neuer Status jetzt ist aber das  ganz sicher ein kompletter Reset vom
> Mega durchgeführt wird .
> Soweit wäre ich also schonmal

Ich gehe mal davon aus, dass deine Initialisierung in main() bei den 
Ports alle LED einschaltet oder dergleichen und du daran erkennst, dass 
ein Reset erfolgt.

Aus
   DDRA  = 0b00000000 ;
    PORTA = 0b11111111 ;
    DDRB  = 0b00001000 ;    
    PORTB = 0b11110111 ;
    DDRC  = 0b11111111 ;
    PORTC = 0b00000000 ;
    DDRD  = 0b11111111 ;
    PORTD = 0b00000000 ;

ist das nicht wirklich für uns Laien erkennbar, daher die Nachfrage.


Programm sieht in der Beziehung eigentlich ganz gut aus, auch wenn mir 
das hier
  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;
sauer aufstösst, das könnte man alles auch lesbarer schreiben. Aber wenn 
mich mein Gedächtnis nicht täuscht (und nein, ich hab jetzt keine Lust 
dem nachzugehen) dann ist Bit 0 im TIMSK tatsächlich der Overflow 
Interrupt vom Timer 0 und dafür hast du eine ISR

Andere freigegebenen Interrupts konnte ich nicht entdecken, so dass wohl 
die Hautursache für seltsame Resets nicht gegeben ist.

Softwaremässig passiert ja nicht viel weiteres, sodass ein 
Programmfehler eher unwahrscheinlich ist (auch wenn man noch ein paar 
Worte zu deiner Abfragemanie verlieren könnte, die den Code nur unnötig 
in die Länge ziehen)

Also Hardware:
Hast du zb die Fuse CKOPT programmiert, damit der Quarzoszillator stabil 
läuft. In einem Parallelthread war genau das die Ursache für seltsame 
Resets.

Wie sieht deine Hardware aus?
Sind zb an den Relais Freilaufdioden?
Was ist mit der Spannungsversorgung des Mega? Kann es da zu Spikes 
kommen?
Hast du zb schon mal ausprobiert, ob die Resets auch dann auftreten, 
wenn du die Relais abklemmst?

Autor: Jo O. (brause1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sieht denn die Eingangsbeschaltung von deinem Taster aus?

Ich tipp mal auf einen Kurzschluss der Versorgungsspannung (über einen 
Kondensator) beim Drücken der Taste.

Auf dem Pollin Entwicklungsboard ist so eine Schaltung drauf die beim 
Drücken unter bestimmten Bedingungen auch einen Rest auslöst.

Wenn du die nachgebaut hast, ist das wahrscheinlich der Fehler.

Hab die anderen Antworten nur überflogen. Wenn das schon kam, dann 
einfach ignorieren.

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut also das Resetproblem wird ein Hardwareproblem sein .
Das muss ich morgen mal alles durchprüfen .
Eventuell sackt aus welchem Grund auch immer wirklich die Spannung ein.
Wobei mich wundert das es immer nur passiert wenn ich die jeweiligen 
Relais aus mache .
Wie schon gerade geschrieben werden insgesamt 3 Relais geschaltet alles 
über einen ULN2003A geschaltet und entsprechend gedämpft .

Ich habe aber noch eine Frage .
Ich nutze den Timer Overflow damit die jeweilige Tasten-LED blinkt 
solange der entsprechende Modus aktiviert ist .
Wenn ich allerdings die Farbe der RGB LEDs ändere die an OCR1A/B sowie 
OCR0 angeschlossen sind habe ändert sich auch die Blinkgeschwindigkeit 
der Tasten-LEDs .

Ich war davon ausgegangen das der Overflow jeweils bis 256 läuft und 
nicht bis zum in OCR0 eingestellten Wert ?! .

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
CKOPT ist im übrigen deaktiviert .

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Problem gelöst. Eine Funktion hat das Blinken immer überschrieben .
Vielen Dank nochmal an alle .

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.