Forum: Mikrocontroller und Digitale Elektronik Speichern und lesen eines internen EEPROMs


von patrick (Gast)


Lesenswert?

Hallo zusammen

Ich habe ein Problem und möchte gerne eure Hilfe beanspruchen.


Ich will mit meine (Analog Devices) ADuC7060 das interne EEPROM 
verwenden.
Also habe ich im Datenblatt gelesen und auch im Internet und habe keine 
Hinweise, die mir weiter helfen könnte, gesehen.Ich möchte gern aus dem 
ADC Register (ADC0DAT) der Wert gewandelte per Tasterdruck nehmen und 
ihn im EEPROM speichern und der Wert muss dann automatisch gelesen 
werden und von aktuellen Wert des AD_Wandlers immer abgezogen. Ich habe 
es noch nie gemacht und hoffe dass ihr schon so etwas gemacht habt.
Also kann mir vielleicht jemand ein C Code Beispiel zeigen wo das EEPROM 
beschrieben und gelesen wird?
Oder sonst ein gute Seite zu diesem Problem. Denn ich habe wie es 
scheint das ganze EEPROM Zeugs noch nicht richtig Begriffen.

Ich danke euch schon einmal.

Gruss Patrick

von Anton (Gast)


Lesenswert?

Den ADuC7060 kenne ich (noch) nicht.

Beim ADuC832 z.B. ist der EEPROM Zugriff ganz einfach:
Es werden betimmte Register für die Daten, die Adresse im EEPORM
und die Funktion beschrieben. Das EEPROM-Handling läuft intern 
automatisch
ab. Dürfte beim ADuC7060 ähnlich sein, (andere AVRs z.B. machen es auch 
so)
Das Steht alles im Datenblatt, meist unter Memory-EEPROM.

von patrick (Gast)


Lesenswert?

Danke Anton,
Ich habe es von Anfang an vermutet und habe direkt die Register gesucht 
und habe versucht die zu initialisieren aber das Problem bleibt fast 
ganz weil ich keine weitere Rechnungen  machen kann. Ich möchte nämlich 
der gespeicherte Wert wieder lesen und von dem aktuellen abziehen. 
Leider ist der AD-Wandler Register nicht beeinflussbar. Ich kann also 
die Berechnung auf dieser Niveau nicht machen.

von Wadim P. (wadim)


Lesenswert?

Also, wenn ich dich richtig verstanden habe, willst du den ADC auslesen 
und diesen Wert in dem Flash/EE Speicher (also im Bereich 0x80000 bis 
0x87fff)ablegen und dann noch weitere Berechnungen machen und wieder 
ändern.

Hmmm...wieso verwendest du nicht einfach den ganz normalen SRAM 
(0x40000-0x40fff)??? Weil der Flash/EE ist ja nicht ganz so schnell und 
deshalb stehen dort immer nur die Konstanten, die niemals verändert 
werden.

Allerdings wenn du den ADC-Wert auch nach dem Reset oder dem Abschalten 
des µC verwenden möchtest, dann musst du den Wert in den ROM speichern. 
Dazu gibt es im Inet auf der Seite 
http://www.analog.com/en/analog-microcontrollers/analog-microcontrollers/aduc7060/products/code-examples/resources.html?display=popup 
eine Library, da sind auch Beispiele drin wie du den ROM löschen und 
wieberbeschreiben kannst.

Übrigens welchen Compiler verwendest du?

Also sag mir bitte Bescheid, ob unbedingt den ROM verwenden möchtest und 
dir der SRAM überhaupt nicht passt...dann können wir an dem C-Code 
arbeiten

mfg Wadim

von patrick (Gast)


Lesenswert?

Hi Wadim,
Ich arbeite mit Keil (µVision3)
Ich möchte beliebig den Wert des AD-Wandler auf Null setzen (abgleichen) 
deswegen möchte ich dieser Wert von ADC Register lesen und ihn im EEPROM 
speichern sodass dieser Wert sich nicht ändert auch wenn man das System 
abschaltet und wieder anschaltet. Dieses Verfahren möchte ich nutzen um 
mein Signal einzustellen. Es muss also im EEPROM gespeichert werden.
Ich habe verschiedene Varianten schon versucht aber komme noch nicht 
weiter.

