Löschen Sie die Erklärungen aus den Beispielen und kopieren Sie anschließend die Beispiele in den Compiler: (benötigt Javascript)

Read from Flash

Works on devices with LPM (load from program memory) instruction implemented


If possible, put your constant tables in the lower 64K and use pgm_read_byte_near() or pgm_read_word_near() instead of pgm_read_byte_far() or pgm_read_word_far() since it is more efficient that way, and you can still use the upper 64K for executable code.


Datatypes (avr/pgmspace.h)

typedef void prog_void PROGMEM;

typedef char prog_char PROGMEM;

typedef unsigned char prog_uchar PROGMEM;


typedef int8_t prog_int8_t PROGMEM;

typedef uint8_t prog_uint8_t PROGMEM;

typedef int16_t prog_int16_t PROGMEM;

typedef uint16_t prog_uint16_t PROGMEM;



Functions from avr-libc

Avr-libc is WinAVR's built in c library


PGM_P

#define PGM_P const prog_char *

used to declare a variable that is a pointer to a string in program space.

PGM_VOID_P

#define PGM_VOID_P const prog_void *


Used to declare a generic pointer to an object in program space.


pgm_read_byte(address_short)

pgm_read_byte_near(address_short)

Read a byte from the program space with a 16-bit (near) address.

Note:

The address is a byte address. But the address is in the program space.


pgm_read_word (address_short)

pgm_read_word_near(address_short)


Read a word from the program space with a 16-bit (near) address.


PROGMEM Stringfunctions from avr-libc

void * memcpy_P (void *, PGM_VOID_P, size_t)

Copy a memory area

int strcasecmp_P (const char *, PGM_P) __ATTR_PURE__

compares the two strings s1 and s2, ignoring the case of the characters

char * strcat_P (char *, PGM_P)

similar to strcat() except that the src string must be located in program space (flash)

int strcmp_P (const char *, PGM_P) __ATTR_PURE__

similar to strcmp()

char * strcpy_P (char *, PGM_P)

similar to strcpy()

The strcpy function copies the string src to dst (including the terminating ‘\0’ character).

size_t strlcat_P (char *, PGM_P, size_t)

The strlcat function appends the NUL-terminated string src to the end of dst. It will append at most size - strlen(dst) - 1 bytes, NUL-terminating the result. Saver than strlncat

size_t strlcpy_P (char *, PGM_P, size_t)

The strlcpy function copies up to size - 1 characters from the NUL-terminated string src to dst, NUL-terminating the result.

size_t strlen_P (PGM_P) __ATTR_CONST__

Length of a string

int strncasecmp_P (const char *, PGM_P, size_t) __ATTR_PURE__


char * strncat_P (char *, PGM_P, size_t)


int strncmp_P (const char *, PGM_P, size_t) __ATTR_PURE__


char * strncpy_P (char *dest, PGM_P src, size_t len)

The strncpy function copies not more than len characters from src into dst, appending ‘\0’ characters if src is less than len characters long, and not terminating dst otherwise.



#BEISPIEL FLASH

#include <avr/io.h>

#include <inttypes.h>

#include <avr/pgmspace.h> enthält Typendeklaration


const int C1 = 34; landet im SRAM

const int C2 PROGMEM = 23; im FLASH


const char foo[] PROGMEM = "Foo";

const char bar[] PROGMEM = "Bar";

PGM_P array1[2] = {foo,bar}; SRAM !!!

Die Datenstruktur array1 wird im SRAM angelegt! Sie enthält zwei konstante Zeiger auf Zeichenketten im Flash

PGM_P array2[2] PROGMEM = {foo,bar}; FLASH


int main (void)

{

const int i1 PROGMEM = 3; //im SRAM;

Achtung! PROGMEM wird für lokale Variable ignoriert! Die Datenstruktur i1 wird im SRAM angelegt, daher funktioniert untenstehendes Einlesen von z nicht!

char buf[32];

unsigned char x,y,z;

strcpy_P (buf, array1[1]); //kopiert aus dem RAM; sollte eigentlich nicht funktionieren; strcpy() verwenden!

strcpy_P (buf, array2[1]); //kopiert aus dem FLASH

x = pgm_read_byte(array1[0]); //liest von ram

y = pgm_read_byte(array2[0]); //liest von flash

z = pgm_read_byte(&i1); funktioniert nicht

return 0;

}













/*

Testprog. & sub for binary to 7segment encoding kner 2004

via lookuptable(LUT)

*/

#include <io.h>

#include <inttypes.h>

#include <avr/pgmspace.h>

uint8_t bTo7a(uint8_t bin); //binary to 7segment Encoder version1

uint8_t bTo7b(uint8_t bin); //binary to 7segment Encoder version2


const int8_t _7SEG_LUT[] PROGMEM = {0xa0,0xa1,0xa2,0xa3,0xa4,

0xa5,0xa6,0xa7,0xa8,0xa9};

//wrong values for debugging only

int main (void)

{

uint8_t seg7Value, binValue = 0;

seg7Value = bTo7a(binValue);

binValue = 3;

seg7Value = bTo7b(binValue);

binValue = 9;

seg7Value = bTo7a(binValue);

return 0;

}

uint8_t bTo7a(uint8_t bin)

{

return pgm_read_byte(&_7SEG_LUT[bin]);

}

uint8_t bTo7b(uint8_t bin)

{

return pgm_read_byte(_7SEG_LUT+bin); _7SEG_LUT ist eine Adresse!

}

Kner 2004 5/5