Benutzer-Werkzeuge

Webseiten-Werkzeuge


software:avr-gcc

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
software:avr-gcc [2013/08/06 22:11] – [Zufallszahlen erzeugen] ollisoftware:avr-gcc [2018/02/24 07:18] (aktuell) – [Links] olli
Zeile 9: Zeile 9:
 Legt man eine Konstante mit <code c> const uint8_t constant = 2; </code> an, wird der Wert aus dem Flash in den RAM geladen und belegt dort unnötig    Legt man eine Konstante mit <code c> const uint8_t constant = 2; </code> 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: 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:
-<code c> const PROGMEM uint8_t constant = 2; </code>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:+<code c> const PROGMEM uint8_t constant = 2; </code> 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 innerhalb 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:
 <code c> <code c>
 const char stringInRAM[] = "Teststring im RAM"; const char stringInRAM[] = "Teststring im RAM";
Zeile 16: Zeile 16:
 lcd_string_P(stringInFlash); lcd_string_P(stringInFlash);
 </code> </code>
-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:+Häufig werden Strings inline definiert. Diese werden auch vom Flash ins RAM geladen. Um das zu verhindern, aber die Inline-Definition beizubehaltengibt es das PSTR-Makro:
 <code c> <code c>
 lcd_string("String im RAM"); lcd_string("String im RAM");
Zeile 32: Zeile 32:
 }; };
 </code>   </code>  
-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):+Hierbei 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):
 <code c> <code c>
 typedef struct{  typedef struct{ 
Zeile 63: Zeile 63:
 </code> </code>
 kann man dann den Linker anweisen, unbenutzte Sections zu entfernen, so dass das entstehende Binary kleiner wird. kann man dann den Linker anweisen, unbenutzte Sections zu entfernen, so dass das entstehende Binary kleiner wird.
 +
 +<WRAP important round>
 +//**Achtung**//
 +Damit Interrupthandler nicht entfernt werden, müssen sie mit
 +<code c>
 +__attribute__ ((used))
 +</code>
 +gekennzeichnet werden.
 +</WRAP>
 +
 +====== PIN, PORT und DDR mit einem define anpassen ======
 +Um einen Pin am AVR zu konfigurieren und zu benutzen, benötigt man die drei Variablen PINX, PORTX, DDRX.
 +Um dies konfigurierbar zu machen, kann man drei defines verwenden:
 +<code c>
 +#define SENSOR_DDR DDRA
 +#define SENSOR_PORT PORTA
 +#define SENSOR_PIN PINA
 +</code>
 +Möchte man den Port z.B. von A auf B ändern, muss man drei defines anpassen. Mit einem Makrotrick kann man das vermeiden. PINX, PORTX, und DDRX werden so definiert:
 +
 +<code c>
 +#define SENSOR_DDR __CONCAT(DDR, SENSOR_PORT_LETTER)
 +#define SENSOR_PORT __CONCAT(PORT, SENSOR_PORT_LETTER)
 +#define SENSOR_PIN __CONCAT(PIN, SENSOR_PORT_LETTER)
 +</code>
 +
 +Mit 
 +<code c>
 +#define SENSOR_PORT_LETTER A
 +</code>
 +lässt sich dann der Buchstabe für alle drei Variablen anpassen. Das Makro %%__CONCAT%% ist dabei wie folgt definiert:
 +<code c>
 +#define __CONCATenate(left, right)   left ## right
 +#define __CONCAT(left, right)   __CONCATenate(left, right)
 +</code>
 +Man kann diese Makros selbst definieren oder die Definition aus dem Header stdint.h benutzen, da man diesen sowieso fast immer inkludiert. 
 ===== Links ===== ===== Links =====
-  * [[http://www.github.com/abcminiuser/avr-tutorials/blob/master/ManagingLargeProjects/Output/ManagingLargeProjects.pdf?raw=true|C Code modularisieren]]+  * [[http://www.swwiki.e-dschungel.de/C|Hinweise zu C allgemein]] 
 +  * [[https://godbolt.org/|Compiler-Explorer]] 
 + 
  
software/avr-gcc.1375819887.txt.gz · Zuletzt geändert: 2013/08/06 22:11 von olli