von Wadim P. (wadim)


Lesenswert?

Also, wie schon geschrieben, im Inet findest du eine Library. Dort 
findest du eine Assemblerdatei FeeWr.s...diese kannst du in dein Projekt 
einbinden.

So...weiter kannst du nach dem gleichen Prinzip, wie in main.c vorgehen.

Du erstellst eine Konstante:
1
static const int i3 = 0x12345678;
2
const int *pi3=&i3;
und im richtigen Moment überschreibst du diese Konstante...
1
FeeWr((char*)&i3,(char*)pi3,4);

weiter kannst du die i3 ganz normal lesen und sie für deine weitere 
Berechnungen verwenden.

das wäre die einfachste Lösung (glaube ich)...

Hoffe, dass das dir weiterhilft.

mfg Wadim

von patrick (Gast)


Lesenswert?

Hallo Wadim,
ich habe leider ohne erfolg die von dir vorgeschlagene Lösung versucht. 
Ich weiß nicht warum es immer noch nicht funktioniert.Kann man diese 
Aufgabe nicht anders lösen?

von Wadim P. (wadim)


Lesenswert?

Natürlich geht es auch anders, aber ich wüsste gerade nicht wie... Ich 
sehe, dass ich in der Zeile mit FeeWr ein kleines Fehler gemacht habe. 
Da müssen die Pointer richtig eingefügt werden, aber wie das geht kann 
man ja in dem Beispiel nachschauen...

Leider kenne ich mich nicht so gut mit Keil aus, ich arbeite mit IAR, 
aber ich weiss, dass du ne Menge Einstellungen machen musst und die 
ganzen nötigen Header-Dateien einfügen sollst, um das Projekt zum Laufen 
zu bringen.

Man kann in IAR sogennante sections (ich glaube auf deutsch nennt man 
diese "Sektoren")erstellen und ihnen eine bestimmte Speicheradresse und 
Speicherweite geben. In diese sections kannst du dann deine Funktionen 
und Variablen ablegen, aber wie das in Keil geht, musst du schon selber 
im Handbuch nachlesen...ich weiss nur, wie das in IAR geht.

Ich versuch dann mal in IAR ein Projekt zu erstellen, welches dann das 
macht, was du willst... Dann schauen wir mal, wie man das unter Keil 
auch machen kann

von patrick (Gast)


Lesenswert?

Ich vermute der unterschied zwischen Keil und IAR ist nicht groß.Ich 
habe zum Beispiel einige Quellcode von Keil und IAR verglichen und habe 
keine Unterschied bei der Schreibweise gefunden.
Ich habe vorhin alles noch einmal versucht aber etwas scheint nicht gut 
zu funktionieren.
Ich habe einen Pointer auf ADC Register zeigen lassen

ADC0data_ptr = ( unsigned long*)0xFFFF051C;

dann habe ich der Wert einer Variablen zugewiesen

ulADC0Result = *ADC0dadta;
Dieser Wert habe ich versucht in EEPROM zu speichern wahrscheinlich 
läuft da etwas schief weil ich nicht mehr der gespeicherte Wert lesen 
kann.
Also wie kann ich besser ab hier dieser Wert Speichern und wieder lesen?

Danke für deine Hilfe

Gruß

patrick

von Wadim P. (wadim)


Lesenswert?

Ich habe etwas mit den FEE Registern rumexperementiert, aber bei mir 
kommt auch nicht gescheites raus. Der liefert mir später einen falschen 
Wert aus und ich verstehe nicht wieso.

Ich arbeite gerade an meinem Projekt und habe vor kurzem einen 
Bootloader geschrieben. Der soll mir Bereiche meines ROMs löschen und 
wiederbeschreiben (jeweils 512Byte), da Funktioniert alles pikobello.

Dazu habe ich noch im ROM Speicherplatz reserviert und dort paar 
konstanten abgelegt, aber das habe ich mir iar gemach und ich weiss 
nicht, wie das in Keil gemacht werden soll. Da sollte ich in so einer 
Konfigurattionsdatei rumpfuschen.

