PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PIC 18F4550 Struktur im Flash speichern



Matzenerich
10.10.2008, 17:07
Hallo µC Hacker,

habe eine Struktur im RAM, die ich in einer anderen Struktur im ROM, also Flash speichern möchte.

Struktur Typ sieht wie folgt aus:

struct DATENSATZ // Strukturvariable (26Byte)zur
{ // Speicherung von Datensaetzen
uint16 chargennr; // Variable fuer Chargennummer
ulong32 akt_st_zahl; // Variable fuer aktuelle Stückzahl
float r_wert1; // Variable fuer Wert Widerstand 1
float r_wert2; // Variable fuer Wert Widerstand 2
float r_wert3; // Variable fuer Wert Widerstand 3
float r_wert4; // Variable fuer Wert Widerstand 4
float r_wert5; // Variable fuer Wert Widerstand 5
};

Die Struktur ds_temp (temporärer Datensatz im RAM) soll in ein Strukturarray mdaten[] gespeichert werden.

Laut dem Buch C Programmieren von Anfang an (Helmut Erlenkötter) kann man eine Struktur mit (in meinem Beispiel) mdaten[0] = ds_temp komplett kopieren. Nur funzt das Speichern im ROM selbst noch nicht.

Hat jemand eine Idee, einen Gedankenanstoss?
Danke.

Matzenerich
18.10.2008, 17:49
Moin Leute,

da leider keiner geantwortet hat, hier nach ca. 10 Tagen die Antwort.
Funzt schon ganz gut, habe jedoch nur noch ein wenig mit nicht geschriebenen Bytes zu tun, vielleicht fällt euch ja was auf.

rom void WriteDataToFlash(rom far union un_struct *dest, ram union un_struct *src, uint8 length)
{
uint8 i=0, j=0, k=0, laenge=0, anz=0; // Zaehlvariable
laenge = length;

// 64er Block identifizieren
offset=(uint8) dest%64; // Offset errechnet
TBLPTR=(((uint24)dest)-offset); // (64er) Basispointer setzen
basisptr=(rom far int8 *)TBLPTR; // Basispointer sichern


// Sichern der Daten (64 oder 128)
buf=(rom far int8 *) TBLPTR; // Adr. TBLPTR in buf speich.
if( ( ((uint24)TBLPTR) +offset+laenge) > ( ((uint24)TBLPTR) +63) ) // wenn Blockuebergreifend
{ // sichere 128 Bytes
for(i=0; i<128u; i++)
{
mem[i]=*buf++;

}
anz=128;
}
else // sonst sichere nur 64 Bytes
{
for(i=0; i<64u; i++)
{
mem[i]=*buf++;
}
anz=64;
}


// modifizieren mit neuen Daten
for(j=0; j<laenge; j++)
{
mem[(offset+j)]=ds_temp_2.ch[j]; //schreibe Datensatz in array
}


// Loeschen
if(anz==128u)
{
// loeschen 1. Teil von 2
EECON1bits.EEPGD = 1;
EECON1bits.CFGS = 0;
EECON1bits.WREN = 1;
EECON1bits.FREE = 1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xaa;
EECON1bits.WR = 1; // CPU steht
_asm NOP _endasm;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;

delay_sek(1);

// loeschen 2. Teil von 2
TBLPTR=( ((uint24)TBLPTR) +64);
EECON1bits.EEPGD = 1;
EECON1bits.CFGS = 0;
EECON1bits.WREN = 1;
EECON1bits.FREE = 1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xaa;
EECON1bits.WR = 1; // CPU steht
_asm NOP _endasm;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;

delay_sek(1);
}
else
{
// loeschen nur 1. Teil
EECON1bits.EEPGD = 1;
EECON1bits.CFGS = 0;
EECON1bits.WREN = 1;
EECON1bits.FREE = 1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xaa;
EECON1bits.WR = 1; // CPU steht
_asm NOP _endasm;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;

delay_sek(1);
}


//2x schreiben bei 64 Byte und 4x schreiben bei 128 Byte
TBLPTR=(uint24) basisptr; // TBLPTR auf Startadr.
if(anz==128u)
{
for(k = 0;k < 128u; k++)
{
TABLAT = mem[k]; // in TABLAT und increm.
_asm // schreibe in holding
TBLWTPOSTINC // register und incremente
_endasm; // hinterher
if(((k + 1) % 32) == 0u) // schreibe alle 32 Bytes
{
_asm TBLRDPOSTDEC _endasm; // vor schreiben in TBLPTR
EECON1bits.EEPGD = 1; // in 32er Block !
EECON1bits.WREN = 1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xaa;
EECON1bits.WR = 1;
_asm NOP _endasm;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;
_asm TBLRDPOSTINC _endasm; // TBLPTR Anfang n. Block

delay_sek(1);
}
}
}
else
{
for(k = 0;k < 64u; k++)
{
TABLAT = mem[k]; // in TABLAT und increm.
_asm // schreibe in holding
TBLWTPOSTINC // register und incremente
_endasm; // hinterher
if(((k + 1) % 32) == 0u) // schreibe alle 32 Bytes
{
_asm TBLRDPOSTDEC _endasm; // vor schreiben in TBLPTR
EECON1bits.EEPGD = 1; // in 32er Block !
EECON1bits.WREN = 1;
INTCONbits.GIE = 0;
EECON2 = 0x55;
EECON2 = 0xaa;
EECON1bits.WR = 1;
_asm NOP _endasm;
INTCONbits.GIE = 1;
EECON1bits.WREN = 0;
_asm TBLRDPOSTINC _endasm; // TBLPTR Anfang n. Block

delay_sek(1);
}
}
}

}