AVR hängt sich auf bei Unterspannung während EEPROM-Schreibzugriff

Gast #3747473
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
Gast #3747514
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.
Gast #3747535
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.

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.