Working with AVR microcontroller FLASH memory using WinAVR GCC

Because AVR microcontrollers are Harvard architecture they have separate address spaces for different memory types: SRAM, FLASH and EEPROM. Each of these memories have their own purposes. If data will not change during all time of program execution, then it should be stored as one type of memory like EEPROM otherwise if data will be used frequently and will change during program execution, then it should be stored in SRAM memory. Where to store data decides program developer. One thing you should note, that working with different types of memories require different operations how they are accessed.

Usually when define variables in C language like int a – compiler automatically stores it in to the SRAM. But if you want you can place constants in EEPROM or even FLASH memories.

As I mentioned no specific operations aren't needed to work with variables sored in SRAM. Lets go through other two memory types FLASH and EEPROM.

Lets say we decide to store some information to FLASH in order to save space in SRAM. Then we

need to show compiler to store this information to FLASH memory. For this wee will need additionally library: #include <avr/pgmspace.h>. Now wee can declare data to be stored in FLASH memory:

// custom LCD characters
const uint8_t backslash[] PROGMEM=  
{
0b00000000,	//back slash
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
0b00000000,
0b00000000
};

Declaring variable with keyword PROGMEM shows compiler to store this constant in AVR FLASH memory.

For reading from FLASH usually use pgm_read_byte() function like in this example:

uint8_t a, i;
for(i=0;pgm_read_byte(&backslash[i]);i++)
{
a=pgm_read_byte(&backslash[i]);
}  

 

this way you can store and read bytes, words and double words by using commands:

pgm_read_byte()

pgm_read_word()

pgm_read_dword()

If you will read pgmspace library documentation you will see that instead const uint8_t backslash[] PROGMEM you can use const prog_uint8_t backslash[]

Here is a working example of program:

#include <avr\io.h>
#include <avr\iom8.h>
#include <avr\pgmspace.h>

const prog_uint8_t backslash[]=
{
0b00000000,//back slash
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
0b00000000,
0b00000000
};
int main(void) {
uint8_t a, i;
for(i=0;pgm_read_byte(&backslash[i]);i++)
{
a=pgm_read_byte(&backslash[i]);
}
   while(1) {
   }
}