• AVR Freaks

PIC12F1501 - Help with writing & reading flash memory

Author
JeyakrishnaSridhar
New Member
  • Total Posts : 8
  • Reward points : 0
  • Joined: 2019/10/02 22:49:23
  • Location: 0
  • Status: offline
2019/11/28 03:11:09 (permalink)
0

PIC12F1501 - Help with writing & reading flash memory

Dear all, 
 
For my project using PIC12F1501 microcontroller, I am using the NCO peripheral with which I need to pulse my underlying circuit at a certain frequency. However, the exact value of the NCO frequency  depends on the underlying components and therefore need a calibration routine needs to be carried out to identify the NCO frequency. 
 
So, I have built a calibration routine which is carried out once in lifetime of uC by using a GPIO input and it includes, 
1. Sweep the NCO frequency
2. Find the suitable NCO frequency
3. Store the needed values (two 16bit values) in the FLASH memory
 
Once calibration is done, the normal routine takes place every time after power on which includes,
1. Read the (two 16bit values) from the FLASH memory
2. Set the NCO frequency according to the stored value
3. Do calculations
 
I used the MCC to fetch flash program read & write routines but the FLASH_WriteWord () needs a ramBuf which already consumes 32 bytes of data. Since the Data Memory is only 64 bytes, I am running out of space with other declarations. I tried to reuse the ramBuf, but wasnt successful. 
 
I tried to edit FLASH_WriteWord() routines to try to accommodate the available Data Memory but still wasnt able to get it working and it is really painful to see that the FLASH_WriteWord is built to write 16 rows and takes so much space even for writing two words.
 
Can someone help with me a better memory optimized code?
 
Thanks
Jeyakrishna Sridhar
 
 
main.c
 
/* Definitions for RAM Memory Allocation */
uint16_t ramBuf[WRITE_FLASH_BLOCKSIZE]; // Needed for writing block
uint16_t PWMValue[2];



/* Reusing ramBuf */

#define StartFreq ramBuf[15]
#define PWMSweep ramBuf[14]
#define VGain_Freq ramBuf[13]
#define FreqStep ramBuf[11]
#define Calib_DONE ramBuf[10]



void Calibrate()
{

/* Constants initialization */

StartFreq = 65529; // start at 999 kHz
FreqStep = 655; // Freq step of 10 kHz

/* Supporting variables */
PWMSweep = StartFreq;
VGain_Freq = 0;

// Find the maximum ADC value in a given frequency sweep and write the value for NCO in Flash
while (1)
{
NCO1INCH = PWMSweep >> 8; // Load values to NCO register
NCO1INCL = PWMSweep & 0xFF;
__delay_ms(100);

if ( ADC_GetConversion(3) <= VGain_Freq)
{
PWMValue[0] = PWMSweep;
PWMValue[1] = ADC_GetConversion(0);
break;
}

VGain_Freq = ADC_GetConversion(3);
PWMSweep = PWMSweep - FreqStep;
__delay_ms(1000);

}


FLASH_WriteWord(NCOFreq_addr, ramBuf, PWMValue); // Write Values to Flash
__delay_ms(1000);

Calib_DONE = 0x01; // Set this so that the calibration is done only once.

}



void ReadData()
{
PWMValue[0] = FLASH_ReadWord(NCOFreq_addr);
__delay_ms(1000);

PWMValue[1] = FLASH_ReadWord(NCOFreq_addr+1);
__delay_ms(1000);



NCO1INCH = PWMValue[0] >> 8;
NCO1INCL = PWMValue[0] & 0xFF;


Freq_read = 0x01; // Set this when the frequency is read once.
}



void main(void)
{



while (1)
{

if ( EN_CALIB_GetValue() == 0) // Calibration mode
{

if ( (Calib_DONE & 0x01) != 1) // If calibration is not done, call calibrate function.
{
Calibrate();
}

}

else // Normal operation mode

{

if ((Freq_read & 0x01) != 1) // If frequency is not read, call calibrate function.
{
ReadData();
}

}

 
memory.c
 
/*In memory.c, I changed the routine FLASH_WriteWord to accept a word array of size 2 so that 2 words of consecutive address are written. I am not sure if i can share */


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[i] = FLASH_ReadWord((blockStartAddr+i));
}

// Write at offset
ramBuf[offset] = word[0];
ramBuf[offset+1] = word[1];

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

 
 
 
#1

1 Reply Related Threads

    pcbbc
    Super Member
    • Total Posts : 1388
    • Reward points : 0
    • Joined: 2014/03/27 07:04:41
    • Location: 0
    • Status: offline
    Re: PIC12F1501 - Help with writing & reading flash memory 2019/12/02 09:17:36 (permalink)
    0
    Take a look at the FLASH_WriteBlock routine.  Modify it so that it only takes an array of the size you need, then ignores the remaining locations in the write cycle.  They will be 0xFF after an erase anyway.
    #2
    Jump to:
    © 2019 APG vNext Commercial Version 4.5