|
Autore |
Messaggio |
opzioni |
Ottavo
postato il: 20.03.2019, alle ore 21:11 |
Pic16F1618346 - NVMREG WRITE TO EEPROM
Salve a tutti!
Sto lavorando ad un piccolo progetto, puramente hobbistico, basato sul pic 16F1618346. Si tratta di un misuratore di volume per liquidi.
Mi sono attenuto a quanto riportato nel datasheet e tutto funziona a meraviglia.
Successivamente è nata la necessitàdi poter effettuare delle calibrazioni e di dover salvare in eeprom almeno 4word.
Uso l'accesso via NVMREG ma la procedua di scrittura non termina mai e non viene nemmeno settato il bit di errore.Quella di lettura invece va a buon fine.
Sicuramente sbaglio qualcosa e/o non ho compreso bene qualche passaggio.
Allego il codice ringraziano s'indora chi si prenderàil disturbo di leggerlo
void SaveOnEEprom()
{
if(RqRead) //Richiesta lettura
{
NVMCON1.NVMREGS=1; //Seleziono EEprom
NVMADRH=0x70; //Specifico indirizzo
NVMADRL=0x00;
NVMCON1.RD=1; //Attivo lettura
if(!NVMCON1.RD) //Lettura terminata
{
MemReadOk=1; //Memoria lettura eseguita
RqRead=0; //Resetto richiesta lettura
SavedAttn=NVMDAT; //Trasferisco dati letti
IntToStrWithZeros(NVMADR&32767, u10);
Lcd_Out(2,1,u10);
Lcd_Out(2,7,"/");
IntToStrWithZeros(NVMDAT, u20);
Lcd_Out(2,8,u20);
}
}
if(RqWrite) //Richiesta scrittura
{
if(!MemWrite)
{
NVMCON1.NVMREGS=1; //Seleziono EEprom
NVMCON1.WREN=1; //Abilito scrittura
INTCON.GIE=0; //Disabilito interrupts
NVMCON2=0x55; //Procedura unlock
NVMCON2=0xaa; //Procedura unlock
NVMADRH=0x70; //Specifico indirizzo
NVMADRL=0x00;
NVMDAT=SavedAttn; //Scrivo dati
NVMCON1.WR=1; //Attivo scrittura
MemWrite=1; //Memoria scrittura attivata
INTCON.GIE=1; //Abilito interrupts
}
if(MemWrite&!NVMCON1.WR) //Scrittura terminata
{
MemWriteOk=1; //Memoria scrittura eseguita
RqWrite=0; //Resetto richiesta scrittura
IntToStrWithZeros(NVMADR&32767, u10);
Lcd_Out(2,1,u10);
Lcd_Out(2,7,"/");
IntToStrWithZeros(NVMDAT, u20);
Lcd_Out(2,8,u20);
}
}
}
detesto citazioni, massime e aforismi nella firma |
|
Ottavo
postato il: 20.03.2019, alle ore 21:26 |
P.S.
Il write protect è ovviamente disabilitato
CONFIG3 : $8009 : 0x0003
detesto citazioni, massime e aforismi nella firma |
|
rcc.roberto
[pagine pubblicate]
postato il: 20.03.2019, alle ore 21:36 |
non me ne intendo molto, e non so se c'entra, ma nel SCRITTURA TERMINATA non entra perché NVMCON1.WR è uguale a 1 |
|
Ottavo
postato il: 20.03.2019, alle ore 22:25 |
Ciao,
e' corretto che lì non entra perché NVMCON1.WR=1, ma nel datasheet è riportato che quel bit viene resettato dal micro stesso al termine dell'operazione di scrittura, analogamente a quanto avviene con NVMCON1.RD per quella di lettura.
detesto citazioni, massime e aforismi nella firma |
|
Ottavo
postato il: 20.03.2019, alle ore 23:30 |
Che stupido che sono!
Ho riletto il codice moltissime volte e non vedevo l'errore.
L'ho pubblicato qui e mi è balzato agli occhi.
Nella funzione di scrittura, il primo controllo condizionale verifica che
MemWrite=0 per avviare la scrittura e all'interno di questo viene settato.
Al secondo if si accede se MemWrite=1 e NVMCON1.WR=0 ma qui dentro MemWrite non viene più resettato.
Notavo un comportamento anomalo e avevo l'impressione che la EEprom venisse scritta una volta sola.
Infatti al secondo tentativo di scrittura con MemWrite=1 e NVMCON1.WR=0
non era più possibile accedere al primo if ed eseguire la procedura di scrittura.
Ripubblico il codice corretto privo della parte inerente l'output su lcd che mi serviva per vedere cosa succedeva.
Qualsiasi suggerimento per eventuali migliorie sarà molto gradito.
void SaveOnEEprom()
{
if(RqRead) //Richiesta lettura
{
NVMCON1.NVMREGS=1; //Seleziono EEprom
NVMADRH=0x70; //Specifico indirizzo
NVMADRL=0x00;
NVMCON1.RD=1; //Attivo lettura
if(!NVMCON1.RD) //Lettura terminata
{
MemReadOk=1; //Memoria lettura eseguita
RqRead=0; //Resetto richiesta lettura
SavedAttn=NVMDAT; //Trasferisco dati letti
}
}
if(RqWrite) //Richiesta scrittura
{
if(!MemWrite)
{
NVMCON1.NVMREGS=1; //Seleziono EEprom
NVMCON1.WREN=1; //Abilito scrittura
INTCON.GIE=0; //Disabilito interrupts
NVMCON2=0x55; //Procedura unlock
NVMCON2=0xaa; //Procedura unlock
NVMADRH=0x70; //Specifico indirizzo
NVMADRL=0x00;
NVMDAT=SavedAttn; //Scrivo dati
NVMCON1.WR=1; //Attivo scrittura
MemWrite=1; //Memoria scrittura attivata
INTCON.GIE=1; //Abilito interrupts
}
if(MemWrite&!NVMCON1.WR) //Scrittura terminata
{
MemWriteOk=1; //Memoria scrittura eseguita
MemWrite=0; //RESETTO MEMORIA SCRITTURA
RqWrite=0; //Resetto richiesta scrittura
}
}
}
detesto citazioni, massime e aforismi nella firma |
|
Ottavo
postato il: 21.03.2019, alle ore 19:53 |
Non funziona ancora!
L'ho acceso questa sera e il contenuto della word salvata ieri è andato perso...nonostante la procedura si fosse conclusa correttamente.
detesto citazioni, massime e aforismi nella firma |
|
agric
postato il: 22.03.2019, alle ore 05:10 |
se ho compreso bene la procedura in scrittura come nella lettura
questo è la sequenza giusta
NVMADRH=0x70; //PRIMA Specifico indirizzo
NVMADRL=0x00;
NVMCON2=0x55; //Procedura unlock
NVMCON2=0xaa; //Procedura unlock
meglio essere un granello di pepe che una cacca d'asino |
|
picmicro675
postato il: 22.03.2019, alle ore 12:11 |
Un po fuori discorso....
Per quello che so io, in generale, bisogna disabilitare gli interrupt durante la scrittura su EEPROM.
Poi rileggi DS40001839D-page 127, ma anche tutto il capitolo 11.
Molto descrittivo il diagramma di flusso della figura 11-5.
Anno nuovo, forum nuovo.
Mi sa che lascio. |
|
agric
postato il: 22.03.2019, alle ore 12:51 |
l'interrupt è disabilitato bit GIE=0.
meglio essere un granello di pepe che una cacca d'asino |
|
picmicro675
postato il: 23.03.2019, alle ore 02:03 |
A me sembra il contrario INTCON.GIE=1; //Abilito interrupts
Poi il diagramma di flusso va studiato a modino che mi sembra la procedura da seguire. Incluso il GIE.
Anno nuovo, forum nuovo.
Mi sa che lascio. |
|
|