ich bin jetzt bei der Arbeit, wenn ich zu Hause bin, versuche ich 
weiter...

mfg Wadim

von patrick (Gast)


Lesenswert?

Das denke ich auch alles was hier noch stört sind diese Register 
besonders FEEDAT und FEEADR.
Z.B ist im Datasheet unter FEECON
0x01   single read:   Load FEEDAT with the 26-bit data. Indexed by 
FEEADR.
0x02   single write:  Write FEEDAT at the address pointed to by FEEADR.

Alles wird nur hier gemacht. Ich habe auch etwas gespeichert aber beim 
Lesen war nicht mehr das selbe.

Ich versuche weiter....

von patrick (Gast)


Lesenswert?

hallo zusammen,
Kann keiner also mir sagen wie ich einen Wert aus dem ADC-Register holen 
und ihn in einem internen EEPROM des ADuC7060 speichern kann?
Ich habe echt keine Ahnung mehr wie ich jetzt noch vorgehen könnte. Ich 
schätze viele arbeiten nicht mit Analog Devices.
Falls jemand eine Idee hat kann er immer weiter geben vielleicht hilft 
das

danke

patrick

von Wadim P. (wadim)


Lesenswert?

Also...ich habe gestern Paer Sachen probiert und habe versucht mich mit 
dem Keil vertraut machen, aber ohne Erfolg. Wie schon geschrieben ich 
habe in IAR fast das Gleiche gemacht, was du brauchst. In IAR gibt es so 
eine Linker-Datei ADuC7060Ex.icf dort kannst du dein Speicher verwalten 
und dir Speicherbereiche für Konstanten und Funktionen reservieren.

Ich habe für meine Zwecke im hinteren Teil des ROMs einen Speicherplatz 
von 512Byte reserviert und dort Paar Daten abgelegt. Dann wenn ich diese 
Daten brauche zu ändern, strate ich meinen selbstgeschriebenen 
Bootloader und überschreibe dieses Segment.

Finde eine Möglichkeit, wie du in Keil den Speicherplatz reservieren und 
dort einige deiner Daten ablegen kannst. Sagen wir mal bei der 
Startadresse 0x87600 und Länge von 512Byte also 0x200. Dann kannst du 
mit den Funktionen FeeClr und FeeWr weiterarbeiten.

Hier ist ein Ausschnitt meines Bootloaders
da sendet der PC, welche Option gewählt werden soll. Für dich sin 0x04 
und 0x05 relevant.
1
static volatile unsigned char  uartFlash[512]; //Speicher für die Daten
2
unsigned char segment=0; //Nummer des zu beschreibenden Segments (0..63)
3
...
4
5
case 0x04: //Flashe Segment x
6
          while((COMSTA0&BIT0)!=BIT0){} //Wartet auf Nummer des Segmentes (0..63)
7
          segment=COMRX; 
8
          FeeClr((char*)(0x80000+(segment*0x200)),(char*)(0x80000+(segment*0x200))); //Lösche Segment x
9
          FeeWr((char*)(0x80000+(segment*0x200)),(char*)&uartFlash[0],512); //Flashe Segment x
10
          COMTX = 0x90; //synchronisation mit PC
11
          while ((COMSTA0 & 0x40) == 0x00){}
12
        break;
13
        
14
      case 0x05: //Vergleich Flash mit Data
15
        while((COMSTA0&BIT0)!=BIT0){} //Wartet auf Nummer des Segmentes (0..63)
16
        segment=COMRX;
17
        checksum=0;
18
        i=0;
19
        FEEADR=(segment*0x200); 
20
        while(i<512){
21
          FEEADR=(segment*0x200)+i;
22
          FEECON=0x01; //Daten aus Adresse FEEADR lesen
23
          checksum=checksum^FEEDAT; //LSByte von FEEDAT
24
          checksum=checksum^(FEEDAT>>8); //MSByte von FEEDAT
25
          ++i;++i;
26
        }
27
        COMTX = checksum; //checksumme an PC senden
