More ways to use AVR Flash memory using WinAVR

We've been talking about controlling AVR Flash memory in previous post. We talked how ease we can write and read from flash memory using PROGMEM atribute. But lets see more ways of usage Flash memory in your applications.

Sometimes when you write a code and in some places you are just sending strings to LCD or USART using simple expression like:

SendSTR(“This is a string”);

This seems very simple but not good way to use strings, because any way this string is being hardcoded in to flash memory, but compiler is forced to load this string to SRAM during microcontroller initialization before main() routine starts. And this string stays in RAM. This is ok for one or two strings but when you use significant amounts of strings this way then you really waste your RAM by holding all static unchanging data.

We know that working with flash requires library:

#include <avr/pgmspace.h>

One way is to use PROGMEM atribute that holds your data in flash and doesn't load it to RAM during startup:

const char FlashString[] PROGMEM = "This is a string ";

Using this declaration sending string function could look like:

void SendSTR_P(const char *FlashSTR)  
{
uint8_t i;  
for (i = 0; pgm_read_byte(&pFlashSTR[i]); i++)  
	{       
		sendChar(pgm_read_byte(&pFlashSTR[i]));  
	} 

 

Call this procedure in your program like this:

SendSTR_P(FlashString);

This is the way you have to write your own procedure to send strings stored in Flash memory. But there is another way if you want to use in-line strings – use PSTR macro instead PROGMEM declaration. So you can use:

SendSTR_P(PSTR(“FlashString”));

This macro doesn't allow to work with strings like they are in ram, because pointer points to flash memory not to RAM. But there are few functions that help to work with strings stored in flash memory. They are all stored in pgmspace.h library. Those functions are similar to string functions like memcpy, strncmp but with _P prefix, for instance:

strncmp_P("RAM string", PSTR("Flash string"));

This is a good habit of naming functions that work with flash strings.

In conclusion of this we can say that we have two ways declaring flash strings: using PROGMEM atribute when declaring values or using PSTR macro function and use in-line strings:

const char FlashString[] PROGMEM = "This is a string in flash";

SendSTR_P(FlashString);

or simply use:

SendSTR_P(PSTR(“This is a string in flash”));

First way is more practical when same string is used multiple times and second way with inline flash strings is suitable when string is used only one time.