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
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.
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.
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
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.
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
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?
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
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
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
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....
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
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
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); }
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.