Hallo, kann man in einer Header Datei auch Anweisungen direkt angeben, die dann, mit dem Abarbeiten der Header Datei, automatisch mit ausgeführt werden? Ich will halt keinen zusätzlichen Funktionsaufruf der mir das Portregister auf Ausgang stellt. Und die main.c zumüllen wollte ich eigendlich auch nicht. Ziel ist halt, einfach Test.h includieren in main.c und *plopp fertig zum gebrauch, mit allen Port und Pin Definitionen... Test.h #define LED_1 PD3 #define PORT_LED_1 PORTD #define DDR_LED_1 DDRD . . /*hier fehlt was*/ DDR_LED_1 = (1<<LED_1) ; LED1 wird Ausgang /*hier fehlt was*/ PORT_LED_1 = (1<<LED_1); LED aus (neg. Logik) Gruß Ralf
Du scheinst einem weit verbreitetem Irrtum zu erliegen, was den Zweck und die Art der Verarbeitung einer Header-Datei angeht. Da steckt nichts, aber auch gar nichts geheimnisvolles dahinter. Der Präprozessor ersetzt die Zeile mit dem Include #inlcude "blabla.h" durch den Inhalt der Datei blabla.h und zwar bevor der eigentliche Compiler den Quelltext zu Gesicht bekommt. Das heist: Das ist ein reiner Editierschritt, so wie du ihn auch händisch in deinem Editor mittels Cut&Paste machen könntest. Nur macht es halt in diesem Fall der Präprozessor. Mehr steckt da absolut nicht dahinter. Wenn du wolltest, könntest du auch folgendes machen: file1.h ******* void foo() file2.h ******* { file3.h ******* int i = 5; file4.h } und eine zusammenfassende file.c: ****** #include file1.h #include file2.h int j = 7; #include file3.h #include file4.h Nachdem sich der Präprozessor die Datei file.c vorgenommen hat und alle includes durch den Inhalt der angegegeben Dateien ersetzt hat, entsteht daraus (ohne die Kommentare, die sind jetzt von mir) void foo() /* aus file1.h */ { /* aus file2.h */ int j = 7; /* stand schon in file.c */ int i = 5; /* aus file3.h */ } /* aus file4.h */ und erst dieses Ergebnis wird zum eigentlichen Compiler geschickt, der es dann übersetzt. Das heist aber auch im Umkehrschluss: Überleg dir, wie du Funktionalität in einem *.c File erledigen müsstest und gliedere dann diese Funktionalität in eine eigene Datei aus. > /*hier fehlt was*/ DDR_LED_1 = (1<<LED_1) ; LED1 wird Ausgang > /*hier fehlt was*/ PORT_LED_1 = (1<<LED_1); LED aus (neg. Logik) Klar. Das wäre auch so kein gültiges C. Anweisungen stehen (ausser bei Initialisierung) immer in Funktionen. Also wirst du wohl eine Funktion dafür machen müssen. Das ist kein Problem, denn du kannst dem Compiler den Hinweis geben, dass du gerne möchtest, dass er die Funktionsaufrufe wegoptimiert (Was er wahrscheinlich soweiso tun würde) inline void SetLed1Ausgang() { DDR_LED_1 = ( 1 << LED1 ); } inline void SetLedAus() { PORT_LED_1 = ( 1 << LED1 ); } eine andere Möglichkeit (wenn du dich nicht auf den Optimierer verlassen willst), ist die Verwendung von Makros (also der Anweisung an den Präprozessor, eine Textersetzung im Quelltext vorzunehmen): #define LED1_AUSGANG DDR_LED_1 = ( 1 << LED1 ) #define LED1_AUS PORT_LED_1 = ( 1 << LED 1 ) und verwendest das ganze dann int main() { LED1_AUSGANG; LED1_AUS; } der Präprozessor ersetzt jeweils den Text LED1_AUSGANG bzw. LED1_AUS durch den Text für den sie stehen, und heraus kommt: int main() { DDR_LED1 = ( 1 << LED1 ); PORT_LED_1 = ( 1 << LED1 ); } Damit aber nicht genug, für DDR_LED1, PORT_LED_1 bzw. LED1 gibt es ja seinerseits Makros, so dass die Ersetzung jeweils weitergeht: int main() { DDRD = ( 1 << PD3 ); PORTD = ( 1 << PD3 ); } DDRD, PORTD und PD3 sind ihrerseits auch wieder Makros (die über io.h eingebunden wurden) und die Ersetzung geht weiter. Ich hab jetzt nicht im Kopf, wie die Zahlenwerte für DDRD und PORTD lauten, PD3 wird durch eine ganz banale 3 ersetzt Im Endeffekt vleibt dann aber sowas übrig: int main() { *(volatile unsigned char)0x23 = ( 1 << 3 ); *(volatile unsigned char)0x24 = ( 1 << 4 ); } und erst dieses wird jetzt, nachdem alle Textersetzungen durchgeführt wurden, zum eigentlichen C-Compiler geschickt, der es übersetzt.
Für gcc 3.x gibt es hier eine Anleitung, wie man code vor dem Start von main() ausführen knn: http://www.roboternetz.de/wissen/index.php/Avr-gcc#Fr.C3.BChe_Codeausf.C3.BChrung_vor_main.28.29 Allerdings soll es ja viele Programme geben, die nur noch in ihrer debug-Version laufen, und keiner findet raus, warum. Solche (meiner Meinung nach unnötigen) Spielchen tragen dazu bei. Oder du programmierst in c++. Dann brauchst du nur ein globales Objekt der Klasse "test" mit den Initialisierungsanweisungen im Konstruktor :-) Oliver
> Ich will halt keinen zusätzlichen Funktionsaufruf der mir das > Portregister auf Ausgang stellt. C ist aber nun einmal funktionsorientiert, zumindest in seiner Syntax. Das erste, was ein Controller daher in main() macht, ist die Initialisierung seiner Hardware. Wenn du dir technisch die paar Takte für den Funktionsaufruf und die Rückkehr daraus sparen willst, dann kannst du diese Funktion gern "static inline" deklarieren. Dann guck aber auch bitte nach, welche startup-time sich aus deinen Fuses ergibt, oft genug liegt die im Bereich vieler Millisekunden (damit der Quarzgenerator stabil werden kann), da stören die paar Takte für die Funktion gar nicht.
Vorweg, Danke für die Antworten... @Karl heinz: ist schon erstaunlich, sämtliche einzel Informationen waren mir bekannt, aber sie mal alle auf einen Blick zu sehen rückt das ganze in ein für mich verständliches Licht, Danke... @Oliver: Ich mag Vererbung nicht. Wie hab ich´s im Studium gelernt; Ein Mann ist ein Mensch, eine Frau ist eine Unterklasse von Mann, damit ist Frau aber noch lange kein Mensch,... oder so ähnlich ;-) @Jörg: Nette Idee mit dem Einsparen von Zeit, aber das war nichtmal meine Absicht, ich wollte das Programm nur einfach einfacher machen. Um genau zu sein hab ich sogar eine kleine Verzögerungsschleife am Anfang, damit der Quarz Zeit zum einschwingen hat (falsche Kondensatoren >zu groß< am Quarz, aber für die ersten Versuche funktioniert es so) Gruß und Danke Ralf
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.