Forum: Mikrocontroller und Digitale Elektronik ATmega8 Timer0- / EEPROM-Fehler


von Simon K. (Gast)


Angehängte Dateien:

Lesenswert?

Hi,
ich habe da zwei Probleme bei denen ich nicht mehr weiter komme.
Die Suchfunktion habe ich natürlich schon versucht, kam aber leider 
nicht zu einer Lösung.

Es geht um ein Programm für eine Datenübertragung von einem ATmega8A 
über UART, zu einem PC mit Labview und geschrieben habe ich das ganze in 
C mit Atmel Studio 6.1 und zur Verwendung kommt das MyAVR M2-Board.

1. Timer0 einstellen: Soll im 20ms Takt einen Interrupt auslösen, eine 
Messung machen und diese im EEPROM ablegen. Danach auf den nächsten 
Interrupt warten und das ganze wiederholen, bis der EEPROM voll ist.
Der µC-Takt ist übrigens 3.686.400MHz und der Prescaler auf 1024.

Dies sollte also ca 10,24s dauern... tut es aber nicht. Selbst wenn ich 
den Startwert des Timers zwischen 0 und 255 variiere, dauert die ganze 
Prozedur, scheinbar unabhängig davon nur ca. 4s. Bei Tests mit einem 
anderen Prescaler waren allerdings Änderungen feststellbar.

2. EEPROM schreiben (in Timer0 ISR): Soll komplett mit den erfassten 
Daten voll geschrieben werden.
Das Problem hier ist, das er scheinbar nicht den gesamten Adressbereich 
ausschöpft. Ab ca. Stelle 144 wird nur noch der Wert 255 an den PC 
übertragen. Als ich den EEPROM ausgelesen habe, war auch ab dieser 
Stelle kein Eintrag mehr vorhanden. Nicht mal eine 0 / 255 oder 
dergleichen...

Das restliche Programm tut genau das was es soll und zeitlich dürfte 
sich auch nicht in de Weg kommen, da ich zu Beginn Test gemacht habe wie 
lange die einzelnen Programmteile/Befehle benötigen und dementsprechend 
Zeitreserven vorgesehen sind.
Mir ist bewusst, dass es nicht die feine Art ist den EEPROM in einer ISR 
zu beschreiben, allerdings tut sich zu dieser Zeit sonst nichts 
nennenswertes im Programm was dadurch gestört werden könnte und die 
Abstände der Messungen möglichst gleich sein.

Ausprobiert habe ich schon folgendes:
- Variiren des Timer Startwertes und Prescaler
- Ändern des zu schreibenden Adressbereichs
- diverse Code-Schnipsel zu Timer und EEPROM verwendet
- Code-Optimierungen in verschiedenen Einstellungen getestet
- zweites Board benutzt
- einen ATmega8L statt ATmega8A verwendet
- ...

Da ich mittlerweile nicht mehr weiter komme und nicht weiss was ich noch 
falsch gemacht haben könnte, wäre es klasse, wenn mir jemand dabei 
helfen könnte.

Hochachtungsvoll :-)
SimonK

von holger (Gast)


Lesenswert?

Mit einer globalen Variablen namens "i" kann man sich eigentlich
nur noch den Arsch abwischen.

von H.Joachim S. (crazyhorse)


Lesenswert?

ISR(TIMER0_OVF_vect)  //Messwerte in EEPROM-Modus ermitteln
{
  UCSRB &= ~(1<<RXCIE);        //Interrupts für UART deaktivieren
  while (i<=511)            //bis EEPROM beschrieben ist
  {
    Messwert = AD_Wandlung();
    Herzschlag(Messwert);
    EEPROMschreiben(Messwert, i);
    PORTB ^= (0<<1);        //EEPROM-LED toggeln
    i++;              //Index hochzählen
  }
  if (i>=511)              //wenn EEPROM beschrieben ist
  {
    UCSRB |= (1 << RXCIE);      //Interrupts für UART aktivieren
    TIMSK &= ~(1<<TOIE0);      //Interrupts für Timer-Overflow 
deaktivieren
  }
}

Das tut schon mal nicht, was du dir erhoffst.
Der EEPROM wird nicht bei jedem Timerinterrupt einmal beschrieben, 
sondern direkt bei ersten Aufruf komplett (while (i<=511)...)

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.