mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AT89C51ED2 + EEPROM


Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich habe gerade folgendes Problem:
Ich habe ein Programmteil das Daten aus dem EEPROM des AT89C51ED2 liest 
und ins XRAM der CPU speichtert. Mit dem Prozessortyp im PLCC68 Gehäuse 
funktioniert das Problemlos. Wenn ich jedoch den gleichen CPU-Typ im 
PLCC44 Gehäuse verwende hängt sich dieser beim zugriff aufs EEPROM auf. 
Wenn ich diesen Progammteil entferne ist alles OK. Es handelt sich bei 
beiden Ausführungen um den ..ED. Typ mit int. EEPROM. Ich habe auch 
schon das Register EECON nochmal mit den Resetzuständen xxxx xx00b 
initialisiert aber ohne Erfolg. Hat von Euch jemand eine Idee?
Gruß Jürgen

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du den Fehler schon gefunden? Wäre mal von Intresse, woran es lag. 
Mir sind außer den zusätzlichen Ports, keine Unterschiede zwischen 
PLCC68 und PLCC44 Version bekannt. Möglicherweise sind in beiden sogar 
die gleichen Chips verbaut(?)

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

poste doch bitte mal deinen Code. Arbeitest du über die interne API oder 
über selbstgebastelte Routinen? Bei Verwendung der API zum Schreiben 
steht etwas im Errata-Sheet, dass es den Controller durcheinanderbringen 
kann. Es steht nicht beschrieben, ob es eine bestimmte Gehäusevariante 
betrifft, aber ich kann mir vorstellen, dass evtl. die längeren 
Bonding-Drähte im größeren Gehäuse schon ausreichen, um den Fehler zu 
verursachen.

Ralf

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
//-------------------------------------------------------------------------
void xram_eeprom (uint adr, uint len)
{
   uint n,val,ie_save;
   
   ie_save = IE;                             // Interuptstatus sichern     
   IE    = 0x00;                             // alle Interrupts sperren    
   for (n=adr; n<len; n++)
   {
      EECON &= ~0x02;                        // XRAM Daten Mapping         
      val= *(uchar xdata*)n;                 // Akku mit XRAM laden        
      EECON |=0x02;                          // EEPROM Daten Mapping       
      *(uchar xdata*)n= val;                 // Akku in EEPROM schreiben    
      while (EECON & 0x01);                  // warten auf Busy 0          
   }
   EECON = 0x00;                             // XRAM Daten Mapping         
   IE    = ie_save;                          // Interruptstatus herstellen 
}           
//------------------------------------------------------------------------- 
void eeprom_xram (uint adr, uint len)           
{
   uint n,val,ie_save;

   ie_save = IE;                             // Interuptstatus sichern     
   IE    = 0x00;                             // alle Interrupts sperren    
   for (n=adr; n<len; n++)
   {
      EECON |=0x02;                          // EEPROM Daten Mapping       
      val= *(uchar xdata*)n;                 // Akku mit EEPROM laden       
      while (EECON & 0x01);                  // warten auf Busy 0          
      EECON &= ~0x02;                        // XRAM Daten Mapping         
      *(uchar xdata*)n= val;                 // Akku in XRAM schreiben       
   }
   EECON = 0x00;                             // XRAM Daten Mapping         
   IE    = ie_save;                          // Interruptstatus herstellen 
}       
//-------------------------------------------------------------------------

Hallo
das sind die beiden Routinen mit denen ich die Daten vom XRAM ins EEPROM 
und umgekehrt schreibe. Zur Verwendung der beiden CPU-Ausführungen noch 
folgender Hinweis:
Ich verwende einen BRENDES Emulator und will in der Singlechipausführung 
die sogenannten Softhooks zur Emulation von P0 und P2 umgehen.
Dazu habe ich mir ein eigenes POD gebaut bei dem ich die 68polige CPU 
verwende. P0 und P2 spendiere ich dem Emulator. Ich habe dann in den 
entspechenden Headerdateien die Adressen von P4 und P5 auf P0 und P2 
umgebogen.Natürlich ist es auch Hardwaremäßig so das Pund P% an den 
physikalischen Pins von P0 und P2 liegen. Wenn die Sofware fertig ist 
wird für die eigendliche Anwendung in der 44pol. CPU diese Manipulation 
rückgängig gemacht. Ich verwende dieses POD schon seit 2 Jahren ohne das 
bisher Probleme auftauchten.
Da hier keine Externen Leitungen verwendet werden habe ich bisher noch 
keine Erklärung. Wie gesagt am Emulator läuft alles einwandfrei.

