www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AT89C51AC3 internes EEPROM


Autor: Michael Heydeck (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich hab mal eine Frage. Ich bin µC neuling und will gerade einen alten 
Verstärker den ich mal gebaut habe "modernisieren".
Ich möchte die Lautstärke, den Bass, die Höhen und die Balance digital 
verstellen und mit Hilfe eines µC auf dem Display anzeigen und 
abspeichern.
Ich hab mir dafür den AT89C51AC3 ausgesucht weil der ein internes 2k 
EEPROM hat.
Mein Problem ist jetzt das ich die Werte nicht speichern kann. Ich will 
es über einen externen Interrupt steuern können, sprich der Interrupt 
kommt und die Werte werden abgespeichert. Der Interrupt wird von einem 
Supervisor IC gesteuert der die Betriebsspannung überwacht und bei einem 
Einbruch sofort den PFO schaltet.
Ich habe mir ein Application Note von Atmel für den µC besorgt und die 
Ansteuerung daraus abgeschrieben.
Das laden der Werte aus dem EEPROM geht jedoch. Ich bekomme immer 0xFF 
nach jedem neustart des µC.
Der Interrupt selber funktioniert auch. Es muss also an der Funktion für 
das Schreiben des EEPROMs liegen.
Habe mal die gesamte Routine kopiert und etwas umgeändert nach meinen 
Anforderungen.
Interruptroutine steht folgendes:

void PowerFail(void) interrupt 0 {
    wr_eeprom_byte(0,volume);
    wr_eeprom_byte(1,bass);
    wr_eeprom_byte(2,treble);
    wr_eeprom_byte(3,balance);
}

Ich hoffe ihr könnt mir helfe.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist EXTRAM Bit im AUXR Register korrekt gesetzt? Ansonsten sieht Deine 
Routine ok aus.

Autor: Michael Heydeck (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Davon habe ich schon gelesen in anderen Beiträgen. Mir ist aber nicht so 
richtig klar wo ich es setzen muss. Ob es in der Funktion zum schreiben 
stehen muss oder schon in einem Headerfile bzw. am Anfang meines 
Hauptfiles.
Deswegen weiß ich leider nicht ob es gesetzt ist.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könnte es auch sein, das die Zeit bis zum totalen Spannungsausfall nicht 
mehr ausreicht um die Schreibvorgänge zu beenden?

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
EXTRAM muss 0 sein, sonst greifst Du nicht auf den internen XDATA 
(EEPROM oder RAM) zu, sondern auf den externen XDATA über P0/P2.

Autor: Michael Heydeck (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich teste es momentan auf einem Evulationsboard in dem ich den Interrupt 
"manuell" betreibe.

Wo muss ich dieses Bit setzen? In meiner Schreibroutine oder von dem 
Punkt aus von dem ich auf die Routine zu greife?

Danke schon mal für die Tips, jetzt kann ich wieder n bissele googlen ;)

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kommt auf Dein System an, ob externer XDATA Speicher genutzt wird oder 
nicht. Standardmäßig sollte es aber auf 0 sein.

Hast Du die Routinen mal ohne den Interrupt und bei normaler Spannung 
ausprobiert? Sind dann nach dem Aus- und Einschalten die Werte noch im 
EEPROM?

Autor: Michael Heydeck (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Matthias,
jetzt hab ich es zum laufen gebracht.
Das EXTRAM Bit war standard mäßig auf 0, daran lag es also nicht.
Ich habe auch versucht die Routine ins Main zu setzen und ohne den 
Interrupt auslösen zu lassen. Hat auch nicht funktioniert.

Habe dann nochmal einen genauen Blick ins Datenblatt geworfen und 
entdeckt das das eigentlich schreiben erst mit den Befehlen 0x50 und 
sofort hinter her 0xA0 ins EECON register funktioniert. Sprich also in 
Atmels Application Note war nicht alles enthalten.

Mit den Zeilen vorher wird wohl nur ein Latch geladen mit den Daten und 
der Adresse wo sie hin sollen und mit den beiden Befehlen der 
Schreibvorgang ausgelöst.

void wr_eeprom_byte(unsigned int adr, unsigned char value){
   bit ea_save;
   while(EECON & 0x01);
   ea_save = EA;
   EA = 0;
   EECON |= 0x02;
   *(unsigned char xdata*)adr = value;
   EECON &= ~0x02;
   EECON &= 0x50;
   EECON &= 0xA0;
   EA = ea_save;
}

Das ist die komplette schreibroutine die bei mir ohne Probs funzt... 
auch mit Interrupt.

Danke für die Hilfe :)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fürs nächste mal:

Was soll denn dieser Unsinn?

Wenn Du Dich dazu bequemen könntest, einen Sourcetext vernünftiger Weise 
als *.c zu posten, dann könnt ich ihn mir mal ansehen.

Programmierer gucken sich Sourcen grundsätzlich nur in ihrem 
Lieblingseditor an, weil man da Fehler am besten erkennt.


Peter

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja stimmt, 0x50 + 0xA0 nach EECON löst erst den Schreibbefehl aus. Ein 
kleiner, aber feiner Unterschied zum gängigeren AT89C51ED2.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.