Struct Array in bestimmten Speicherbereich ablegen
-
Jackson0 schrieb:
Sorry ich bin noch Anfänger...
Dann solltest du dich gar nicht erst mal an die Programmierung eines MC wagen. Da kann dir die MMU deine größten Patzer nicht abfangen.
Jackson0 schrieb:
Compiler sagt: E4032C: initialization: constant expression is expected for file scope variable: `PPG'
Lern doch erst einmal, wie man ordentlich Zeiger verwendet.
Du machst*(__far unsigned char*) 0xDF4000;
- das Sternchen am Anfang ist eine Dereferenzierung, sprich, dass du den WERT haben willst, der an0xDF4000
liegt, und nicht einfach nur die Adresse. Der Compiler weiß nicht, was an0xDF4000;
liegt, aber für globale Variablen (file scope) brauchst du einen Wert, der sich NICHT ändern kann.Lass das Sternchen also weg. Und noch viel wichtiger, lern erstmal C ohne MC.
-
Danke, ich bin ja dabei es zu lernen. (learning by doing
)
Ich habe es Compiliert bekommen, aber funktioniert leider noch nicht:
init:
typedef struct PPG_Setup_Data { short Period; short Duty100; short Duty50; short Duty1; } Setup_PPG; // Setup_PPG PPG[255]; Setup_PPG* PPG = (Setup_PPG*) (__far unsigned char*) 0xDF4000;
main:
Uart_SendString(debugUart,"\nErgebnis EEprom read:\n"); for(z=0; z<10/2; z++) { Uart_SendString(debugUart,"Period="); Uart_SendBin2Asci(debugUart,PPG[z].Period , DEC, '0',5); Uart_SendString(debugUart,", Duty100="); Uart_SendBin2Asci(debugUart,PPG[z].Duty100 , DEC, '0',5); Uart_SendString(debugUart,"\n"); }
Ausgabe:
Ergebnis EEprom read: Period=00000, Duty100=00000 Period=00000, Duty100=00000 Period=00000, Duty100=00000 Period=00000, Duty100=00000 Period=00000, Duty100=00000
Testdaten sind im EEProm drin das habe ich überprüft und wenn keine drin wären würde eh alles 0xFF sein.
-
PPG sollte (so wie ich es verstehe) auch ein far-Pointer sein,
__far Setup_PPG * PPG = (Setup_PPG*) (__far unsigned char*) 0xDF4000;
-
Habe ich geändert, leider bleibt die Ausgabe gleich.
-
Sollte das nicht eher:
__far Setup_PPG *PPG = (__far Setup_PPG*)0xDF4000;
sein? Kannst du dir mal im Programm
PPG
ausgeben lassen (printf)?
-
Jackson0 schrieb:
Habe ich geändert, leider bleibt die Ausgabe gleich.
Willst du interne Register der MCU ansprechen, oder hast du irgendeine Hardware an den Bus gebastelt? Im ersten Fall sollte es im SDK eine .h-Datei mit lauter typedefs geben, die man dafür benutzen kann.
Um welchen Controller handelt es sich? Nenn mal bitte die Bezeichnung.
-
Der Code von Dachschaden funktioniert schon etwas (oder ich habe noch Fehler im schreiben/lesen vom EEPROM)
Ich habe jetzt insgesamt 12 Bytes per Array (im Testarray und EEprom einfach von 0-107 befüllt)
// Test EEProm Daten 1 2 3 4 5 6 7 8 9 10 11 12 volatile const unsigned char Test[9][12] = { 0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10,11, 12,13,14,15,16,17,18,19,20,21,22,23, 24,25,26,27,28,29,30,31,32,33,34,35, 36,37,38,39,40,41,42,43,44,45,46,47, 48,49,50,51,52,53,54,55,56,57,58,59, 60,61,62,63,64,65,66,67,68,69,70,71, 72,73,74,75,76,77,78,79,80,81,82,83, 84,85,86,87,88,89,90,91,92,93,94,95, 96,97,98,99,100,101,102,103,104,105,106,107 };
main:
Uart_SendString(debugUart,"\nErgebnis EEprom read:\n"); for(z=0; z<10; z++) { Uart_SendString(debugUart,"Channel="); Uart_SendBin2Asci(debugUart,PPG[z].Channel , DEC, '0',5); Uart_SendString(debugUart,", Status="); Uart_SendBin2Asci(debugUart,PPG[z].Status , DEC, '0',5); Uart_SendString(debugUart,", Strom="); Uart_SendBin2Asci(debugUart,PPG[z].Strom , DEC, '0',5); Uart_SendString(debugUart,", Period="); Uart_SendBin2Asci(debugUart,PPG[z].Period , DEC, '0',5); Uart_SendString(debugUart,", Duty100="); Uart_SendBin2Asci(debugUart,PPG[z].Duty100 , DEC, '0',5); Uart_SendString(debugUart,", Duty50="); Uart_SendBin2Asci(debugUart,PPG[z].Duty50 , DEC, '0',5); Uart_SendString(debugUart,", Duty1="); Uart_SendBin2Asci(debugUart,PPG[z].Duty1 , DEC, '0',5); Uart_SendString(debugUart,"\n"); }
Ausgabe jetzt:
Ergebnis EEprom read: Channel=00000, Status=00001, Strom=00770, Period=01284, Duty100=01798, Duty50=02312, Duty1=02826 Channel=00012, Status=00013, Strom=03854, Period=04368, Duty100=04882, Duty50=05396, Duty1=05910 Channel=00012, Status=00013, Strom=03854, Period=04368, Duty100=04882, Duty50=05396, Duty1=05910 Channel=00024, Status=00025, Strom=06938, Period=07452, Duty100=07966, Duty50=08480, Duty1=08994 Channel=00024, Status=00025, Strom=06938, Period=07452, Duty100=07966, Duty50=08480, Duty1=08994 Channel=00036, Status=00037, Strom=10022, Period=10536, Duty100=11050, Duty50=11564, Duty1=12078 Channel=00036, Status=00037, Strom=10022, Period=10536, Duty100=11050, Duty50=11564, Duty1=12078 Channel=00048, Status=00049, Strom=13106, Period=13620, Duty100=14134, Duty50=14648, Duty1=15162 Channel=00048, Status=00049, Strom=13106, Period=13620, Duty100=14134, Duty50=14648, Duty1=15162 Channel=00060, Status=00061, Strom=16190, Period=16704, Duty100=17218, Duty50=17732, Duty1=18246
Die Shortwerte sind jetzt natürlich schlecht zu lesen da glaube ich auch noch verdreht 03 + 02 HEX Ergibt 770
Zeile 1 würde ich mal sagen stimmt,
Zeile 2 auch, weil der erste Wert im nächsten Array ist 12
aber warum steht in Zeile 3 wieder als erstes 12
Zeile 4 wäre eigendlich Zeile 3 (also erstes Byte Zeile1=0 Z2=12,Z3=24,z4=36,z5=48,usw.)hier noch die Write_EEprom:
for (z=0;z<9;z++) { write_eeprom((0+z*12),12,&Test[z]); // Testwerte speichern } unsigned char write_eeprom(unsigned short adr, unsigned short len, unsigned short *data);
-
Andromeda schrieb:
Willst du interne Register der MCU ansprechen, oder hast du irgendeine Hardware an den Bus gebastelt? Im ersten Fall sollte es im SDK eine .h-Datei mit lauter typedefs geben, die man dafür benutzen kann.
Um welchen Controller handelt es sich? Nenn mal bitte die Bezeichnung.
Nein das ist das ein Bereich des interene Flashs der für sowas zu gebrauchen ist (8K je Sektor) Fujitsu FX16 Serie. Für die Dinger gibt es leider keine SDK's...
-
Jackson0 schrieb:
Fujitsu FX16 Serie. Für die Dinger gibt es leider keine SDK's...
Muss es geben. Du hast doch bestimmt ein Eval Board, ne? Von dem du das gekauft hast bekommst du sicherlich auch ein SDK.
Ansonsten mal dort nachfragen: https://www.mikrocontroller.net
-
Wo kommt plötzlich
PPG[z].Strom
her? OderPPG[z].Channel
Das Feld finde ich nicht in deiner Anfangsdeklaration. Kann es sein, dass du da mit den Feldern durcheinandergekommen bist? DirkB hat dich bereits gewarnt, dass Padding-Bytes eingefügt werden könnten, die willst du eventuell nicht haben.
-
Die war zum Besseren Verständnis recht einfach gehalten, zu Anfang waren es 9 Bytes jetzt sind es 12 Bytes. Das Ändert ja nichts am Prinzip. Und die ersten beiden Zeilen werden ja auch richtig übertragen je 12 Bytes.
typedef struct PPG_Setup_Data { // Länge 12 Byte char Channel; char Status; short Strom; short Period; short Duty100; short Duty50; short Duty1; } Setup_PPG;
-
Also:
Du schreibst in den EEPROM, und willst dann gleich wieder auslesen, was du so geschrieben hast.Hast du mal die gegenwärtige Adresse, auf die
&PPG[z]
zeigt, ausgegeben? Nur um sicherzugehen, dass er auch wirklich in 12-Byte-Schritten durchläuft.Wenn das Lesen funktioniert, vielleicht geht dann beim Schreiben was schief:
for (z=0;z<9;z++) { write_eeprom((0+z*12),12,&Test[z]); // Testwerte speichern }
(0+z*12)
kann auch direktz * sizeof(Test[z])
geschrieben werden. Ansonsten: da wir nicht wissen, was inwrite_eeprom
passiert, können wir dir auch nicht sagen, was inwrite_eeprom
passiert. Irgendwie logisch.Hast du dir mal ausgeben lassen, ob
(0 + z * 12)
wirklich die Position liefert, die du haben willst?
-
also die Daten im EEProm sind defintiv richtig:
Uart_SendString(debugUart,"\nErgebnis EEprom read:\n"); for(z=0; z<108; z++) { read_eeprom(z); Uart_SendBin2Asci(debugUart,z, DEC, '0',3); Uart_SendString(debugUart,","); } Uart_SendString(debugUart,"\n");
Ergibt:
Ergebnis EEprom read: 000,001,002,003,004,005,006,007,008,009,010,011,012,013,014,015,016,017,018,019,020,021,022,023,024,025,026,027,028,029,030,031,032,033,034,035,036,037,038,039,040,041,042,043,044,045,046,047,048,049,050,051,052,053,054,055,056,057,058,059,060,061,062,063,064,065,066,067,068,069,070,071,072,073,074,075,076,077,078,079,080,081,082,083,084,085,086,087,088,089,090,091,092,093,094,095,096,097,098,099,100,101,102,103,104,105,106,107,
Also funktioniert der Write-Befehl korrekt.
Ich habe mir auch mal die Mühe gemacht:
for(z=0; z<10; z++) { Uart_SendString(debugUart,"Channel="); Uart_SendBin2Asci(debugUart,PPG[z].Channel , DEC, '0',5); Uart_SendString(debugUart,", Status="); Uart_SendBin2Asci(debugUart,PPG[z].Status , DEC, '0',5); Uart_SendString(debugUart,", Strom="); Uart_SendBin2Asci(debugUart,PPG[z].Strom , DEC, '0',5); Uart_SendString(debugUart,", Period="); Uart_SendBin2Asci(debugUart,PPG[z].Period , DEC, '0',5); Uart_SendString(debugUart,", Duty100="); Uart_SendBin2Asci(debugUart,PPG[z].Duty100 , DEC, '0',5); Uart_SendString(debugUart,", Duty50="); Uart_SendBin2Asci(debugUart,PPG[z].Duty50 , DEC, '0',5); Uart_SendString(debugUart,", Duty1="); Uart_SendBin2Asci(debugUart,PPG[z].Duty1 , DEC, '0',5); Uart_SendString(debugUart,"\n"); }
einmal mit und einmal ohne Schleife also 9 * hintereinander den ganzen Block geschrieben und für 'z' echte Zahlen in jeden Block geschrieben. Das Ergebnis ist das gleiche:
Ergebnis EEprom read: z=00000 Channel=00000, Status=00001, Strom=00770, Period=01284, Duty100=01798, Duty50=02312, Duty1=02826 z=00001 Channel=00012, Status=00013, Strom=03854, Period=04368, Duty100=04882, Duty50=05396, Duty1=05910 z=00002 Channel=00012, Status=00013, Strom=03854, Period=04368, Duty100=04882, Duty50=05396, Duty1=05910 z=00003 Channel=00024, Status=00025, Strom=06938, Period=07452, Duty100=07966, Duty50=08480, Duty1=08994 z=00004 Channel=00024, Status=00025, Strom=06938, Period=07452, Duty100=07966, Duty50=08480, Duty1=08994 z=00005 Channel=00036, Status=00037, Strom=10022, Period=10536, Duty100=11050, Duty50=11564, Duty1=12078 z=00006 Channel=00036, Status=00037, Strom=10022, Period=10536, Duty100=11050, Duty50=11564, Duty1=12078 z=00007 Channel=00048, Status=00049, Strom=13106, Period=13620, Duty100=14134, Duty50=14648, Duty1=15162 z=00008 Channel=00048, Status=00049, Strom=13106, Period=13620, Duty100=14134, Duty50=14648, Duty1=15162
Also müsste der Fehler doch irgendwo hier liegen:
typedef struct PPG_Setup_Data { // Länge 12 Byte char Channel; char Status; short Strom; short Period; short Duty100; short Duty50; short Duty1; } Setup_PPG; __far Setup_PPG *PPG = (__far Setup_PPG*)0xDF4000;
-
Du gibst
z
aus, aber:dachschaden schrieb:
Hast du mal die gegenwärtige Adresse, auf die &PPG[z] zeigt, ausgegeben? Nur um sicherzugehen, dass er auch wirklich in 12-Byte-Schritten durchläuft.
Mich beschleicht das Gefühl, dass du bei jedem zweiten Schritten vorwärts einen Schritt zurück machst.
-
Kann das was damit zu tun haben das __far nicht allein stehen darf sondern nur mit (__far unsigned int*) im EEProm Code gibt es nur __far mit unsigned int* nie alleine?
unsigned short read_eeprom(unsigned short adr) { return (*(__far unsigned int*) (0xDF4000 + adr * 2)); }
-
Code:
Uart_SendString(debugUart,"\nErgebnis EEprom read:\n"); for(z=0; z<9; z++) { Uart_SendString(debugUart,"z="); Uart_SendBin2Asci(debugUart,z , DEC, '0',5); Uart_SendString(debugUart,", ADR:0x"); Uart_SendBin2Asci(debugUart,&PPG[z] , HEX, '0',6); Uart_SendString(debugUart," Channel="); Uart_SendBin2Asci(debugUart,PPG[z].Channel , DEC, '0',5); Uart_SendString(debugUart,", Status="); Uart_SendBin2Asci(debugUart,PPG[z].Status , DEC, '0',5); Uart_SendString(debugUart,", Strom="); Uart_SendBin2Asci(debugUart,PPG[z].Strom , DEC, '0',5); Uart_SendString(debugUart,", Period="); Uart_SendBin2Asci(debugUart,PPG[z].Period , DEC, '0',5); Uart_SendString(debugUart,", Duty100="); Uart_SendBin2Asci(debugUart,PPG[z].Duty100 , DEC, '0',5); Uart_SendString(debugUart,", Duty50="); Uart_SendBin2Asci(debugUart,PPG[z].Duty50 , DEC, '0',5); Uart_SendString(debugUart,", Duty1="); Uart_SendBin2Asci(debugUart,PPG[z].Duty1 , DEC, '0',5); Uart_SendString(debugUart,"\n"); }
Ausgabe:
Ergebnis EEprom read: z=00000, ADR:0xDF4000 Channel=00000, Status=00001, Strom=00770, Period=01284, Duty100=01798, Duty50=02312, Duty1=02826 z=00001, ADR:0xDF400C Channel=00012, Status=00013, Strom=03854, Period=04368, Duty100=04882, Duty50=05396, Duty1=05910 z=00002, ADR:0xDF4018 Channel=00012, Status=00013, Strom=03854, Period=04368, Duty100=04882, Duty50=05396, Duty1=05910 z=00003, ADR:0xDF4024 Channel=00024, Status=00025, Strom=06938, Period=07452, Duty100=07966, Duty50=08480, Duty1=08994 z=00004, ADR:0xDF4030 Channel=00024, Status=00025, Strom=06938, Period=07452, Duty100=07966, Duty50=08480, Duty1=08994 z=00005, ADR:0xDF403C Channel=00036, Status=00037, Strom=10022, Period=10536, Duty100=11050, Duty50=11564, Duty1=12078 z=00006, ADR:0xDF4048 Channel=00036, Status=00037, Strom=10022, Period=10536, Duty100=11050, Duty50=11564, Duty1=12078 z=00007, ADR:0xDF4054 Channel=00048, Status=00049, Strom=13106, Period=13620, Duty100=14134, Duty50=14648, Duty1=15162 z=00008, ADR:0xDF4060 Channel=00048, Status=00049, Strom=13106, Period=13620, Duty100=14134, Duty50=14648, Duty1=15162
Adresspointer sind also auch richtig
-
Wieso verwendest du nicht direkt Typen wie
uint8_t
oderuint16_t
? Warum packst du die Werte im Typen nicht in ein Array?#include <stdint.h> typedef struct { uint8_t fields_1[2]; /*Channel, Status*/ uint16_t fields_2[5]; /*Strom, Period, Duty100, Duty50, Duty1*/ }Setup_PPG;
Warum hast du nicht direkt auch ein paar Debug-Strings?
const char*const debug_strings_fields_1[] = { "Channel=", ", Status=" }; const char*const debug_strings_fields_2[] = { ", Strom=", ", Period=", ", Duty100=", ", Duty50=", ", Duty1=" };
Warum hast du kein Makro, mit dem du die Elemente in einem Array erhältst?
#define ARRAY_SIZE(array) ((sizeof(array) / sizeof((array)[0])))
Warum packst du die Ausgabe des Objekts nicht direkt in eine Funktion?
void print_eeprom(__far Setup_PPG*tmp_PPG) { uint16_t i; for(i = 0;i < ARRAY_SIZE(tmp_PPG->fields_1);i++) printf("%s%u",debug_strings_fields_1[i],tmp_PPG->fields_1[i]); for(i = 0;i < ARRAY_SIZE(tmp_PPG->fields_2);i++) printf("%s%u",debug_strings_fields_2[i],tmp_PPG->fields_2[i]); puts(""); }
Was ist die Größe eines
unsigned int
auf deiner Plattform? Warum ist dein Rückgabetyp für deine Lesefunktionunsigned short[]/c], aber verwendest einen [c]unsigned int
für die Referenzierung? Warum multiplizierst duadr
mit 2, anstatt ordentlich zu indizieren?uint16_t read_eeprom(uint16_t index) { __far uint16_t*tmp = (__far uint16_t*)PPG; return tmp[index]; }
Wieso postest du den Code zu
write_eeprom
nicht? Warum erhältst du keine Fehlermeldung beim Kompilieren, dass duwrite_eeprom
einenunsigned char*
übergibst, wenn einunsigned short*
erwartet wird?Auf keine diese Fragen möchte ich ein "Weiß ich nicht" sehen.
Deine Lese-Funktion liest 2-Byte-Werte - deine Ausgabe:
000,001,002,003,004,005,006 ...
Bedeutet also, dass dein EEPROM folgendes Muster hat:
0x00,0x00,0x01,0x00,0x02,0x00,0x03,0x00
Aber deine Ausgabe:
z=00000, ADR:0xDF4000 Channel=00000, Status=00001, Strom=00770, Period=01284, Duty100=01798, Duty50=02312, Duty1=02826
Zeigt eher, dass dein EEPROM so aussieht:
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
Sprich, die Funktion, die die Daten schreibt, macht dies Byte-weise, nicht 2-Byte-Weise. Das passt nicht aber zu der Ausgabe deines EEPROM.
Ich habe mal den ganzen Scheiß versucht, nachzubauen:
#include <sys/mman.h> #include <stdint.h> #include <stdio.h> #include <string.h> typedef struct { uint8_t fields_1[2]; /*Channel, Status*/ uint16_t fields_2[5]; /*Strom, Period, Duty100, Duty50, Duty1*/ }Setup_PPG; Setup_PPG*PPG; #define STATIC_ADDR (0xDF0000) #define STATIC_LEN (0x4000) const char*const debug_strings_fields_1[] = { "Channel=", ", Status=" }; const char*const debug_strings_fields_2[] = { ", Strom=", ", Period=", ", Duty100=", ", Duty50=", ", Duty1=" }; #define ARRAY_SIZE(array) ((sizeof(array) / sizeof((array)[0]))) void eeprom_write(uint16_t index,uint16_t len,const uint8_t*data) { uint16_t*tmp = (uint16_t*)PPG; uint16_t i; for(i = 0;i < len;i++) tmp[index + i] = data[i]; } uint16_t eeprom_read(uint16_t index) { uint16_t*tmp = (uint16_t*)PPG; return tmp[index]; } const uint8_t Test[9][12] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107 }; void eeprom_print(Setup_PPG*tmp_PPG) { uint16_t i; for(i = 0;i < ARRAY_SIZE(tmp_PPG->fields_1);i++) { printf("%s%05u",debug_strings_fields_1[i],tmp_PPG->fields_1[i]); } for(i = 0;i < ARRAY_SIZE(tmp_PPG->fields_2);i++) { printf("%s%05u",debug_strings_fields_2[i],tmp_PPG->fields_2[i]); } puts(""); } int main(void) { uint16_t i,j; PPG = mmap((void*)STATIC_ADDR,STATIC_LEN,PROT_READ | PROT_WRITE,MAP_PRIVATE | MAP_ANONYMOUS,-1,0); if(MAP_FAILED == PPG) { printf("Konnte Mapping nicht anlegen"); return 1; } for(i = 0;i < ARRAY_SIZE(Test);i++) eeprom_write(i * sizeof(Test[i]),sizeof(Test[i]),Test[i]); for(i = 0;i < ARRAY_SIZE(Test);i++) eeprom_print(&PPG[i]); for(i = 0;i < 108;i++) { if(!(i % sizeof(Test[i]))) puts(""); printf("%03d|",eeprom_read(i)); } puts(""); munmap(PPG,STATIC_LEN); return 0; }
Die einzigen Unterschiede sind, dass ich keine
__far
-Zeiger nutzen muss (wegen linearem Adressraum) und ichprintf
verwenden kann. Und ich kann dein Problem nicht nachvollziehen:Channel=00000, Status=00000, Strom=00001, Period=00002, Duty100=00003, Duty50=00004, Duty1=00005 Channel=00006, Status=00000, Strom=00007, Period=00008, Duty100=00009, Duty50=00010, Duty1=00011 Channel=00012, Status=00000, Strom=00013, Period=00014, Duty100=00015, Duty50=00016, Duty1=00017 Channel=00018, Status=00000, Strom=00019, Period=00020, Duty100=00021, Duty50=00022, Duty1=00023 Channel=00024, Status=00000, Strom=00025, Period=00026, Duty100=00027, Duty50=00028, Duty1=00029 Channel=00030, Status=00000, Strom=00031, Period=00032, Duty100=00033, Duty50=00034, Duty1=00035 Channel=00036, Status=00000, Strom=00037, Period=00038, Duty100=00039, Duty50=00040, Duty1=00041 Channel=00042, Status=00000, Strom=00043, Period=00044, Duty100=00045, Duty50=00046, Duty1=00047 Channel=00048, Status=00000, Strom=00049, Period=00050, Duty100=00051, Duty50=00052, Duty1=00053 000|001|002|003|004|005|006|007|008|009|010|011| 012|013|014|015|016|017|018|019|020|021|022|023| 024|025|026|027|028|029|030|031|032|033|034|035| 036|037|038|039|040|041|042|043|044|045|046|047| 048|049|050|051|052|053|054|055|056|057|058|059| 060|061|062|063|064|065|066|067|068|069|070|071| 072|073|074|075|076|077|078|079|080|081|082|083| 084|085|086|087|088|089|090|091|092|093|094|095| 096|097|098|099|100|101|102|103|104|105|106|107|
Wie sieht deine
write_eeprom
-Routine aus?
-
Also das ist eine 16 Bit MCU und die Bibliothek <stdint.h> hat er leider nicht und somit auch kein uint8_t etc.
Das Teil hat nur sehr wenig Flash/RAM deshalb muss alles recht "einfach" gehalten werden...
Deine Lese-Funktion liest 2-Byte-Werte - deine Ausgabe:
Code:
000,001,002,003,004,005,006 ...Das ist nur ein Trick, er liest ab Adresse0 2 Byte aber ins char passt ja nur eins davon. Dann liest er ab Adresse1 2 Bytes also quasi mittendrin und so weiter...
Hier die write_eeprom: Das mit den zwei Sektoren hat nichts mit dem Problem zu tun und kann ignoriert werden!
unsigned char write_eeprom(unsigned short adr, unsigned short len, unsigned short *data) { volatile unsigned short i, j, wdata; unsigned char error; volatile unsigned long fadr1, fadr2, fvalid; // check which sector is valid if (*(__far unsigned int*)(Sektor2 + 0x1FFE) == 0x0000) { // read from Sektor1 and write to Sektor2 Uart_SendString(2,"\nSektor 1 read, Sektor 2 write\n"); fadr1 = Sektor1; fadr2 = Sektor2; fvalid = Sektor1 + 0x1FFE; } else { // read from Sektor2 and write to Sektor1 Uart_SendString(2,"\nSektor 2 read, Sektor 1 write\n"); fadr1 = Sektor2; fadr2 = Sektor1; fvalid = Sektor2 + 0x1FFE; } for (i = 0; i < len ; i++) { wdata = (*(__far unsigned int*) (fadr1+(adr+i)*2) | data[i]); // Da nur Nullen o. löschen geschrieben werden können beide Werte mit OR verkn. und wenn der Wert nicht größer als die Flashdaten sind ist es möglich if (wdata > (*(__far unsigned int*) (fadr1+(adr+i)*2))) { // Daten können nicht ohne EEprom zu löschen geschrieben werden! if (*(__far unsigned int*)(fadr2 + 0x1FFE) != 0xFFFF) { // Erase SECTOR to be written error = Main_Flash_sector_erase(fadr2); // erase Sector } else { Uart_SendString(2,"\nSektor nicht geloescht!"); } // Write valid flag of old SECTOR: 1st step error = Main_Flash_write(fvalid, 0x00FF); j = 0; i = 0; for (i = 0; i < EEPROM_size; i+=2) { // count word-wise if ((i >= ((adr*2)+len*2)) || (i < adr * 2)) { wdata = (*(__far unsigned int*) (fadr1 + i)); // copy data } else { wdata = data[j]; // new data j++; } error = Main_Flash_write(fadr2 + i, wdata); } // Overwrite valid flag of old SECTOR: 2nd step error = Main_Flash_write(fvalid, 0x0000); return error; } else if (*(__far unsigned int*) (fadr1+(adr+i)*2) != data[i]) { // Daten können OHNE EEprom löschen geschrieben werden error = Main_Flash_write(fadr1 + (adr+i)*2, data[i]); } } return error; }