Gruß Jürgen

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Code ist äußerst seltsam.
Du schreibst auf die gleiche Adresse im SRAM, wie im EEPROM. Vielleaicht 
zerhaust Du Dir dabei irgendwelche Variablen. Oder Du schreibst auf 
Adressen, wo gar kein EEPROM ist.

Für Kopierroutinen nimmt man immer 2 Pointer (Zieladresse, 
Quelladresse).

Das Busy-Waiting beim Lesen ist witzlos.

Stell dochmal fest, wo genau sich das Programm aufhängt.

Hängts nur im Emulator oder auch im real Life?


Peter

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter,
XRAM und EEPROM liegen im gleichen Adressraum und werden im 
EECON-Register durch das Bit EEE selektiert bzw. umgeschaltet. Daher 
kann der Datenpointer auf die gleiche Adresse zeigen. Den Code habe 
weitgehenst von der Atmel Apnote übernommen. Wenn ich feststellen könnte 
wo das Programm hängt hätte ich schon gewonnen. Im Emulator läuft es 
problemlos und alle Register haben korekte Werte.

Autor: JÜrgen Grieshofer (Firma: 4CKnowLedge) (psicom) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jürgen wrote:
> Wenn ich feststellen könnte
> wo das Programm hängt hätte ich schon gewonnen.


Wieso lädst du dir keinen Debugger runter? Einfach Breakpoint setzen und 
gut is xP

Vllt wenn du nur den Teil mit dem EEPROM testen willst, könnte ich dir 
auf die schnelle Keil µVision raten... Ist in der Testversion auf 4k 
beschränkt, aber es liefert alles was du zum knacken deines Problems 
brauchst xP

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann es sein, dass die Variablen volatile sein müssen, da der Compiler 
sonst evtl. meint, dass du in den gleichen Speicher schreibst und das 
ganze deswegen wegoptimiert? Das widerspricht zwar der Aussage, dass es 
mit dem anderen µC funktioniert, aber wer weiss...

Ralf

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie ist uint genau definiert?
Welches Speichermodell (Small, Large...)?

Matthias

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe Dein Programm mal auf meinen AT89C51ED2 im PLCC-44 getestet, es 
läuft. Eine kleine Anpassung habe ich vorgenommen: Alle Variablen und 
auch die Zeiger selber liegen jetzt im internen RAM, unabhängig vom 
Speichermodell. (Während der Routine darf keine Variable im XRAM 
liegen!)

Kontrolliere mal die Einstellung des AUXR-Registeres. Nach dem Reset ist 
nicht der gesamte XRAM aktiv, nur 768 Byte. Musst erst XRS2/1/0 richtig 
setzen. Auch könnte das EXTRAM bit falsch gesetzt sein.

Matthias
// Typendefinition
typedef unsigned int uint;
typedef unsigned char uchar;

