Guten Abend,
ich bin gerade dabei, mit ein paar Standart-Funktionen und Strukturen
für zukünftige 8 Bit AVR- Projekte anzulegen.
Habe mich jetzt mal durch die ganzen Header mit ettlichen defines des
GCC gebissen und letztendlich eine Struktur entworfen, so wie ich es für
richtig halte.
Nun hätte ich die Bitte, dass ihr mal kurz darüber schaut und mir ein
Feedback gebt, ob ich die Header-Files richtig verstanden habe und die
Struktur so passt.
Insbesondere bei den Makros setBit etc bin ich mir unsicher, da ich ja
hier auf den Wert des Pointers zugreifen müsste?....
Vielen Dank schonmal.
Gruß Jan
Header:
1
#if defined (__AVR_ATtiny13A__)
2
#define NUMPIN 5
3
#else
4
#error "Wrong device selected, please adapt number of Pins."
5
#endif
6
7
#include<stdint.h>
8
9
10
#ifndef GPIO_H_
11
#define GPIO_H_
12
13
#define INPUT 0
14
#define OUTPUT 1
15
16
typedefstruct
17
{
18
uint8_t*PR;/* Address of Port-Register */
19
uint8_t*DR;/* Address of Data-Direction-Register */
20
uint8_tPin;/* Pin-Number */
21
uint8_tDrctn[NUMPIN];/* Array for Data-Direction of each Pin */
22
uint8_tPinCount;/* Total number of Pins per Port */
Jan schrieb:> uint8_t *PR; /* Address of Port-Register */> uint8_t *DR; /* Address of Data-Direction-Register */
Die Zeiger müssen auf ein "volatile"-Objekt zeigen.
Du weißt schon, dass der ATtiny13A nur 64 Byte RAM hat? Ein einziges
GPIO-Struct belegt davon schon 11 Byte, ohne dass es irgendeine
Information enthält, die im RAM sein muss ...
Ich zähle "nur" 10 Byte, wie kommst du auf 11?
Ja ist mir durchaus bewusst, aber die Anwendung für den Tiny ist auch
nicht sehr Ressourcen-hungrig. Wird ein einfacher PWM-Dimmer.
Sicher kann man sowas auch ohne wilde Strukturen programmieren, mir ging
es aber auch darum mal einen "Grundstock" für zukünftige Programme (die
natürlich nicht auf dem Tiny laufen) zu legen. Dann bietet sich eine
Modularisierung schon an.
@ Jörg: Danke für den Hinweis, hab ich im Eifer des Gefechts total
übersehen.
Wie gesagt, meine Idee war die Software in verschiedene Schichten zu
gliedern (GPIO gehört beispielsweise zur Hardware-Kapselung und muss
controllerspezifisch angepasst werden). Das erleichtert die Portierung
des Codes auf andere Zielsysteme.
Sicher wirkt das nun auf den ersten Blick total aufgebläht, aber ich
verspreche mir davon Zeitersparnis bei größeren Projekten, da bei allen
Schichten oberhalb der Hardware-Kapselung alle Schnittstellen gleich
bleiben können.
Jan schrieb:> Wie gesagt, meine Idee war die Software in verschiedene Schichten zu> gliedern (GPIO gehört beispielsweise zur Hardware-Kapselung und muss> controllerspezifisch angepasst werden). Das erleichtert die Portierung> des Codes auf andere Zielsysteme.
Das kannst du auf deinem Entwicklungsrechner so betrachten.
> Sicher wirkt das nun auf den ersten Blick total aufgebläht, aber ich> verspreche mir davon Zeitersparnis bei größeren Projekten, da bei allen> Schichten oberhalb der Hardware-Kapselung alle Schnittstellen gleich> bleiben können.
Stimmt, auf einem kleinen µC kannst du das getrost als Hintergrundwissen
betrachten, wenn deine Entwicklungsumgebung das nicht selbständig für
das Zielsystem ausreichend optimiert.
Auf Controllern, bei denen man schon mit Funktionsaufrufen sparen muß,
damit der Stack nicht überläuft, gelten andere Gesetze.
Oder man schreibt sich ein paar Headerdateien mit Inline-Funktionen. Die
kann man einfach austauschen, wenn man das Programm auf eine andere
Plattform portieren möchte. Wenn sich nur die Ports/Pins ändern, reicht
es, die config-Datei zu ändern.
leds_config.h
Peter Dannegger schrieb:> Bei größeren MCs mit mehreren Ports hast Du trauer.
Dafür hast Du Trauer, wenn Du die GPIOs mit einem Funktionsaufruf statt
per Speicherzugriff steuern musst ... ;)
Aber Du hast schon recht, wenn man mehrere Ports mit der gleichen
Inline-Funktion bedienen will/muss, ist es nicht mehr so hübsch. Aber
auch nicht unmöglich. Ich hatte genau diese Situation in einem Projekt,
bei dem eine Status-LED in einer neuen Hardwareversion an einen anderen
Port gewandert ist.
Die Datei sah dann so aus:
Dank Inlining und Constant Folding bleibt von den Funktionen bei Aufruf
mit konstantem Parameter nur noch das reine Ändern des Ports übrig.
Weiterer Vorteil: Man kann ohne Overhead mehrere LEDs gleichzeitig
ändern.
Die sind zwar nicht ganz so portabel, wie deine Strukturen, haben dafür
aber den Vorteil, dass sie kein RAM und keinen zusätzlichen Code
erzeugen (da der Compiler das sehr gut optimiert).