28
        while ((COMSTA0 & 0x40) == 0x00){} //wartet bis Byte gesendet
29
        break;
30
...

man soll immer mit 512Byte Blöcken arbeiten, da das ganze Speicher in 
sogenannte "pages" unterteilt ist.


Ich habe noch ein Verdacht,dass vor dem Screiben in den ROM die Daten 
dort erstmal gelöscht werden sollen. Also vor dem FEECON=0x02; muss eine 
FEECON=0x05; ausgeführt werden.

Du musst unbedingt darauf achten, welche page du löschst, weil dort 
eventuell noch dein Programmcode befinden kann, deshalt habe ich dir 
oben vorgeschlagen die Speicheradresse 0x87600 zu nehmen.

So...das wäre dann der grobe Überblick, bei weiteren Problemen oder 
Feinheiten frag mich einfach.


mfg Wadim

von patrick (Gast)


Lesenswert?

Das hier soll ein Programm, das gut funktioniert aber was dieses 
Programm macht ist noch nicht was ich haben möchte.

*********************************************************************/
#include <ADuC7026.h>
#define PROTECT 0

extern int write (int file, char * ptr, int len);  // Function used to 
write string
void delay (int length);
void erase_page(unsigned short int addr);
void save(unsigned short int addr, unsigned char data);
void protect_page(unsigned int addr);
unsigned short load(unsigned short int addr);
unsigned short SingleVerify(unsigned short int addr, unsigned char 
data);
void senddata(short);
char hex2ascii(char);
unsigned char ERROR;
unsigned int status, uiTest, uiTest1, uiTest2;
unsigned short ucVerifyTest = 0;

unsigned int * data_ptr;
int main(void)
{
  unsigned char count = 0;
  unsigned int i = 0;
  char output[7] = "Error\n";
  ERROR = 0;

  GP1CON = 0x011;           // Setup tx & rx pins on P1.0 and P1.1

   // Start setting up UART at 9600bps
  COMCON0 = 0x80;        // Setting DLAB
  COMDIV0 = 0x88;        // updated for rev H
     COMDIV1 = 0x00;
     COMCON0 = 0x07;        // Clearing DLAB

  GP4DAT = 0x04000000;    // configure P4.2 as output
  FEEMOD = 0x8;        // bit 3 should be set to allow erase/write 
command
  data_ptr = (unsigned int *)0x00080448;
  uiTest = *data_ptr;
  delay(20);
  data_ptr++;
  uiTest1 = *data_ptr;
    delay(20);
    data_ptr++;

  uiTest2 = *data_ptr;
    delay(20);
if (PROTECT){          // if it is not protected yet

  erase_page(0xF000);        // erase page 120

  for (i=0;i<10;i++) {
    count ++;        // save numbers
      save(0xF000+2*i, count);
  }

  for (i=0;i<10;i++){      // Output Data
       senddata (load(0xF000+2*i));
  }

  protect_page(0xBFFFFFFF);   // protect pages
  RSTSTA = 0x02;         // software reset
}
else{
    erase_page(0xE000);        // erase page 120
  erase_page(0xF000);        // erase page 120

  erase_page(0xF200);        // erase page 121
  erase_page(0xF400);        // erase page 122

  count = 0xA;

  if (ERROR){
    write(0,output,7);    // Output Error message
  }
  else{
    for (i=0;i<10;i++){       // Save data
      save(0xE000+2*i, 0x77);

    }

    for (i=0;i<10;i++){       // Save data
      save(0xF000+2*i, count);
      count --;
    }
    for (i=0;i<10;i++) {
    count ++;        // save numbers
      save(0xF200+2*i, 0x55);
    }
    for (i=0;i<10;i++) {
    count ++;        // save numbers
      save(0xF400+2*i, 0xAA);
    }

    for (i=0;i<10;i++) {
    count ++;        // save numbers
      save(0xF300+2*i, count);
    }
     for (i=0;i<10;i++){           // Output Data
        senddata (load(0xE000+2*i));
    }

    for (i=0;i<10;i++){           // Output Data
          senddata (load(0xF000+2*i));
    }
    for (i=0;i<10;i++){      // Output Data
     senddata (load(0xF400+2*i));
    }
  }
  ucVerifyTest =  SingleVerify( 0xF300+4, 0x0003);
  protect_page(0xBFF00000);   // protect pages 120-123

  RSTSTA = 0x02;         // software reset
  while (1){
    GP4DAT ^= 0x00040000;    // complement P4.2
    delay(100000);
  }

  }

  return 0;
}

