to save RAM in an AVR, for constants, numbers or especially strings, use the avr lib for GCC, and the “xxx_P” functions and macros.
These put constants in flash and don’t copy them to RAM at initialization.
there’s a particular .h for those - it’s something like <avr/progmem.h>
So you code
PSTR(“hello world”); and that goes to flash.
There are routines like
printf_P()
that take the format string from flash rather than RAM.
And puts_P() and so on.
where the _P means program memory.
That .h also gives macros and typedefs for putting constants in flash.
The AVR and PIC have two address spaces - one for flash program and constants and one for RAM. They overlap numerically, i.e., there is an address 0 in both spaces. So there have to be special instructions to fetch data (not instructions) from flash. This is why there are the _P library things.
The megaAVRs do not bank-switch RAM or instruction address spaces (up to 64KB) whereas most popular 8 bit PICs have an unfortunately tiny page size. This is a huge simplification and avoids lots of bank switching code wasting space.
Nice thing about the small and large ARMs is that they too have both flash and RAM, but the address spaces never overlap. Thus all instructions work for either.
The AVR/PIC dual address spaces date way back to an era when large static RAMs were very expensive.
The ARMs, esp. NXP, keep flash speeds from slowing the processor by doing very wide reads of flash - 8 or so bytes per read, then they take the needed chunks to execute the instruction in that area. Data in flash is retrieved using the same bit/byte/word/longword instructions as for RAM.
And instructions/code can be placed and executed from RAM, usually for debugging.
The LPC21xx and LPC176x are really convenient to use and for hobby projects, are not significantly more expensive than high end AVR/PIC 8 bitters.
PIC and AVR 32 bit CPUs are nonsensical to me, given ARM and how its licensed to so many vendors. I can’t see how AVR32 or PIC32 can compete - just based on popularity of ARM and lower risk of longevity.
So it’s a mistake to say that a “Harvard” architecture micro is for flash and RAM address spaces. The ARM has both memory types but in one linear address space, so I say it’s not Harvard. Since most compilers are von Neuman oriented, the single linear space is much easier on the software developer.