Dies ist eine alte Version des Dokuments!
Inhaltsverzeichnis
AVR-GCC
Zufallszahlen erzeugen
Um Zufallszahlen mit der rand-Funktion (aus stdlib.h) zu erzeugen, ist ein Startwert (Seed) notwendig. Dieser wird durch srand(seed) gesetzt. Bei gleichem Seed ist die Folge immer gleich. Um unterschiedliche Folgen zu erhalten, ist ein veränderlicher Seed erforderlich. Dazu gibt es mehrere Ansätze:
- Zeit bis zum ersten Tastendruck zählen
- Wert eines „floatenden“ ADC-Eingangs lesen
Konstanten im Flash ablegen
Legt man eine Konstante mit
const uint8_t constant = 2;
an, wird der Wert aus dem Flash in den RAM geladen und belegt dort unnötig Platz, denn verändert werden darf der Wert der Konstante sowieso nicht. Soll das automatische Laden in das RAM verhindert werden, muss das Schlüsselword PROGMEM verwendet werden:
const PROGMEM uint8_t constant = 2;
. Diese Werte müssen dann mit pgm_read_byte()
, pgm_read_word()
, usw. gelesen werden. Soll eine Funktion Werte aus RAM und Flash verarbeiten, müssen zwei Versionen programmiert werden, denn in einer Funktion ist nicht zu erkennen, ob die Daten in RAM oder Flash liegen. Es ist üblich das Funktionen, die aus dem Flash lesen auf „_P“ enden:
const char stringInRAM[] = "Teststring im RAM"; const PROGMEM char stringInFlash[] = "Teststring im Flash"; lcd_string(stringInRAM); lcd_string_P(stringInFlash);
Häufig werden String auch inline definiert. Diese werden auch ins RAM geladen. Um das zu verhindern, aber die Inline-Definition beizubehalten gibt es das PSTR-Makro:
lcd_string("String im RAM"); lcd_string_P(PSTR("String im Flash");
Prinizipiell können alle Datentypen im Flash abgelegt werden. Bei structs sind einige Besonderheiten zu beachten.
typedef struct{ char text[20]; uint8_t index; } struct1; struct1 PROGMEM teststruct = { .text = "String in RAM", .index = 0 };
Hier bei liegt die Variable index und der Pointer auf den String im Flash, der String selbst liegt aber noch im RAM. Um das zu verhindern, muss er wie folgt definiert werden (eine Verwendung des PSTR-Makros ist hier nicht möglich):
typedef struct{ const char* text; uint8_t index; } struct1; const PROGMEM char stringInFlash[] = "String in Flash"; struct1 PROGMEM teststruct = { .text = stringInFlash, .index = 0 };
Der Zugriff auf die Elemente des Structs erfolgt dann so:
lcd_string_P((char*) pgm_read_word(&teststruct->text)); //Cast zu Char Pointer if (pgm_read_byte(&(teststruct->index))==curIndex) return true;