Forum: Mikrocontroller und Digitale Elektronik AT89C51ED2 + EEPROM


von Jürgen (Gast)


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

von Matthias (Gast)


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(?)

von Ralf (Gast)


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

von Jürgen (Gast)


Lesenswert?

1
//-------------------------------------------------------------------------
2
void xram_eeprom (uint adr, uint len)
3
{
4
   uint n,val,ie_save;
5
   
6
   ie_save = IE;                             // Interuptstatus sichern     
7
   IE    = 0x00;                             // alle Interrupts sperren    
8
   for (n=adr; n<len; n++)
9
   {
10
      EECON &= ~0x02;                        // XRAM Daten Mapping         
11
      val= *(uchar xdata*)n;                 // Akku mit XRAM laden        
12
      EECON |=0x02;                          // EEPROM Daten Mapping       
13
      *(uchar xdata*)n= val;                 // Akku in EEPROM schreiben    
14
      while (EECON & 0x01);                  // warten auf Busy 0          
15
   }
16
   EECON = 0x00;                             // XRAM Daten Mapping         
17
   IE    = ie_save;                          // Interruptstatus herstellen 
18
}           
19
//------------------------------------------------------------------------- 
20
void eeprom_xram (uint adr, uint len)           
21
{
22
   uint n,val,ie_save;
23
24
   ie_save = IE;                             // Interuptstatus sichern     
25
   IE    = 0x00;                             // alle Interrupts sperren    
26
   for (n=adr; n<len; n++)
27
   {
28
      EECON |=0x02;                          // EEPROM Daten Mapping       
29
      val= *(uchar xdata*)n;                 // Akku mit EEPROM laden       
30
      while (EECON & 0x01);                  // warten auf Busy 0          
31
      EECON &= ~0x02;                        // XRAM Daten Mapping         
32
      *(uchar xdata*)n= val;                 // Akku in XRAM schreiben       
33
   }
34
   EECON = 0x00;                             // XRAM Daten Mapping         
35
   IE    = ie_save;                          // Interruptstatus herstellen 
36
}       
37
//-------------------------------------------------------------------------

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

von Peter D. (peda)


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

von Jürgen (Gast)


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.

von JÜrgen G. (Firma: 4CKnowLedge) (psicom) Benutzerseite


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

von Ralf (Gast)


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

von Matthias (Gast)


Lesenswert?

Wie ist uint genau definiert?
Welches Speichermodell (Small, Large...)?

Matthias

von Matthias (Gast)


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
1
// Typendefinition
2
typedef unsigned int uint;
3
typedef unsigned char uchar;
4
5
//-------------------------------------------------------------------------
6
void xram_eeprom (uint adr, uint len)
7
{
8
   uint data n,val,ie_save;
9
   
10
   //ie_save = IE;                             // Interuptstatus sichern     
11
   //IE    = 0x00;                             // alle Interrupts sperren    
12
   EA = 0; // alle Interrupts sperren  
13
   for (n=adr; n<len; n++)
14
   {
15
      EECON &= ~0x02;                        // XRAM Daten Mapping         
16
      val= *(uchar xdata* data)n;                 // Akku mit XRAM laden        
17
      EECON |=0x02;                          // EEPROM Daten Mapping       
18
      *(uchar xdata* data)n= val;                 // Akku in EEPROM schreiben    
19
      while (EECON & 0x01);                  // warten auf Busy 0          
20
   }
21
   EECON = 0x00;                             // XRAM Daten Mapping         
22
   //IE    = ie_save;                          // Interruptstatus herstellen 
23
   EA = 1; // alle Interrupts freigeben
24
}           
25
//------------------------------------------------------------------------- 
26
void eeprom_xram (uint adr, uint len)           
27
{
28
   uint data n,val,ie_save;
29
30
   //ie_save = IE;                             // Interuptstatus sichern     
31
   //IE    = 0x00;                             // alle Interrupts sperren    
32
   EA = 0; // alle Interrupts sperren  
33
   for (n=adr; n<len; n++)
34
   {
35
      EECON |=0x02;                          // EEPROM Daten Mapping       
36
      val= *(uchar xdata* data)n;                 // Akku mit EEPROM laden       
37
      while (EECON & 0x01);                  // warten auf Busy 0          
38
      EECON &= ~0x02;                        // XRAM Daten Mapping         
39
      *(uchar xdata* data)n= val;                 // Akku in XRAM schreiben       
40
   }
41
   EECON = 0x00;                             // XRAM Daten Mapping         
42
   //IE    = ie_save;                          // Interruptstatus herstellen 
43
   EA = 1; // alle Interrupts freigeben
44
}       
45
//-------------------------------------------------------------------------

von Jürgen (Gast)


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

von Jürgen (Gast)


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

von Matthias (Gast)


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.

von Jürgen (Gast)


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

von Ralf (Gast)


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

von Jürgen (Gast)


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

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.