Memoria Flash di un pic12F617 per memorizzare (ESEMPI cercasi disperatamente)

9 Anni 6 Mesi fa #1 da Elby
Sto cercando di far memorizzare all'interno del pic 12f617 dei dati (solo 4 dati in realtà relativi al numero di overflow che deve fare il timer per indicare quattro tempi diversi).

E' la prima volta che mi trovo a dover memorizzare un dato e quindi non so bene come fare specie perchè l'unico supporto su cui farlo è la flash interna di questo pic.

Sul datasheet ci sono le spiegazioni ma devo ammettere che proprio non riesco ad afferrare il concetto di come si fa a dover scrivere un dato in quattro step e comunque non mi è chiaro come mai debba utilizzare sia il registro PMADRL che PMADRH.
In rete ho cercato tantissimo ma non trovo alcun tipo di esempio che non sia in assembler (che per me è peggio dell'arabo) e quindi chiedo al forum se qualcuno ha un esempio completo di come si utilizzi questa funzione del pic. Chiedo un esempio completo perchè non mi è neppure chiaro come viene chiamato un indirizzo specifico di memoria e su quali criteri si basa a scelta.
Ringrazio infinitamente chiunque mi potrà aiutare.

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Elby
  • Senior Member
  • Senior Member
Di più
9 Anni 5 Mesi fa #2 da Pascolo
Se non hai grande esperienza ti consiglio di cambiare micro (sempre della Microchip) e provare il nuovo tool "Code Configurator".
Anch'io non ho grande esperienza e con questo tool sono riuscito a programmare la flash e a fare molte altre cose. Vale la pena darci un occhiata.
Un micro supportato de questo tool è ad esempio il 12F1572.

Per questo micro devi tradurre in C il codice che trovi a pag 30 e 34 del data sheet, i commenti al lato del codice dovrebbero darti una mano.
Intanto quale compilatore stai utilizzando?
Ringraziano per il messaggio: Elby

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Pascolo
  • Junior Member
  • Junior Member
Di più
9 Anni 5 Mesi fa #3 da Elby
Programmo con XC8 ed il mio problema è proprio relativo al meccanismo di stoccaggio dei dati nella flash.
Non ho capito come si devono scrivere i dati (sembrerebbe in quattro step ciascuno con un'allocazione di memoria) però si leggono in un solo step immettendo semplicemente gli indirizzi alto e basso e leggendo. In quest'ultimo caso poi non capisco come, dato che alla fine leggerò due Byte, possa per esempio uscire dalla funzione di lettura con due dati separati.
Purtroppo senza un esempio non riesco proprio a capire

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Elby
  • Senior Member
  • Senior Member
Di più
9 Anni 5 Mesi fa #4 da Pascolo
Il code configurator per il 12F1572 genera il seguente codice che a prima occhiata dovrebbe andare bene (controlla i registri):


uint16_t FLASH_ReadWord(uint16_t flashAddr) {
uint8_t GIEBitValue = INTCONbits.GIE; // Save interrupt enable

INTCONbits.GIE = 0; // Disable interrupts
PMADRL = (flashAddr & 0x00FF);
PMADRH = ((flashAddr & 0xFF00) >> 8);

PMCON1bits.CFGS = 0; // Deselect Configuration space
PMCON1bits.RD = 1; // Initiate Read
NOP();
NOP();
INTCONbits.GIE = GIEBitValue; // Restore interrupt enable

return ((PMDATH << 8) | PMDATL);
}

void FLASH_WriteWord(uint16_t flashAddr, uint16_t *ramBuf, uint16_t word) {
uint16_t blockStartAddr = (uint16_t) (flashAddr & ((END_FLASH - 1) ^ (ERASE_FLASH_BLOCKSIZE - 1)));
uint8_t offset = (uint8_t) (flashAddr & (ERASE_FLASH_BLOCKSIZE - 1));
uint8_t i;

// Entire row will be erased, read and save the existing data
for (i = 0; i < ERASE_FLASH_BLOCKSIZE; i++) {
ramBuf = FLASH_ReadWord((blockStartAddr + i));
}

// Write at offset
ramBuf[offset] = word;

// Writes ramBuf to current block
FLASH_WriteBlock(blockStartAddr, ramBuf);
}

int8_t FLASH_WriteBlock(uint16_t writeAddr, uint16_t *flashWordArray) {
uint16_t blockStartAddr = (uint16_t) (writeAddr & ((END_FLASH - 1) ^ (ERASE_FLASH_BLOCKSIZE - 1)));
uint8_t GIEBitValue = INTCONbits.GIE; // Save interrupt enable
uint8_t i;

// Flash write must start at the beginning of a row
if (writeAddr != blockStartAddr) {
return -1;
}

INTCONbits.GIE = 0; // Disable interrupts

// Block erase sequence
FLASH_EraseBlock(writeAddr);

// Block write sequence
PMCON1bits.CFGS = 0; // Deselect Configuration space
PMCON1bits.WREN = 1; // Enable wrties
PMCON1bits.LWLO = 1; // Only load write latches

for (i = 0; i < WRITE_FLASH_BLOCKSIZE; i++) {
// Load lower 8 bits of write address
PMADRL = (writeAddr & 0xFF);
// Load upper 6 bits of write address
PMADRH = ((writeAddr & 0xFF00) >> 8);

// Load data in current address
PMDATL = flashWordArray;
PMDATH = ((flashWordArray & 0xFF00) >> 8);

if (i == (WRITE_FLASH_BLOCKSIZE - 1)) {
// Start Flash program memory write
PMCON1bits.LWLO = 0;
}

PMCON2 = 0x55;
PMCON2 = 0xAA;
PMCON1bits.WR = 1;
NOP();
NOP();

writeAddr++;
}

PMCON1bits.WREN = 0; // Disable writes
INTCONbits.GIE = GIEBitValue; // Restore interrupt enable

return 0;
}

void FLASH_EraseBlock(uint16_t startAddr) {
uint8_t GIEBitValue = INTCONbits.GIE; // Save interrupt enable


INTCONbits.GIE = 0; // Disable interrupts
// Load lower 8 bits of erase address boundary
PMADRL = (startAddr & 0xFF);
// Load upper 6 bits of erase address boundary
PMADRH = ((startAddr & 0xFF00) >> 8);

// Block erase sequence
PMCON1bits.CFGS = 0; // Deselect Configuration space
PMCON1bits.FREE = 1; // Specify an erase operation
PMCON1bits.WREN = 1; // Allows erase cycles

// Start of required sequence to initiate erase
PMCON2 = 0x55;
PMCON2 = 0xAA;
PMCON1bits.WR = 1; // Set WR bit to begin erase
NOP();
NOP();

PMCON1bits.WREN = 0; // Disable writes
INTCONbits.GIE = GIEBitValue; // Restore interrupt enable
}
/**
End of File
*/

Le funzioni da chiamare sono "
uint16_t FLASH_ReadWord(uint16_t flashAddr) {
uint8_t GIEBitValue = INTCONbits.GIE; // Save interrupt enable

INTCONbits.GIE = 0; // Disable interrupts
PMADRL = (flashAddr & 0x00FF);
PMADRH = ((flashAddr & 0xFF00) >> 8);

PMCON1bits.CFGS = 0; // Deselect Configuration space
PMCON1bits.RD = 1; // Initiate Read
NOP();
NOP();
INTCONbits.GIE = GIEBitValue; // Restore interrupt enable

return ((PMDATH << 8) | PMDATL);
}

void FLASH_WriteWord(uint16_t flashAddr, uint16_t *ramBuf, uint16_t word) {
uint16_t blockStartAddr = (uint16_t) (flashAddr & ((END_FLASH - 1) ^ (ERASE_FLASH_BLOCKSIZE - 1)));
uint8_t offset = (uint8_t) (flashAddr & (ERASE_FLASH_BLOCKSIZE - 1));
uint8_t i;

// Entire row will be erased, read and save the existing data
for (i = 0; i < ERASE_FLASH_BLOCKSIZE; i++) {
ramBuf = FLASH_ReadWord((blockStartAddr + i));
}

// Write at offset
ramBuf[offset] = word;

// Writes ramBuf to current block
FLASH_WriteBlock(blockStartAddr, ramBuf);
}

int8_t FLASH_WriteBlock(uint16_t writeAddr, uint16_t *flashWordArray) {
uint16_t blockStartAddr = (uint16_t) (writeAddr & ((END_FLASH - 1) ^ (ERASE_FLASH_BLOCKSIZE - 1)));
uint8_t GIEBitValue = INTCONbits.GIE; // Save interrupt enable
uint8_t i;

// Flash write must start at the beginning of a row
if (writeAddr != blockStartAddr) {
return -1;
}

INTCONbits.GIE = 0; // Disable interrupts

// Block erase sequence
FLASH_EraseBlock(writeAddr);

// Block write sequence
PMCON1bits.CFGS = 0; // Deselect Configuration space
PMCON1bits.WREN = 1; // Enable wrties
PMCON1bits.LWLO = 1; // Only load write latches

for (i = 0; i < WRITE_FLASH_BLOCKSIZE; i++) {
// Load lower 8 bits of write address
PMADRL = (writeAddr & 0xFF);
// Load upper 6 bits of write address
PMADRH = ((writeAddr & 0xFF00) >> 8);

// Load data in current address
PMDATL = flashWordArray;
PMDATH = ((flashWordArray & 0xFF00) >> 8);

if (i == (WRITE_FLASH_BLOCKSIZE - 1)) {
// Start Flash program memory write
PMCON1bits.LWLO = 0;
}

PMCON2 = 0x55;
PMCON2 = 0xAA;
PMCON1bits.WR = 1;
NOP();
NOP();

writeAddr++;
}

PMCON1bits.WREN = 0; // Disable writes
INTCONbits.GIE = GIEBitValue; // Restore interrupt enable

return 0;
}

void FLASH_EraseBlock(uint16_t startAddr) {
uint8_t GIEBitValue = INTCONbits.GIE; // Save interrupt enable


INTCONbits.GIE = 0; // Disable interrupts
// Load lower 8 bits of erase address boundary
PMADRL = (startAddr & 0xFF);
// Load upper 6 bits of erase address boundary
PMADRH = ((startAddr & 0xFF00) >> 8);

// Block erase sequence
PMCON1bits.CFGS = 0; // Deselect Configuration space
PMCON1bits.FREE = 1; // Specify an erase operation
PMCON1bits.WREN = 1; // Allows erase cycles

// Start of required sequence to initiate erase
PMCON2 = 0x55;
PMCON2 = 0xAA;
PMCON1bits.WR = 1; // Set WR bit to begin erase
NOP();
NOP();

PMCON1bits.WREN = 0; // Disable writes
INTCONbits.GIE = GIEBitValue; // Restore interrupt enable
}
/**
End of File
*/
Le funzioni da chiamare sono la "FLASH_ReadWord" e la "FLASH_WriteWord".
Ringraziano per il messaggio: Elby

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Pascolo
  • Junior Member
  • Junior Member
Di più
9 Anni 5 Mesi fa #5 da Pascolo
Allegati:
Ringraziano per il messaggio: Elby

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Pascolo
  • Junior Member
  • Junior Member
Di più
Moderatori: Mauro LaurentiPinnaStefAMatteo Garia

Registrati al sito

Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.

Registrati al sito LaurTec.

Login