Forum: Mikrocontroller und Digitale Elektronik AVR hängt sich auf bei Unterspannung während EEPROM-Schreibzugriff


von Marc (Gast)


Lesenswert?

Hallo,

für eine Applikation verwende ich einen Atmel ATMEGA64A bei einer 
Betriebsspannung von 5.0 V. Die Brown-Out-Detection ist aktiviert und 
für 4.0 V konfiguriert.

Leider passiert es trotzdem, dass sich der Controller bei Unterspannung 
während eines EEPROM-Schreibzugriffs aufhängt.
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
4
#define EEPROM_BUFFER_SIZE      128
5
#define EEPROM_BUFFER_MASK      ( EEPROM_BUFFER_SIZE - 1 )
6
7
static volatile uint16_t s_eepromBuffAdr [EEPROM_BUFFER_SIZE];
8
static volatile uint8_t s_eepromBuffData [EEPROM_BUFFER_SIZE];
9
static volatile uint8_t s_eepromHead = 0;
10
static volatile uint8_t s_eepromTail = 0;
11
12
ISR ( EE_READY_vect )
13
{
14
  uint8_t tmptail = 0;
15
  
16
  if ( s_eepromHead != s_eepromTail )
17
  {
18
    // calculate and store new buffer index
19
    tmptail = ( s_eepromTail + 1 ) & EEPROM_BUFFER_MASK;
20
    s_eepromTail = tmptail;
21
    // get one byte from buffer and write it to EEPROM
22
    EEAR = s_eepromBuffAdr [tmptail];   // address
23
    EEDR = s_eepromBuffData [tmptail];  // data   
24
    // master write enable
25
    EECR |= (1<<EEMWE);   
26
    // strobing eeprom write
27
    EECR |= (1<<EEWE);
28
  }
29
   
30
  else
31
  {   
32
    // disabling eeprom ready interrupt
33
    EECR &= ~(1<<EERIE);
34
  }
35
}
36
37
void eeprom_write_byte_isr ( uint8_t *dst, uint8_t src )
38
{
39
  uint8_t tmphead = 0;
40
41
  tmphead  = ( s_eepromHead + 1 ) & EEPROM_BUFFER_MASK;
42
43
  while ( tmphead == s_eepromTail );    // waiting for free space buffer
44
45
  s_eepromBuffAdr [tmphead] = (uint16_t) dst;
46
  s_eepromBuffData [tmphead] = src;
47
  s_eepromHead = tmphead;
48
49
  EECR |= (1<<EERIE);                   // enable interrupt
50
}

Für Ideen und Kommentare bin ich dankbar.

Gruß Marc

von Volker (Gast)


Lesenswert?

Ich frag mal vorsichtig gegen:
Was sollte der AVR bei Unterspannung deiner Meinung nach sonst machen?
Einfach weiterlaufen? :-)

von Marc (Gast)


Lesenswert?

Volker schrieb:
> Ich frag mal vorsichtig gegen:
> Was sollte der AVR bei Unterspannung deiner Meinung nach sonst machen?
> Einfach weiterlaufen? :-)

Da habe ich mich wohl etwas ungeschickt ausgedrückt. Der 
Spannungseinbruch ist nur von kurzer Dauer. Normalerweise sollte der 
Brown-Out-Detector den Controller bei Spannungseinbruch zurücksetzen. Im 
konkreten Fall bleibt er aber stehen. Aktuell umgehe ich dieses Problem, 
indem ich den internen Watchdog aktiviere.

von Volker (Gast)


Lesenswert?

Du meinst also daß die BOD nicht anspricht und der Controller im
1
while ( tmphead == s_eepromTail );

hängen bleibt?

von Marc (Gast)


Lesenswert?

Volker schrieb:
> Du meinst also daß die BOD nicht anspricht und der Controller im
> while ( tmphead == s_eepromTail );
>
> hängen bleibt?

Korrekt. Wobei ich bisher noch nicht prüfen konnte ob der Controller 
genau an dieser Stelle hängen bleibt.

Andere Timer-Interrupts (z.B. ein 10-ms-Timer) werden auch nicht mehr 
ausgeführt.

von Peter D. (peda)


Lesenswert?

Marc schrieb:
> Andere Timer-Interrupts (z.B. ein 10-ms-Timer) werden auch nicht mehr
> ausgeführt.

Das riecht stark danach, als ob der Fehler im nicht gezeigten Code 
liegt.

Kannst Du nicht ein ausführbares hängendes Programm zeigen?
Mit nur 2 Schnipselchen kann man nichts anfangen.

von Marc (Gast)


Lesenswert?

Leider läßt sich der Fehler nicht mehr reproduzieren.

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.