Haver si te soluciona esto .
Lo hice hace mucho , creo que funciona .
Codigo:
#define EEPROM_0 0xFC00 // 1kb
#if defined(__dsPIC30F6011__) || defined(__dsPIC30F6013__)
#define EEPROM_0 0xF800 // 2k
#endif
#if defined(__dsPIC30F6010__) || defined(__dsPIC30F6012__) || defined(__dsPIC30F6014__)
#define EEPROM_0 0xF000 // 4k
#endif
/* ********************************************************************* */
void EraseCicle(void)
/* ********************************************************************* */
{
IFS0bits.NVMIF=0;
asm( " DISI #5 " ); // Block all interrupts with priority <7
/* for next 5 instructions*/
asm( " MOV #0x55,W0 " );
asm( " MOV W0,NVMKEY " ); // Write the 0x55 key
asm( " MOV #0xAA,W1 " );
asm( " MOV W1,NVMKEY " ); // Write the 0xAA key
asm( " BSET NVMCON,#15 " ); // Initiate program sequence NVMCONbits.WR=1;
asm( " NOP " );
asm( " NOP " );
}
/* ********************************************************************* */
void EepromWrite(unsigned int Addr , unsigned int Dato)
/* ********************************************************************* */
{
Addr = EEPROM_0 + ( Addr * 2 );
/* Writing to the Data EEPROM */
asm( "mov %0,w0 " : : "g" ( Addr ) : "w0" ); // Addr L
asm( " MOV #0x7F,W1 " ); // Addr H
asm( " MOV W1,TBLPAG " );
asm( " mov %0,w2 " : : "g" ( Dato ) : "w2" ); // Dato
asm( " TBLWTL W2,[W0] " ); // Write data
/* The NVMADR captures last table access address*/
asm( " MOV #0x4044,W0 " ); // OPERATION Erase 1 word of data memory.
asm( " MOV W0,NVMCON " );
EraseCicle(); while ( IFS0bits.NVMIF==0 ){}
/* The NVMADR captures last table access address*/
asm(" MOV #0x4004,W0 " ); // OPERATION Write 1 word to data memory.
asm(" MOV W0,NVMCON " );
EraseCicle(); while ( IFS0bits.NVMIF==0 ){}
}
/* ********************************************************************* */
unsigned int EepromRead(unsigned int Addr )
/* ********************************************************************* */
{
Addr = EEPROM_0 + ( Addr * 2 );
asm( " mov %0,w0 " : : "g" (Addr) : "w0" ); // Addr HL
asm( " MOV #0x7F,W1 " ); // Addr U
asm( " MOV W1,TBLPAG " );
asm( " TBLRDL [ W0 ], W0 " ); // lee dato EEPROM retorna w0
}
Suerte con el cacharro .
Claro , perdona , no lo puse completo .
Lo he editado para completarlo .
no olvides poner la cabecera el pic que usas
#define __dsPIC30F6014__
Ya que cada modelo varia la direccion en que empieza
Codigo:
2kb. 0xF800 -> 30F6011 , 30F6013
4kb. 0xF000 -> 30F6010 , 30F6012 , 30F6014
1kb. 0xFC00
Solo es una manera y se puede obtimizar seguramente , tambien gravar todo un bloque .
Esta inspirado del data sheet que indica como se lee y escrive .
Codigo:
XAMPLE 7-4: DATA EEPROM WORD WRITE
; Point to data memory
MOV #LOW_ADDR_WORD,W0 ; Init pointer
MOV #HIGH_ADDR_WORD,W1
MOV W1,TBLPAG
MOV #LOW(WORD),W2 ; Get data
TBLWTL W2,[ W0] ; Write data
; The NVMADR captures last table access address
; Select data EEPROM for 1 word op
MOV #0x4004,W0
MOV W0,NVMCON
; Operate key to allow write operation
DISI #5 ; Block all interrupts with priority <7 for
; next 5 instructions
MOV #0x55,W0
MOV W0,NVMKEY ; Write the 0x55 key
MOV #0xAA,W1
MOV W1,NVMKEY ; Write the 0xAA key
BSET NVMCON,#WR ; Initiate program sequence
NOP
NOP
; Write cycle will complete in 2mS. CPU is not stalled for the Data Write Cycle