//-------------------------------------------------------------------------
void xram_eeprom (uint adr, uint len)
{
   uint data n,val,ie_save;
   
   //ie_save = IE;                             // Interuptstatus sichern     
   //IE    = 0x00;                             // alle Interrupts sperren    
   EA = 0; // alle Interrupts sperren  
   for (n=adr; n<len; n++)
   {
      EECON &= ~0x02;                        // XRAM Daten Mapping         
      val= *(uchar xdata* data)n;                 // Akku mit XRAM laden        
      EECON |=0x02;                          // EEPROM Daten Mapping       
      *(uchar xdata* data)n= val;                 // Akku in EEPROM schreiben    
      while (EECON & 0x01);                  // warten auf Busy 0          
   }
   EECON = 0x00;                             // XRAM Daten Mapping         
   //IE    = ie_save;                          // Interruptstatus herstellen 
   EA = 1; // alle Interrupts freigeben
}           
//------------------------------------------------------------------------- 
void eeprom_xram (uint adr, uint len)           
{
   uint data n,val,ie_save;

   //ie_save = IE;                             // Interuptstatus sichern     
   //IE    = 0x00;                             // alle Interrupts sperren    
   EA = 0; // alle Interrupts sperren  
   for (n=adr; n<len; n++)
   {
      EECON |=0x02;                          // EEPROM Daten Mapping       
      val= *(uchar xdata* data)n;                 // Akku mit EEPROM laden       
      while (EECON & 0x01);                  // warten auf Busy 0          
      EECON &= ~0x02;                        // XRAM Daten Mapping         
      *(uchar xdata* data)n= val;                 // Akku in XRAM schreiben       
   }
   EECON = 0x00;                             // XRAM Daten Mapping         
   //IE    = ie_save;                          // Interruptstatus herstellen 
   EA = 1; // alle Interrupts freigeben
}       
//-------------------------------------------------------------------------

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
erstmal vielen Dank für Eure Antworten,ich war übers Wochenende nicht 
Zuhause und es ist erst mal nichts mehr gelaufen.

@Ralf: wenn ich mir mit dem Emulator den übersetzten ASM-Code anschaue 
ist soweit alles i.o.

@Matthias: alle lokalen Variablen sind vom Speichertyp Small. Das AUXR 
Register habe initialisiert auf 1792 Bytes ( obwohl ich nur 200 Bytes 
brauche) und der Zugriff aufs Int.XRAM freigeben.

Ich habe langsam den Verdacht das mit den CPU's was faul ist 
möglicherweise RD statt ED Typen.

Leider komme ich diese Woche nicht mehr dazu weiterzumachen (ist ein 
Privatvergnügen :-) )ich werde mal versuchen ein paar neur CPU's 
aufzutreiben. Ich melde mich wieder wenn ich neue Erkenntnisse habe.

Gruß Jürgen

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich bin erst heute wieder dazugekommen an der Steuerung weiterzumachen 
und bin dabei auf ein ganz anderes Problem gestossen. Ich hatte vermutet 
das das Programm an der Stelle wo auf das EEPROM zugegriffen wird hängt. 
In diesen Feler hatte ich mich verrannt weil das Programm mit nur 
geringfügiger Änderung (auskommentieren des Busyflags EECON) auf einem 
AT89C55 problemlos läuft. Der Zugriff aufs int. XRAM geht natürlich ins 
Nirvana:-) . Wenn ich den AT89C51ED2 einsetze geht garnichts d.h. der 
Controller macht nichts! Programmiert hat ihn mir ein Kollege mit dem 
GALEP4. Wir haben das mehrfach ausprobiert. Ich habe mir das ALE-Signal 
angeschaut da ist alles OK abernach einem Reset wird kein Befehl 
ausgeführt. Hat jemand von Euch dazu eine Vermutung?
Gruß Jürgen

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da wird Hilfe schwer. Eine Ursache könnte ein falsch gesetztes BLJB-Bit 
im AT89C51ED2 sein. Dann startet nach Reset nicht Dein Programm sondern 
der Bootloader (Auslieferungszustand!).

Wenn Du die Möglichkeit hast, programmier mal seriell über den internen 
Bootloader mit FLIP-Software.

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Matthias,
ich bin dabei die Schaltung so zu modifizieren das ich an PSEN und Reset 
herankomme. Ich werde es mit dem Bootlader probieren. Danke
Gruß Jürgen

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Jürgen,

achte darauf, dass du nicht direkt auf LOW ziehst, sondern über einen 
PullDown-Widerstand (ALE ist normalerweise ein Ausgang), sonst könntest 
du den µC zerstören. Ich meine, der Reset ist auch bidirektional, aber 
das weiss ich grad nicht sicher.

Ralf

Autor: Jürgen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

@Matthias, bingo das BLJB Bit war's, wir haben im GALEP Programmer die 
Stelle gefunden wo dieses Bit gesetzt bzw. gelöscht wird. Funktioniert 
jetzt alles einwandfrei.
@Ralf, ich habe eine Schaltung gefunden die dies berücksichtigt.

Danke noch an alle gruß Jürgen

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.