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
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(?)
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
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
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
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.
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
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
Wie ist uint genau definiert? Welches Speichermodell (Small, Large...)? Matthias
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 | //-------------------------------------------------------------------------
|
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
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
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.
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.