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


von Chris (Gast)


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

1
//----------------------------------------------------------------------
2
#define  F_CPU 11059200  // Taktfrequenz des myAVR-Boards
3
#include <avr\io.h>    // AVR Register und Konstantendefinitionen
4
#include <inttypes.h>
5
#include <avr\interrupt.h>
6
7
//------------------------------------------------------------ Globale Variablen
8
#define MAGNET_KALT      1 
9
#define MAGNET_WARM      0 
10
#define MAGNET_TEIL      2 
11
#define DUFT             3 
12
#define LED_TROPENREGEN  0 
13
#define LED_REGEN_MITTE  1 
14
#define LED_ERFRISCHUNG  2 
15
#define LED_VITALREGEN   3 
16
#define LED_DUFT         6 
17
#define LED_LED          5 
18
char tropenregen_an = 0;
19
char regen_mitte_an = 0;
20
char erfrischung_an = 0;
21
char vitalregen_an = 0;
22
char duft_an = 1;
23
char led_an  = 1;
24
char dusche_an = 0;
25
char pressed = 0;
26
char led_active = 0 ;
27
char vital_active = 0;
28
char ledonoff = 1;
29
int timecount = 0;
30
31
//OCR1A = 20   ;        // blau
32
//OCR1B = 200  ;        // grün
33
//OCR0  = 255  ;        // rot
34
35
//----------------------------------------------------------------------
36
void pwmInit()
37
{
38
39
  TCCR0  = 0b01100001 ;  // Timer R  Prescaler 1024 / Phase Correct PWM
40
41
  TCCR1A = 0b10100001 ;  //  Timer G  Prescaler 1024 / Phase Correct PWM
42
  TCCR1B = 0b00000001 ;  //  Timer B  Prescaler 1024 / Phase Correct PWM
43
44
  TCCR2  = 0b01100001 ;  //  Timer DimmerPrescaler 1024 / Phase Correct PWM
45
46
  TIMSK  = 0b00000001;
47
}
48
//----------------------------------------------------------------------
49
50
void reset_all()
51
{
52
  tropenregen_an = 0;
53
  regen_mitte_an = 0;
54
  erfrischung_an = 0;
55
  vitalregen_an = 0; 
56
  led_active = 0;
57
  ledonoff = 1;
58
}
59
60
//----------------------------------------------------------------------
61
void Dimmer (char updown)
62
{
63
  if (updown == 1)  // hochdimmmen
64
  {
65
    while (OCR2 < 255)   
66
    {
67
      OCR2 = OCR2+1;
68
      waitMs(7);
69
    }
70
71
  }
72
  //----------------------------------------------------------------------
73
else if (updown == 0)
74
  {
75
76
    while (OCR2>40)   // runterdimmen
77
    {
78
      OCR2 = OCR2-1;
79
      waitMs(7);
80
    }
81
  }
82
83
}
84
85
//----------------------------------------------------------------------
86
87
void LED_Ausgabe (char anaus)
88
{
89
  if (anaus == 1)
90
  {
91
    if ( duft_an == 1)
92
    {
93
      PORTD |= (1 <<LED_DUFT);   // Duft LED an
94
    }
95
96
  else if (duft_an == 0)
97
    {
98
      PORTD &=~ (1 <<LED_DUFT);  // Duft LED aus
99
    }
100
101
    if ( led_an == 1)
102
    {
103
      PORTC |= (1 <<LED_LED);   // Duft LED an
104
    }
105
106
  else if (led_an == 0)
107
    {
108
      PORTC &=~ (1 <<LED_LED);  // Duft LED aus
109
    }
110
111
    if ( led_active == 0 )         // Standartlicht
112
    {
113
      PORTD |= ( (1 <<LED_TROPENREGEN) | (1 << LED_REGEN_MITTE) | (1 << LED_ERFRISCHUNG) | (1 << LED_VITALREGEN) ) ; //LED Tastenfeld an
114
      OCR1A = 20   ;        // blau
115
      OCR1B = 200  ;        // grün
116
      OCR0  = 255  ;        // rot
117
    }
118
119
  }
120
121
else if (anaus == 0)   // alle Lichter aus
122
  {
123
    PORTD &=~ ( (1 <<LED_TROPENREGEN) | (1 << LED_REGEN_MITTE) | (1 << LED_ERFRISCHUNG) | (1 << LED_VITALREGEN) | (1 << LED_DUFT) ) ;
124
    PORTC &=~ ( 1 << LED_LED ) ; 
125
    OCR1A = 0   ; // blau
126
    OCR1B = 0  ; // grün
127
    OCR0  = 0  ; // rot  
128
  }
129
130
}
131
132
//------------------------------------------------------------
133
134
void Taster_abfragen ()                                                         // Tastenabfrage
135
{
136
  switch (PINA & 0b11111111)
137
  {
138
139
    //------------------------------------------------------------
140
    case 0b10111110 :                                                    // Taster Tropenregen
141
    if ((tropenregen_an == 0) && (pressed != 1) && (dusche_an == 1))
142
    {
143
      reset_all();
144
      pressed = 1;
145
      if (led_an == 1)
146
      {
147
148
        if ( OCR2 == 255 )
149
        {
150
          Dimmer (0);
151
        }
152
        led_active = 1;
153
        OCR1A = 0   ;        // blau
154
        OCR1B = 0  ;        // grün
155
        OCR0  = 255  ;        // rot
156
      }
157
      tropenregen_an = 1;
158
      PORTC |= ((1 << MAGNET_TEIL) | (1 << MAGNET_WARM)) ;             //Magnetventile anschalten
159
      PORTC &= ~ ( (1 << MAGNET_KALT) ) ; 
160
    }
161
  else if ((tropenregen_an == 1) && (pressed != 1) && (dusche_an == 1) ) 
162
    {
163
      reset_all();                                                     //Magnetventile und LED ausschalten
164
      pressed = 1; 
165
      if (led_an == 1)
166
      {
167
        Dimmer (1);
168
      }
169
      PORTC &= ~ ( (1 << MAGNET_KALT) | (1 << MAGNET_WARM) | (1 << MAGNET_TEIL) ) ;      
170
    }
171
    break;
172
173
    //------------------------------------------------------------
174
175
    case 0b10111101 :                                                   // Taster Regen Mitte
176
    if ((regen_mitte_an == 0) && (pressed != 1) && (dusche_an == 1) )
177
    {
178
      reset_all();
179
      pressed = 1;
180
      if (led_an == 1 )
181
      {
182
        if (OCR2 == 255)
183
        {
184
          Dimmer (0);
185
        }
186
        led_active = 1;
187
        OCR1A = 0   ;        // blau
188
        OCR1B = 255  ;        // grün
189
        OCR0  = 0  ;        // rot
190
      }
191
      regen_mitte_an = 1;
192
      PORTC |= (1 << MAGNET_WARM) ;                                   // Magnetventile anschalten
193
      PORTC &= ~ ( (1 << MAGNET_KALT) | (1 << MAGNET_TEIL) ) ; 
194
    }
195
  else if ((regen_mitte_an == 1) && (pressed != 1) && (dusche_an == 1) ) 
196
    {
197
      reset_all();
198
      pressed = 1;      
199
      if (led_an == 1)
200
      {
201
        Dimmer (1);
202
      }
203
      PORTC &= ~ ( (1 << MAGNET_KALT) | (1 << MAGNET_WARM) | (1 << MAGNET_TEIL) ) ; 
204
205
    }
206
207
    break;
208
209
    //------------------------------------------------------------    
210
211
    case 0b10111011 :                                                  // Taster Erfrischung
212
    if ((erfrischung_an == 0) && (pressed != 1) && (dusche_an == 1) )
213
    {
214
      reset_all();
215
      pressed = 1;
216
217
      if (duft_an == 1)
218
      {
219
        PORTC |= (1 << DUFT) ;
220
      }
221
222
      if (led_an == 1)
223
      {
224
        Dimmer (0);
225
        led_active = 1;
226
        OCR1A = 255   ;        // blau
227
        OCR1B = 0  ;        // grün
228
        OCR0  = 0  ;        // rot
229
      }
230
231
      erfrischung_an = 1;
232
      PORTC |= ( 1 << MAGNET_KALT );                                   //Magnetventile anschalten
233
      PORTC &= ~ ( (1 << MAGNET_TEIL) | (1 << MAGNET_WARM) ) ;  
234
235
    }
236
  else if ((erfrischung_an == 1) && (pressed != 1) && (dusche_an == 1) )    
237
    {
238
      reset_all();                                                   //Magnetventile und LED ausschalten
239
      pressed = 1; 
240
      if (led_an == 1)
241
      {
242
        Dimmer (1);
243
      }
244
      PORTC &= ~ ( (1 << MAGNET_KALT) | (1 << MAGNET_WARM) | (1 << MAGNET_TEIL) | (1 << DUFT)) ;
245
    }
246
247
    break;
248
249
    //------------------------------------------------------------    
250
251
    case 0b10110111 :                                                 // Taster Vitalregen
252
    if ((vitalregen_an == 0) && (pressed != 1) && (dusche_an == 1) )
253
    {
254
      reset_all();
255
      pressed = 1;
256
      if (led_an == 1)
257
      {
258
        Dimmer (0);
259
        led_active = 1;
260
261
      }
262
263
      vitalregen_an = 1;
264
      PORTC |= ((1 << MAGNET_TEIL) | (1 << MAGNET_WARM)) ;
265
      PORTC &= ~ ( (1 << MAGNET_KALT) ) ; 
266
267
    }
268
  else if ((vitalregen_an == 1) && (pressed != 1) && (dusche_an == 1) )    
269
    {
270
      //Magnetventile und LED ausschalten
271
      reset_all();
272
      pressed = 1;
273
      if (led_an == 1)
274
      {
275
        Dimmer (1);
276
      }
277
      PORTC &= ~ ( (1 << MAGNET_KALT) | (1 << MAGNET_WARM) | (1 << MAGNET_TEIL) ) ; 
278
    }
279
280
    break;
281
282
    //------------------------------------------------------------
283
284
    case 0b10101111 :                                                   // Taster Duftstoff
285
    if ((duft_an == 0) && (pressed != 1) && (dusche_an == 1) )
286
    {
287
      pressed = 1;
288
      duft_an = 1;
289
    }
290
  else if ((duft_an == 1) && (pressed != 1) && (dusche_an == 1) )
291
    {
292
      pressed = 1;
293
      duft_an = 0;
294
    }
295
296
    break;
297
298
    //------------------------------------------------------------
299
300
    case 0b10011111 :                                                   // Taster LED-Licht
301
    if ((led_an == 0) && (pressed != 1) && (dusche_an == 1 ))
302
    {
303
      pressed = 1;
304
      led_an  = 1;
305
      led_active = 0;
306
    }
307
  else if ((led_an == 1) && (pressed != 1) && (dusche_an == 1) )
308
    {
309
      pressed = 1;
310
      led_an  = 0;
311
      led_active = 0;
312
    }
313
    break;
314
315
    //------------------------------------------------------------
316
317
    case 0b10111111 :       // Kontakt Dusche eingeschaltet 
318
    waitMs(100);
319
    dusche_an = 1;
320
    pressed   = 0;
321
    break;
322
323
    //------------------------------------------------------------
324
325
    default :               // kein Taster gedrückt / dusche aus
326
    dusche_an = 0;
327
    LED_Ausgabe(0) ;
328
    waitMs(100);
329
    pressed   = 0;
330
    break;
331
332
  }
333
}
334
335
//------------------------------------------------------------
336
void led_wechsel()
337
{
338
339
}
340
//------------------------------------------------------------
341
342
void led_blinken()
343
{
344
  if ((tropenregen_an == 1) && (ledonoff == 0) )        // LED Tropenregen blinken
345
  {
346
    PORTD |= (1 <<LED_TROPENREGEN);
347
    ledonoff = 1;
348
  }
349
else if ((tropenregen_an == 1) && (ledonoff == 1) )
350
  {
351
    PORTD &=~ (1 <<LED_TROPENREGEN);
352
    ledonoff = 0;
353
  }
354
355
  if ((regen_mitte_an == 1) && (ledonoff == 0 ))        // LED regen mitte blinken  
356
  {
357
    PORTD |= (1 <<LED_REGEN_MITTE);
358
    ledonoff = 1;
359
  }
360
else if ((regen_mitte_an == 1) && (ledonoff == 1) )
361
  {
362
    PORTD &=~ (1 <<LED_REGEN_MITTE);
363
    ledonoff = 0;
364
  }
365
366
  if ((erfrischung_an == 1) && (ledonoff == 0) )        // LED Erfrischung blinken  
367
  {
368
    PORTD |= (1 <<LED_ERFRISCHUNG);
369
    ledonoff = 1;
370
  }
371
else if ((erfrischung_an == 1) && (ledonoff == 1) )
372
  {
373
    PORTD &=~ (1 <<LED_ERFRISCHUNG);
374
    ledonoff = 0;
375
  }
376
377
  if ((vitalregen_an == 1) && (ledonoff == 0 ))        // LED Vitalregen blinken  
378
  {
379
    PORTD |= (1 <<LED_VITALREGEN);
380
    ledonoff = 1;
381
  }
382
else if ((vitalregen_an == 1) && (ledonoff == 1) )
383
  {
384
    PORTD &=~ (1 <<LED_VITALREGEN);
385
    ledonoff = 0;
386
  }
387
388
}
389
390
//------------------------------------------------------------
391
392
393
394
SIGNAL(SIG_OVERFLOW0)
395
{
396
  timecount = timecount+1 ;  // zähler erhöhen
397
  if (timecount == 10000)       // wenn 1 sec
398
  {
399
    timecount = 0;
400
    led_blinken();
401
  }
402
403
}
404
405
406
407
  //----------------------------------------------------------------------
