Forum: Mikrocontroller und Digitale Elektronik MCUCSR beim Mega8 Immer ==(1<<BORF ) | (1<<EXTRF) | (1<<PORF )


von Michael S. (schiko)


Lesenswert?

AtmelStudio 6.1
C nicht c++
AtMega8A
Int Osc 8MHz


Moin moin,

ich möchte mir die Neustartgründe des Controllers im EEProm merken
bzw hochzählen. Das funktioniert soweit auch ganz gut für
1. Forcierten Jump über den Programcode hinaus, dann ist MCUCSR==0
2. Forcierter Endlosschleife mit Watchdog, dann ist MCUCSR==(1<<WDRF )
aber mit eingeschalteter Brownout-det, bekomme ich bei jeweils
-Reset per Resetpin,
-Power off/on
-Spannung unter brownout-U Regeln
immer aller 3 Bits gesetzt, dh.:
MCUCSR ==(1<<BORF ) | (1<<EXTRF) | (1<<PORF ) ==0x07
und ohne Brownout-Fuse gesetzt immer:
MCUCSR ==             (1<<EXTRF) | (1<<PORF ) ==0x03
Mir geht es vor allem darum, eventuell Brownout-Resets im Betrieb
auf die Schliche zu kommen. Ich kann aber scheinbar an der
Spannungsversorgung und am Resetpin drehen was ich will,
ich bekomme nie separat gesetzte untere Bits.

Ich lese MCUCSR als erste Instruktion in main.
Der Staretupcode dürfte, da reines C, MCUCSR auch nicht verändern.
(btw.: Weiß jemand, wie man VOR der main mit dem AtmelStudio im
Simulator debuggen kann? Man kann zwar den Speicherort eines Breakpoint
per Hand setzen, aber anscheinend werden alle vor der main ignoriert)
Änderungen der Startuptime (8MHz + 64ms .. 8Mhz + 4ms o.ä) bringen
auch kein anderes Verhalten.

Hat jemand eine Idee/Lösung dazu, oder kennt das Phänomen?

1
uint8_t g_nLastReset;
2
..
3
int main()
4
{
5
6
   g_nLastReset = MCUCSR;
7
   EEParam_SetDefaults(&g_Param);
8
   ReadEEProm();
9
   if(g_nLastReset == 0        ) {g_Param.m_eResetCntZero____ ++; eeprom_write_byte( &EE.g_EEParam[g_eeBlockNr].m_eResetCntZero____, g_Param.m_eResetCntZero____);}
10
   if(g_nLastReset & (1<<WDRF )) {g_Param.m_eResetCntWatchDog ++; eeprom_write_byte( &EE.g_EEParam[g_eeBlockNr].m_eResetCntWatchDog, g_Param.m_eResetCntWatchDog);}
11
   if(g_nLastReset & (1<<BORF )) {g_Param.m_eResetCntBrownOut ++; eeprom_write_byte( &EE.g_EEParam[g_eeBlockNr].m_eResetCntBrownOut, g_Param.m_eResetCntBrownOut);}
12
   if(g_nLastReset & (1<<EXTRF)) {g_Param.m_eResetCntExternal ++; eeprom_write_byte( &EE.g_EEParam[g_eeBlockNr].m_eResetCntExternal, g_Param.m_eResetCntExternal);}
13
   if(g_nLastReset & (1<<PORF )) {g_Param.m_eResetCntPowerOn_ ++; eeprom_write_byte( &EE.g_EEParam[g_eeBlockNr].m_eResetCntPowerOn_, g_Param.m_eResetCntPowerOn_);}
14
   MCUCSR &= (1<<WDRF ) | (1<<BORF ) | (1<<EXTRF) | (1<<PORF );
15
..
16
   + für Testzwecke: SerielleAuagabe( g_nLastReset );

Schiko

von g457 (Gast)


Lesenswert?

Setzt Du das MCUCSR auch irgendwann zurück?

von Michael S. (schiko)


Lesenswert?

g457 schrieb:
> Setzt Du das MCUCSR auch irgendwann zurück?

Ojee, ich hätte es FAST wieder getan, wäre ich nicht zwischendurch auf 
die
Idee gekommen, testweise nur die relevanten Bits zurückzusetzen,
INCL. dem bitweisen NOT.
  MCUCSR &= ~((1<<WDRF ) | (1<<BORF ) | (1<<EXTRF) | (1<<PORF ));
Stattdessen kurz geändert in:
MCUCSR = 0;
..und es funktioniert alles wie gewünscht.

:-)
Schiko

von Michael S. (schiko)


Lesenswert?

> ..und es funktioniert alles wie gewünscht.

Genauer:
Power on/off:
alle 3Bits gesetzt, kann am Test mit VCC uber Programmer ISP liegen, 
aber egal:
MCUCSR ==(1<<BORF ) | (1<<EXTRF) | (1<<PORF )

Spannung < BrownOut:
MCUCSR ==(1<<BORF )

Resetpin Low:
MCUCSR ==(1<<EXTRF)

Watchdog-Reset:
MCUCSR ==(1<<WDRF )

Ich kann so jedenfalls alles unterscheiden :-)

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.