Forum: Mikrocontroller und Digitale Elektronik Mein AVR nimmt mich auf den Arm - Was ist los mit dem ADC?


von Daniel B. (scheinleistung)


Lesenswert?

Hallo zusammen,

Ich hab ein ominöses Problem und komm nicht auf den Fehler ...

Ich hab eine Funktion geschrieben die den MEGA168 runterfährt wenn die 
Batteryspannung kritisch wird. Siehe unten.

Es gibt z.B. eine 3V Schwelle, funktioniert super: bei Unterschreiten 
wird Berieb eingestellt.

Auch z.B. die 3,6V Schwelle funktioniert super.

Jetzt gibt es aber auch eine 6,0V Schwelle. Hier wirds komisch:
Anstatt dass der uC abschaltet, hängt er sich auf und wiederholt das 
Blinken einer LED die das "Runterfahren" anzeigt unendlich lange.
Da hilft nur ein kompletter Neustart.
AB JETZT tritt das Problem aber NIE MEHR auf - ab jetzt wird bei 
Unterschreiten auch sofort runtergefahen. Nur das erste Mal hängt er 
sich auf - und schützt so natürlich nicht die batterie. So und jetzt?? 
Hab alles mögliche probiert.

Ich messe Spannungen von 3 bis 10V und versorge den uC und ADC mit 3V.

Hier der Code. Woran kann es liegen??
1
void guard(void)
2
{
3
   if(supplyLevel_ui < voltageLevel_ui[0])
4
   {
5
      shutDown();
6
   }
7
}

1
void shutDown(void)
2
{
3
   cli();
4
5
   // Watchdog abschalten um autom. Reset (=Neustart) zu vermeiden
6
   wdt_disable();
7
8
   clearLEDs();
9
10
   //Info LED
11
   infoShutdown();    
12
13
   //Herunterfahren
14
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);
15
   sleep_enable();
16
   sleep_cpu();              
17
}

Hat vielleicht jemand eine Idee? Ich verzweifle ^^

von R. F. (rfr)


Lesenswert?

Die am ADC liegende Spannung darf nicht grösser als 5 V sein.
Wo liegt deine Referenz?

Gruss
Robert

von Daniel B. (scheinleistung)


Lesenswert?

Die Referenz ist 3,0V gepuffert. Über einen Spannungsteiler messe ich 
die Spannungen am ADC zwischen 1 und 3V. Diese 6V Schwelle zB ergibt 
dann am Spannungsteiler zB 2,00V.

von ... (Gast)


Lesenswert?

R. Freitag schrieb:
> Die am ADC liegende Spannung darf nicht grösser als 5 V sein.

Falsch! Die darf nicht höher als Vref sein. Und Vref darf nicht höher 
als AVcc sein.

von Daniel B. (scheinleistung)


Lesenswert?

Genau. Hier kann es auch kein Problem geben, funktioniert an sich.
Nur dass es sich eben beim ERSTEN Unterschreiten der 6V Schwelle 
aufhängt.

Nimmt man übrigens wenn es sich aufgehängt hat die Spannung wieder über 
die Schwelle (am Netzteil) startet der uC neu. Was bedeutet dass der 
Interrupt zum einlesen der Spannung noch funktionieren muss - obwohl zu 
demn Zeitpunkt über cli schon die Interrupts deaktiviert wurden... ?

Wie kann sich ein so simpler code so aufhängen?

von Peter D. (peda)


Lesenswert?

Watchdogreset?

Tip:
Man macht immer zuerst nur die Funktion.
Der Watchdog wird erst ganz zum Schluß eingebaut, wenn alle Funktionen 
einwandfrei laufen.

Bei der Entwicklung ist der Watchdog nur ne unnütze Fehlerquelle. Er 
kann sogar Fehler verschleiern.


Peter

von ?? (Gast)


Lesenswert?

ich frage mich grade, warum du nicht den brown out detector benutzt? der 
macht doch genau das, oder habe ich das falsch verstanden?

von Daniel B. (scheinleistung)


Lesenswert?

@Peter: Danke! Schalte ich den Watchdog gar nicht erst ein, tritt es 
nicht mehr auf. So, aber woran kann es liegen, wie Ihr oben seht, 
schalte ich den eigentlich kurz vorm runtefahren auch aus!?!
Jetzt mache ich den Watchdog disable noch früher schon beim 
SPannungsmessen, bringt aber nix das Problem tritt wieder auf. Und den 
Watchdog jetzt einfach ganz raus lassen möchte ich eig nicht...


@Gast: Der arbeitet ja nur mit dem uC vorgegeben Schwellen. Ich reagiere 
auf verschiedene Batterietypen!

von Peter D. (peda)


Lesenswert?

Daniel B. schrieb:
> @Peter: Danke! Schalte ich den Watchdog gar nicht erst ein, tritt es
> nicht mehr auf.

Dann wird also irgendwo vorher der Watchdog ansprechen. Und dann kannst 
Du ihn nicht eher disablen, bis das WDRF Bit gelöscht ist.

Datenblatt S.53:

"• Bit 3 - WDE: Watchdog System Reset Enable
WDE is overridden by WDRF in MCUSR. This means that WDE is always set 
when WDRF is
set. To clear WDE, WDRF must be cleared first. This feature ensures 
multiple resets during conditions
causing failure, and a safe start-up after the failure."


Peter

von Daniel B. (scheinleistung)


Lesenswert?

Das war auch das Problem. Ich bin eigentlich laut Doku davon ausgegangen 
dass das von der wdt.h auch so gehandelt wird.

Fazit:
Gelöst hab ich das Problem dann mit einer eigenen disable Funktion.
1
  wdt_reset();
2
  MCUSR &= ~(1<<WDRF);
3
  WDTCSR |= (1<<WDCE) | (1<<WDE);
4
  WDTCSR = 0x00;

von spess53 (Gast)


Lesenswert?

Hi

>Fazit:
>Gelöst hab ich das Problem dann mit einer eigenen disable Funktion.

Der WD ist normalerweise nicht aktiv. Warum hast du ihn überhaupt 
eingeschaltet?

MfG Spess

von Daniel B. (scheinleistung)


Lesenswert?

Naja meines Wissens nach macht es Sinn damit sich die Software, sollte 
Sie doch mal einen Weg ins Nirvana finden - wir Programmierer sind ja 
nicht perfekt - resettet. Ich habe permanent einen 2s WD laufen und 
resette in der main permanent.

Korrigiert mich gerne - aber das habe ich mir so angelesen.

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.