Hallo Gemeinde,
ich habe leider noch ziemlich wenig Ahnung von C, habe aber das Projekt schon ans laufen bekommen. Jetzt hätte ich gerne noch einen Taster (z. B. an Eingang 1) an dem ich die Ausgänge zusätzlich schalten kann, also z. B. per Taster einschalten und dann per Weboberfläche ausschalten, oder umgekehrt.
Wo im code müsste denn das abgefragt werden? Hab schon gesucht, bin aber nicht wirklich weiter gekommen. Wäre super, wenn jemand ein wenig Starthilfe geben könnte.
Vielen Dank
Gerhard
in C muss es immer eine Funktion main() geben (oft im Modul main.c). Bei Embedded Systemen enthält die so gut wie immer eine while(1){...} Schleife. Es macht ja bei einem Embedded System auch keinen Sinn die Funktion main() wieder zu verlassen. In dieser while(1) Schleife werden dann alle Tätigkeiten, die das Embedded System ausführen soll der Reihe nach zyklisch abgearbeitet. Das ist auch bei der ETH_M32_EX firmware so...
Wenn Du einen Port Ausgang schalten möchtest, kannst Du dies dann auch dort in der while(1) Schleife einfügen. Ordentlich wird es, in dem Du eine Funktion schreibst (man muss z.B. dafür sorgen, dass die Taste entprellt wird usw.), oder weniger ordentlich du schreibst Deinen Code direkt in die while(1) Schleife (main() wird dann dadurch aber immer unübersichtlicher. Guter Programmierstil ist, wenn man Funktionen schreibt, die nicht länger als eine Seite sind, und somit mit wenigen Blicken zu erfassen sind).
Bei der Aufgabe Ports zu schalten musst Du Dich auch nicht weiter darum kümmern, dass andere Module des Systems davon informiert werden (die u.U. auf die gleichen Ports zugreifen), was Du in Deinem Code so treibst, da bei der ETH_M32_EX Firmware, die Portregister selber als Informationsquelle über den Zustand der aktuellen Einstellungen dienen... Somit kannst Du einen Ausgang über den Webserver oder eine externe Taste ein/ausschalten, ohne dass es dabei zu Überschneidungen käme (auf Wechselwirkungen von Funktionen untereinander muss man immer höllisch aufpassen)...
Hilft Dir das weiter?
Grüße,
Micha
Hi Micha,
erst mal herzlichen Dank für die schnelle Antwort. Also, wenn ich das richtig verstanden habe, dann schreibe ich mir einfach eine neue Funktion, die den Ausgang ansteuert (abhängig vom Taster natürlich) und muss mich nicht um die Ansteuerung, die per Webinterface gemacht wird, kümmern, da diese den Zustand der Ausgänge sowieso einliest sobald da eine Aktion stattfindet.
Diese Funktion rufe ich dann in main.c auf.
Na da werd ich mich mal dranmachen, Versuch macht kluch )
Vielen Dank nochmal.
Gerhard
ganz genau so... Der Aufruf Deiner Funktion muss dann innerhalb der while(1) Schleife liegen, damit sie immer wieder aufgerufen wird... Wenn Du nicht weiterkommst einfach fragen...
an dem Problem hänge ich im Moment auch. Wie genau ich eine eigene .h und .c Datei einbinde, damit ich meine eigenen Funktion aufrufen kann.
Habe mir ein paar Beispiele angeschaut, komme aber nicht weiter, bekomme immer folgende Fehlermeldung:
main.c:221: undefined reference to `my_funktion'
Wenn ich zB eine MyTest.h und MyTest.c Datei einbinde, muss ich in main.c am Anfang
#include MyTest.h
angeben, dann ist sie in der Main Routine deklariert. Ist damit dann auch automatisch die .c Datei mit dem gleichen Namen eingebunden?
Muss ich wenn die Funktion Global sein soll die Funktion in der .h Datei noch mal angeben:
void my_funktion (void);
Eine Funktion in ein anderes "bestehendes" Modul zu integrieren funktioniert, aber keine eigene Dateien mit Funktionen anlegen.
Hallo,
h-Dateien dienen dazu, externe Funktionen und Variablen, die in einer anderen C-Datei stehen, bekannt zu machen. Das läuft so ab: Der Compiler übersetzt die C-Dateien Eine nach der Anderen nach Objekt code (Dateiendung normalerweise .obj. Objekt code enthält noch Symbolische Adressen, diese werden dann später erst durch den Linker durch reelle Adressen ersetzt). Dabei muss der Compiler ja aber wissen, wie das Format (Eingangs- und Ausgangsvariablen) einer Funktion, die in einer anderen C-Datei steht, aussieht...
Somit gibt der Compiler eine Fehlermeldung aus, wenn die Deklaration der externen Funktion fehlt, und keine, wenn man die Funktion als extern deklariert. (Er weiss durch die Deklaration im h-File nur wie das Format der Funktion aussehen soll und prüft, ob das mit der Verwendung in dem C-File zusammen passt (d.h. ob die Eingabe- und Ausgabevariablen in Typ und Anzahl passen). Wenn die Funktion dann in der Datei, in der sie steht, in Wirklichkeit ein ganz anderes Format hat, merkt das erst der Linker.
Im 2. Schritt werden dann alle vom Compiler zu Objekt Code übersetzten Dateien vom Linker zu ausführbarem Code (alle noch symbolischen Adressen werden durch reelle ersetzt) zusammegebaut. Dazu müssen dem Linker alle Dateien mitgeteilt werden. Wenn welche fehlen, gibt er Fehlermeldungen aus, da es dann ja symbolische Adressen gibt, die nirgendwo eine Korrespondenz haben. (Der Linker erzeugt u.U. auch ein map-File. Dort kann man u.A. sehen, welche reellen Adressen er den symbolischen zugewiesen hat).
Wenn Du eine neue C-Datei erstellt hast, musst du das dem auch Linker mitteilen. Dies geht bei WinAVR über das Makefile. Dort müssen alle Dateien aufgelistet sein, die zum Projekt gehören:
Hier ein Auszug des ETH_M32_EX Makefiles:
... # If there is more than one source file, append them above, or modify and
# uncomment the following:
SRC = main.c usart.c stack.c timer.c cmd.c base64.c
SRC += networkcard/enc28j60.c networkcard/rtl8019.c
SRC += httpd.c telnetd.c ntp.c lcd.c udp_lcd.c wol.c
SRC += http_get.c analog.c sendmail.c
SRC += camera/cam.c camera/servo.c
SRC += dnsc.c dhcpc.c
...
Hier sind alle Sourcefiles aufgelistet, damit diese Dateien vom Compiler übersetzt und an den Linker übergeben werden können.
Du kannst dann z.B. deine neue C-Datei in der letzten Zeile hinzufügen (denn die Reihenfolge der Dateien spielt keine Rolle):
SRC += dnsc.c dhcpc.c my_new_file.c
wobei my_new_file.c der Name der C-Datei ist, in der die Funktion 'my_funktion' zu finden ist...
Die Meldung: main.c:221: undefined reference to `my_funktion' ist genau dieser Fehler, weil der Linker die Funktion nirgendwo findet. Ausserdem wurde Deine neue Datei sicherlich auch nicht nach Object code übersetzt, weil auch nur die im Makefile stehenden Sourcefiles vom Compiler übersetzt werden. Es kann dann gut sein, dass Du jetzt auch noch Fehlermeldungen vom Compiler bekommst, falls Du welche in deinem Sourcefile hast (...böse Unterstellung, aber ein Erfahrungswert *lach*)
vielen Dank für die schnelle Antwort, ich denke das war es gewesen... an das Makefile hab ich gar nicht mehr gedacht...
Du bist ein Hellseher, habe wirklich eine Fehlermeldung vom Compiler bekommen, damit kann ich aber gar nichts anfangen???
------- begin --------
avr-gcc (WinAVR 20080610) 4.3.0
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
make.exe: *** No rule to make target `Hexfiles/Webserver_Test_MEGA644.eep', needed by `all'. Stop.
> Process Exit Code: 2
> Time Taken: 00:03
sobald ich meine .c Datei einbinde erhalte ich folgende Meldung, wenn ich die .c Datei raus nehme ist alles gut.
Ich versuche es aber weiter, nehme noch mal ein frisches File....
Hi,
diese Meldung kommt nicht vom Compiler, sondern von make.exe.
Make überprüft anhand der Liste der C-Dateien welche der Dateien seit der letzten Compilierung geändert wurden, und sorgt dafür, dass nur die geänderten neu compiliert werden (das spart Zeit bei großen Projekten und war zu Zeiten langsamer Rechner auch sehr sinnvoll.)
Diese Meldung habe ich auch ab und zu. Da hilft dann "Make Clean" auszuführen, das löscht alle Object Files (Dateiendung bei WinAVR entgegen der obigen Erklärung: .o), und dadurch compiliert make.exe beim nächsten mal alle C-Dateien des Projekts neu, wenn man "Make ALL" ausführt...
Das sollte dann ohne diese Fehlermeldung klappen...
Manchmal kommt die Meldung auch bei "Make Clean", dagegen hilft bei mir den Programmers Notepad zu beenden und neu zu starten...
Ich bin allerdings auch kein Experte für WinAVR bzw. make.exe...
Könntest du allenfalls mal deinen C-Code reinstellen? Ich wäre daran interessiert, da ich etwas ähnliches versuche und meine C-Kenntnisse recht mager bis fast gar nicht vorhanden sind.
bei Hapos Bitte möchte ich mich gleich mit anschließen!
Ich suche auch gerade nach einer Möglichkeit die Ausgänge über z.B. über einen Taster zu schalten .
Hallo,
ich das:
if (PINA & (1 << PINA1)) {
PORTA = PORTA | 0b0000000;
}
in die Hauptschleife der main.c eingefügt um per Schalter eine LED auszuschalten, angeschaltet wird die über die Weboberfläche was auch funktioniert nur warum wird die LED sofort wieder ausgeschaltet nachdem man sie einschält? Offenbar ist die if Schleife immer erfüllt auch wenn der Taster nicht gedrückt ist!? Könnte mir bitte jemand einen Tipp geben woran es liegen könnte!?
Danke