void delay (int length) {    // delay
  while (length >= 0)
      length--;
}

void protect_page(unsigned int addr){
  FEEADR = 0x1234;           // Key
  FEEDAT = 0xA5A5;          // Key
  FEEPRO = addr;
  FEEMOD = 0x48;
  FEECON = 0x0C;
  status = FEESTA&0x03;
  while (!(status)) status = FEESTA&0x03;
  if ((status&0x02)==0x02) //ERROR = 1;
  return;                // return
}


unsigned short load(unsigned short int addr){
  FEEADR = addr;
  FEECON = 0x01;        // single read command
  status = FEESTA&0x03;
  while (!(status)) status = FEESTA&0x03;
  if ((status&0x02)==0x02) ERROR = 1;
  return (FEEDAT);
}


void save(unsigned short int addr, unsigned char data){
  FEEADR = addr;        // set data address
  FEEDAT = data;        // set data value
  FEECON = 0x02;        // single Write command
  status = FEESTA&0x03;
  while (!(status)) status = FEESTA&0x03;
  if ((status&0x02)==0x02) ERROR = 1;
  return;
}

unsigned short SingleVerify(unsigned short int addr, unsigned char 
data){
  FEEADR = addr;        // set data address
  FEEDAT = data;        // set data value
  FEECON = 0x04;        // single verify command
  status = FEESTA&0x03;
  while (!(status)) status = FEESTA&0x03;
  if ((status&0x02)==0x02) ERROR = 1;
  return (status);
}

void erase_page(unsigned short int addr){
  FEEADR = addr;        // set data address
  FEECON = 0x05;        // erase page command
  status = FEESTA&0x03;
  while (!(status)) status = FEESTA&0x03;
  if ((status&0x02)==0x02) ERROR = 1;
   return;
}

void senddata(short to_send){
  while(!(0x020==(COMSTA0 & 0x020))){}
    COMTX = 0x0A;            // output LF
  while(!(0x020==(COMSTA0 & 0x020))){}
    COMTX = 0x0D;            // output CR
  while(!(0x020==(COMSTA0 & 0x020))){}
    COMTX = hex2ascii ((to_send >> 8) & 0x0F);
  while(!(0x020==(COMSTA0 & 0x020))){}
    COMTX = hex2ascii ((to_send >> 4) & 0x0F);
  while(!(0x020==(COMSTA0 & 0x020))){}
    COMTX = hex2ascii (to_send & 0x0F);
}


char hex2ascii(char toconv){
  if (toconv<0x0A) toconv += 0x30;
  else toconv += 0x37;
  return (toconv);
}

von patrick (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute,
ich habe bis jetzt das gewünschte Ergebnis noch nicht erzielen können 
obwohl es einfach scheint.
Ich habe zuerst ein Problem mit einem Interuppt (external interuppt). Er 
wird durch eine Taste eingelöst und ich möchte es anwenden um das 
Speichern der Werte im EEPROM zu bewirken.

Das Speichern der Werte klappt auch nur halbs Weg
wenn ich etwas speichere, bekomme ich beim Lesen nur die 4 letzten 
Charater.

kann jemand mir sagen wie ich es besser hinbekommen kann.

von patrick (Gast)


Lesenswert?

Hallo zusammen,
ich habe schon gefunden wie ich ein Wert im EEPROM speichern kann. Aber 
kaum löst man ein Problem,taucht ein neues auf. Ich merke jetzt dass der 
EEPROM-Register nur 16bit groß ist und die Wert, die ich speichern 
möchte 24bit codiert sind. Also ich bekomme nur die 16bit wieder beim 
Lesen.
Kamm man mir sagen wie ich das lösen kann.

Danke!!

mfg

pat....

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.