|
|||||||
| Arcade | Registrazione | Blogs | Regolamento | Feedback | FAQ | Lista Utenti | Calendario | Segna come Letti |
| Ultimi 5 blog pubblicati su PcTuner Blog | ||
|
||
![]() |
|
|
Strumenti Discussione | Modalità Visualizzazione |
|
|
#1 |
|
Registered User
|
Scrittura e lettura in eeprom
Sarebbe possibile avere un esempio di codice per la scrittura e lettura di una locazione eeprom interna al pic?
Vorrei cercare di capire come funziona. Grazie... grazie |
|
|
|
|
|
#4 | |
|
Registered User
|
Quote:
Naturalmente vanno usate con sale in zucca analizzate e capite. Se non si usa l'interrupt non va riabilitato altrimenti scoppiano dei sani casini. In assembly vi sono tutte quelle che io uso per un certo progetto per altri progetti creo delle routine alla bisogna. Le istruzioni RAM_xx sono delle macro che mi servono per girare tra i banchi senza sprecare spazio, ad es. RAM_2_3 agisce solo su un BIT di STATUS (RP0) e non su 2 come farebbe la direttiva BANKSEL. Possono essere sostituite tranquillamente da BANKSEL seguita dalla sua etichetta. Codice:
banksel 000h ; Va nel bamco RAM 0. banksel 080h ; Va nel bamco RAM 1. banksel 100h ; Va nel bamco RAM 2. banksel 180h ; Va nel bamco RAM 3. Codice:
//-----------------------------------------------------------------------------
void WriteEE(unsigned char dato) //Scrive sulla EE interna un Byte.
//L'indirizzo Š passato in addrEE che viene aggiornato.
{
EEADR=addrEE++;
EEDATA=dato; //Carica il dato.
EECON1bits.EEPGD=0; //Punta alla memoria dati.
EECON1bits.WREN=1; //Abilita la scrittura.
INTCONbits.GIE = 0; //disable interrupts, fortemente raccomandato.
EECON2=0x55;
EECON2=0xAA;
EECON1bits.WR=1;
INTCONbits.GIE = 1; //enable interrupts
//Per permettere la lettura immediata deve aspettare di aver scritto.
//while(EECON1bits.WR) ; //Utilizza un'istruzione in pi—.
do ; while(EECON1bits.WR) ; //Se ha finito di scrivere prosegue.
// Impiega 4mS per scrivere. Manuale TABLE22-2 pag.265
EECON1bits.WREN=0; //Disabilita la scrittura per evitare accidenti (runaway program).
ClrWdt();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void ReadEEtoprm1(void){ //Legge sulla EE interna un Byte.
// NB usa 12 istruzioni assembler.
// L'indirizzo Š passato in addrEE ritorna quanto letto in prm1.
// addrEE non Š toccato.
EEADR=addrEE; // Deve rimanere invariato.
EECON1bits.CFGS=0; //Punta alla memoria dati. Ô gi… a 0.
EECON1bits.EEPGD=0; //Punta alla memoria dati. Ô gi… a 0.
INTCONbits.GIE = 0; // Disabilita tutti gli interrupt.
EECON1bits.RD=1;
EECON1bits.RD=1; // Per superare un problema sull'emulatore.
EECON1bits.RD=1; // Per superare un problema sull'emulatore.
prm1=EEDATA;
INTCONbits.GIE = 1; // Abilita tutti gli interrupt.
}
//-----------------------------------------------------------------------------
Codice:
;***************************************************************************** ;********************** GESTIONE MEMORIA EEPROM INTERNA ********************** ;***************************************************************************** ;------------------------------------------------------------------------- ;NB La chiamata a queste routine pu• entrare da qualunque pagina RAM ; ed esce sempre in pagina 0. ;------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ReadEE: ;Legge sulla EE interna un Byte all'indirizzo passato in W, ritorna ; con il dato in W. IF TIPO==627 || TIPO==628 RAM_1 ELSE ;Per gli 873 ecc. RAM_2 ENDIF movwf EEADR bcf EEADR,7 ;Per sicurezza. IF TIPO==627 || TIPO==628 bsf EECON1,RD ELSE ;Per gli 873 ecc. RAM_2_3 EECON1,EEPGD ;Punta alla memoria dati. bsf EECON1,RD RAM_3_2 ENDIF movfw EEDATA ;ATTN. dei chiamanti fanno il test dello 0 per cui deve ; essere l'ultima istruzione che tocca il flag Z. RAM_0 clrwdt return ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- WriteEE: ;Scrive sulla EE interna un Byte all'indirizzo passato in W, ; il dato Š passato in dummy. IF TIPO==627 || TIPO==628 RAM_1 ELSE ;Per gli 873 ecc. RAM_2 ENDIF movwf EEADR ;L'indirizzo Š gia in W. bcf EEADR,7 ;Per sicurezza. movfw dummy ;Prende il dato. E' sovrapposto in pag.2. movwf EEDATA IF TIPO!=627 && TIPO!=628 ;Per gli 873 ecc. RAM_2_3 bcf EECON1,EEPGD ;Punta alla memoria dati. ENDIF bsf EECON1,WREN ;Abilita la scrittura. bcf INTCON,GIE ;Disabilita gli interrupt. movlw 0x55 movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1,WR bsf INTCON,GIE ;Riabilita gli interrupt. bcf EECON1,WREN ;Disabilita la scrittura. ;Per permettere la lettura immediata deve aspettare di aver scritto. btfsc EECON1,WR ;Skip se ha finito di scrivere. goto $-1 RAM_0 clrwdt return ;----------------------------------------------------------------------------- ;----------------------------------------------------------------------------- ClearAllEE: ;Cancella tutta la memoria EEPROM interna. movlw 128 ;Numero dei byte da cancellare. movwf addrEE ;Usato come contatore. clrf dummy ;Dato da scrivere in dummy. decf addrEE,W ;Indirizzo in W. call WriteEE decfsz addrEE,F goto $-3 return ;Risparmio: se non Š usata... provv ;----------------------------------------------------------------------------- ;********************************************************************* ; LEGGE dei byte consecutivi da EEPROM interna. ; Mette i dati letti in HL (FSR) e seguenti. ; L'indirizzo di partenza Š in addrEE che si incrementa. Read6EE: movlw 6 movwf cntbyte ;Quanti byte deve leggere. readloop: movfw addrEE call ReadEE movwf _HL_ incf addrEE,F incf HL,F decfsz cntbyte,F goto readloop return ;********************************************************************* ; SCRIVE dei byte consecutivi nella EEPROM interna. ; Preleva i dati da scrivere da HL (FSR) e seguenti. ; L'indirizzo di partenza Š in addrEE che si incrementa. Write6EE: movlw 6 movwf cntbyte ;Quanti byte deve scrivere. writeloop: movfw _HL_ ;Preleva il dato da scrivere. movwf dummy movfw addrEE call WriteEE incf addrEE,F incf HL,F decfsz cntbyte,F goto writeloop return ;********************************************************************* ;***************************************************************************** ;******************** FINE GESTIONE MEMORIA EEPROM INTERNA ******************* ;***************************************************************************** Essendo io un nostalgico dello Z80 o fatto queste definizioni: Codice:
#define HL FSR ;Nostalgico dello Z80 Š Camillo! #define _HL_ INDF ;Peccato che non si possano utilizzare le parentesi. #define HL_23 bsf STATUS,IRP ;Per l'uso indiretto dei banchi alti. #define HL_01 bcf STATUS,IRP ;Per l'uso indiretto dei banchi bassi.
Camillo
Il VeroProgrammatore può contare fino a 1024 con le dita delle mani. Grazie a .mau. Le donne e i gatti fanno quello che vogliono, gli uomini e i cani dovrebbero rilassarsi e abituarsi all'idea. R.A.Heinlein |
|
|
|
|
|
|
#5 |
|
Registered User
|
tnx nel week provo a capire però non avrò a disposizione internet (cambio di appartamento e dopo un mese telecom mi deve ancora allacciare alice. NDR Lunedì disdico)
Poi vedrai lunedì come fioccano le domande. Ciao e grazie |
|
|
|
|
|
#8 |
|
Registered User
|
per camillo:
io per scrivere sulla eeprom di un 18f2585 con il compilatore CCs utilizzo la seguente procedura Codice:
void writeee(char dato int address)
{
temp1=address
temp=dato
write_eeprom (temp1, temp); //address nel mio caso è 1
}
Puoi dirmi se ho sbagliato qualcosa (anche se sembra funzionare benissimo) perche' nel tuo caso vedo la procedura un po piu' corposa....sarà il diverso compilatore? ciao ciao Ultima Modifica di alecrp : 29-11-2006 19.31.05. |
|
|
|
|
|
#9 |
|
Scienziato pazzo
|
Queste sono le routine che ho scritto io
Codice:
SCRITTURA EEPROM ; SCRIVE EEPROM INTERNA ALL'INDIRIZZO "INDEE" VALORE "DATO" eewrite movf indee,w ; legge indirizzo bsf status,rp1 ; bank 2 bcf status,rp0 movwf eeadr bcf status,rp1 ; bank 0 movf dato,w ; leggi dato bsf status,rp1 ; bank 2 movwf eedata bsf status,rp0 ; bank 3 bcf eecon1,eepgd ; data memory bsf eecon1,wren ; attiva write movlw 0x55 movwf eecon2 movlw 0xAA movwf eecon2 bsf eecon1,wr ; scrivi btfsc eecon1,wr ; wr tornato a 0? goto $-1 ; no attende scrittura bcf eecon1,wren ; disattiva write bcf status,rp0 ; bank 0 bcf status,rp1 return LETTURA ; LEGGE EEPROM INTERNA ALL'INDIRIZZO "INDEE" E MEMORIZZA IN "DATO" eeread movf indee,w ; legge indirizzo bsf status,rp1 ; bank 2 bcf status,rp0 movwf eeadr bsf status,rp0 ; bank 3 bcf eecon1,eepgd ; data memory bsf eecon1,rd bcf status,rp0 ; bank 2 movf eedata,w ; leggi dato bcf status,rp1 ; bank 0 movwf dato ; memorizza return [edit] Devi usare i tag "code". Puoi inserirli cliccando sul tasto # nella finestra di post Ultima Modifica di FluidGuitar : 29-11-2006 22.31.19. |
|
|
|
|
|
#10 | |
|
Registered User
|
Quote:
Forse c'è qualche possibilità con dei dsPIC33xxxx di qualche razza. La tua domanda è troppo generica "suono di qualsiasi tipo" comprende tutto dai subsonici agli ultrasuoni con qualsiasi timbro, dal BIP al Clavicembalo ben temprato di JSB o ai Carmina Burana di Orff ecc.
Camillo
Il VeroProgrammatore può contare fino a 1024 con le dita delle mani. Grazie a .mau. Le donne e i gatti fanno quello che vogliono, gli uomini e i cani dovrebbero rilassarsi e abituarsi all'idea. R.A.Heinlein |
|
|
|
|
|
|
#11 | |
|
Registered User
|
Quote:
Normalmente un int viene rappresentato con 16bit ed è sconsigliabile il suo uso con il PIC essendo una macchina a 8 bit. La EEPROM interna è effettivamente da 256 byte e anche quando è più ampia viene divisa in banchi da 256 (PIC18F4620), il suo indirizzo parte da 0 fino a 255 (0xFF). A mio parere non ha senso fare una function che passa un'intero a meno che non sia la function stessa a gestire i banchi. La mia procedura non dovrebbe essere più corposa, è ampia il necessario per fare quello che deve fare, è come se fosse scritta in assembly. Il C18 traduce tutte quelle istruzioni C in una sola asm, l'ottimizzazione è massima anche nel caso del do ; while(EECON1bits.WR). Ci farei una scommessa che la tua write_eeprom (temp1, temp); non è ottimizzata come la mia anche per il solo fatto che passa 2 parametri che vanno messi nello stack e poi ripresi. Se poi gestisce i banchi col suo indirizzo integer...
Camillo
Il VeroProgrammatore può contare fino a 1024 con le dita delle mani. Grazie a .mau. Le donne e i gatti fanno quello che vogliono, gli uomini e i cani dovrebbero rilassarsi e abituarsi all'idea. R.A.Heinlein |
|
|
|
|
![]() |
Per le vostre immagini su questo forum potete usare PcTunerUp! Iscriviti gratuitamente alla nostra newsletter. |
| Utenti attualmente attivi che stanno leggendo questa discussione: 1 (0 utenti e 1 visitatori) | |
| Strumenti Discussione | |
| Modalità Visualizzazione | |
|
|