408
409
  main ()            
410
  {
411
    DDRA  = 0b00000000 ;
412
    PORTA = 0b11111111 ;
413
    DDRB  = 0b00001000 ;    
414
    PORTB = 0b11110111 ;
415
    DDRC  = 0b11111111 ;
416
    PORTC = 0b00000000 ;
417
    DDRD  = 0b11111111 ;
418
    PORTD = 0b00000000 ;
419
    pwmInit();  
420
    reset_all();  
421
    sei();
422
    OCR2 = 255;
423
    do
424
425
  {
426
    Taster_abfragen () ; 
427
428
    if (dusche_an == 1 )
429
    {
430
      LED_Ausgabe(1) ;
431
    }
432
433
  }
434
  while (true);      
435
}
436
//----------------------------------------------------------------------

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ist das ein Spaßbad?

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

von Leo .. (-headtrick-)


Lesenswert?

>Ist das ein Spaßbad?
Eher ne Spaßdusche.

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

von Chris (Gast)


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 ?!

von Hc Z. (mizch)


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:
1
o Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

von Chris (Gast)


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

von Captain S. (captainsubtext)


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.

von Karl H. (kbuchegg)


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
1
   DDRA  = 0b00000000 ;
2
    PORTA = 0b11111111 ;
3
    DDRB  = 0b00001000 ;    
4
    PORTB = 0b11110111 ;
5
    DDRC  = 0b11111111 ;
6
    PORTC = 0b00000000 ;
7
    DDRD  = 0b11111111 ;
8
    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
1
  TCCR0  = 0b01100001 ;  // Timer R  Prescaler 1024 / Phase Correct PWM
2
3
  TCCR1A = 0b10100001 ;  //  Timer G  Prescaler 1024 / Phase Correct PWM
4
  TCCR1B = 0b00000001 ;  //  Timer B  Prescaler 1024 / Phase Correct PWM
5
6
  TCCR2  = 0b01100001 ;  //  Timer DimmerPrescaler 1024 / Phase Correct PWM
7
8
  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?

von Jo O. (brause1)


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.

von Chris (Gast)


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 ?! .

von Chris (Gast)


Lesenswert?

CKOPT ist im übrigen deaktiviert .

von Chris (Gast)


Lesenswert?

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

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.