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