Hallo, ich hab mir einen kleinen Autonomen Roboter gebaut, aber immer
wenn ich versuche die Steuerung der Motoren in ein externe .c und .h
zupacken läuft danach nichts mehr.
Es passiert das die Beiden Motoren nur noch rückwärts oder gar nicht
mehr laufen und der Servo in der Rechten Prosition stehen bleibt. ach
aus und einschalten fährt der Servo wieder in die Mitte bebewegt sich
nach rechts und bleibt dort.
>extern void MOTOR_PWM (uint16_t A, uint16_t B);
Schlüsselwort EXTERN vor einer Funktionsdeklaration kommt mir seltsam
vor.
Was soll damit erreicht werden ?
Gruß,
dasrotemopped.
ne hab wieder ERRORS noch WARNINGS oder MESSAGES
was ich nur komisch finde ist der Code bleibt ja gleich, ich packe ja
nur die Funktion der Steuerung in eine externe c zur übersicht, der Code
wird ja nicht verändert.
Sebi schrieb:> was ich nur komisch finde ist der Code bleibt ja gleich, ich packe ja> nur die Funktion der Steuerung in eine externe c zur übersicht, der Code> wird ja nicht verändert.
Hast Du auch sorgfältig und mehrfach kontrolliert, ob beim Zerteilen und
Kopieren nicht doch irgend etwas schief gegangen ist?
>extern ist für den Compiler nur ein Hinweis das die Funktion anderweitig
noch benutzt wird.
eher nicht. das ist laut meinem Kernighan/Ritchie für Variablen, nicht
Funktionen.
Darum vermute ich, das dein Programm ein Problem mit der Sichtbarkeit
von Variablen hat.
>*** Globale Variablen ***>uint16_t abstand = 0,rechts =0,links =0;
Global verstehst du warscheinlich auch anders als C.
void MOTOR_PWM (uint16_t A, uint16_t B)
{
OCR1A = A;
OCR1B = B;
}
A ist 16 bit, muss auf einem 8bitter OCR1A nicht einzeln in OCR1AL und
OCRA1H beschrieben werden ?
Ist schon was länger her, als ich AVRs benutzt habe.
dasrotemopped schrieb:>>extern void MOTOR_PWM (uint16_t A, uint16_t B);> Schlüsselwort EXTERN vor einer Funktionsdeklaration kommt mir> seltsam vor.
EXTERN ist auch kein SChlüsselwork; extern aber wohl.
> Was soll damit erreicht werden?
MOTOR_PWM hat external linkage. Siehe etwa C99 §6.2.2 Linkage of
Identifiers, Clause 5.
Also wenn ich A und B als je als uin8_t angebe ändert sich nix.
mache ich es als AH und AL und füge die anschließend zusammen passiert
auch nix anders.
dasrotemopped schrieb:> A ist 16 bit, muss auf einem 8bitter OCR1A nicht einzeln in OCR1AL und> OCRA1H beschrieben werden ?
Nein. Das ist ein Grund, C zu verwenden und nicht Assembler :-)
dasrotemopped schrieb:> A ist 16 bit, muss auf einem 8bitter OCR1A nicht einzeln in OCR1AL und> OCRA1H beschrieben werden ?
Da passt der Compiler auf dich auf und macht es in der richtigen
Reihenfolge.
dasrotemopped schrieb:>>extern ist für den Compiler nur ein Hinweis das die Funktion anderweitig> noch benutzt wird.> eher nicht. das ist laut meinem Kernighan/Ritchie für Variablen, nicht> Funktionen.> Darum vermute ich, das dein Programm ein Problem mit der Sichtbarkeit> von Variablen hat.>>>*** Globale Variablen ***>>uint16_t abstand = 0,rechts =0,links =0;>> Global verstehst du warscheinlich auch anders als C.>> void MOTOR_PWM (uint16_t A, uint16_t B)> {> OCR1A = A;> OCR1B = B;> }>> A ist 16 bit, muss auf einem 8bitter OCR1A nicht einzeln in OCR1AL und> OCRA1H beschrieben werden ?> Ist schon was länger her, als ich AVRs benutzt habe.
extern gibt die Speicherklasse an und bei einer Funktionsdeklaration ist
"extern" der Default, deshalb kann man ihn auch weglassen. Manche
Programmierer schreiben den "extern" Klassifizierter explizit mit in die
Funktionsdeklaration, um die Lesbarkeit zu verbessern.
Ein anderer Klassifizierer bei einer Funktionsdeklaratin wäre
"static"..und jetzt kannst du mal raten, was der Unterschied zwischen
extern und static ist ;-)
Johann L. schrieb:> dasrotemopped schrieb:>>>extern void MOTOR_PWM (uint16_t A, uint16_t B);>> Schlüsselwort EXTERN vor einer Funktionsdeklaration kommt mir>> seltsam vor.> EXTERN ist auch kein SChlüsselwork; extern aber wohl.>>> Was soll damit erreicht werden?>> MOTOR_PWM hat external linkage. Siehe etwa C99 §6.2.2 Linkage of> Identifiers, Clause 5.
Nur mal so aus Interesse eines C-Standard-Juristen und weil Du hier
einer der ausgefuchsteren C-Standard-Juristen bist.
Willst Du damit sagen, dass MOTOR_PWM ohnehin (also ohne das
extern-Schlüsselwort) external linkage hat, also das Schlüsselwort
überflüssig ist? So verstehe ich Absatz 5:
"5 If the declaration of an identifier for a function has no
storage-class specifier, its linkage is determined exactly as if it were
declared with the storage-class specifier extern. If the declaration
of an identifier for an object has file scope and no storage-class
specifier, its linkage is external."
(Hervorhebungen von mir).
Oder, willst Du lediglich erklären, was die Wirkung ist? Das ist
zweifellos so richtig. Wobei man noch erwähnen könnte, dass das
Schlüsselwort "extern" redundant ist.
Oder willst Du weder das eine noch das andere damit sagen?
Irgendwie irritiert mich das extern - habe ich in 30 Jahren weder
verwendet noch vermisst (in Bezug auf Funktionen).
Es gibt entweder einen Prototyp; und der ist dann implizit extern, falls
er nicht durch eine Definition in der selben Datei ersetzt wird. Oder er
ist faktisch extern und der Linker meckert, falls er nicht doch noch
irgendwo anders (in einem Objekt) die Definition entdeckt.
Aber mit dem Problem des TO scheint mir das alles nichts zu tun zu
haben.
nicht geraten, im C/C++ Referenz Buch nachgelesen (tatsächlich nicht
gegooglet):
"Soll der Zugriff auf die Funktion nur aus Funktionen innerhalb des
aktuellen Moduls heraus erfolgen dürfen, müssen Sie static angeben."
Raten ist nicht so meins ...
Deuter des Willens K&Rs schrieb:> Willst Du damit sagen, dass MOTOR_PWM ohnehin (also ohne das> extern-Schlüsselwort) external linkage hat, also das Schlüsselwort> überflüssig ist?
Genau so ist es. Bei Funktionsdeklarationen ist "extern" implizit, es
eigens hinzuschreiben überflüssig aber auch nicht störend.
Rufus Τ. F. schrieb:> Deuter des Willens K&Rs schrieb:>> Willst Du damit sagen, dass MOTOR_PWM ohnehin (also ohne das>> extern-Schlüsselwort) external linkage hat, also das Schlüsselwort>> überflüssig ist?>> Genau so ist es. Bei Funktionsdeklarationen ist "extern" implizit, es> eigens hinzuschreiben überflüssig aber auch nicht störend.
So sehe ich das auch (und schrieb das auch).
Meine Frage war, wie Johann das gemeint, was er mit seinem Beitrag
beabsichtigt hat. Das selbe was ich denke, oder was anderes oder mehr?
Sagen wir mal, weil ich Johann zutraue, etwas auszusagen, was auch ich
so sagen würde, aber das er damit etwas Anderes oder Zusätzliches sagen
will, was ich nicht so sagen würde.
Kurz: Vielleicht kann ich da noch was lernen, was zwar nicht im
Gegensatz zu meiner Ansicht steht, sie aber erweitert.
Also die USART.h als auch die HC_SR_04.h laufen eigentlich ohne Probleme
hab sie schon in meheren Projekten drin ohne das dort ein fehler erzeugt
wird.
Sebi schrieb:> Hab mal weiter rum probiert, also SOLO läuft die MOTOR_PWM
In Summe denke ich, kann man plausibel vermuten, dass das Problem durch
das bisher gezeigte von Deinem Code nicht verursacht wird. Zwar gibt es
einige technisch etwas fragwürdige Details, aber sie sind nicht wirklich
mit Deinem Problem in Verbindung zu bringen.
Ich schlage Dir vor, einmal das gesamte Projekt (je nach IDE also
kompletten Projektpfad, makefiles etc. - Backupfiles der Editoren vorher
löschen) als ZIP zu posten. Einmal in der Variante die geht und einmal
in der Variante die nicht geht.
Dann kann das hier vielleicht jemand mal nachvollziehen - zumindest was
das Compilieren und Linken angeht.
Also jetzt versteh ich die Welt nicht. benutze ich alle 3 .h läuft es
jetzt sobald ich jede if oder else auskommentiere.
setzte ich die void MOTOR_PWM einfach ins hauptprogramm läuft es auch
mit if else.
Bau doch mal an verschiedenen Stellen Meldungen oder Fehler ein. Dann
kannst Du feststellen ob der Compiler überall hinkommt.
Hast Du mal alle Zwischendateien gelöscht oder explizit einen rebuild
all angestoßen?
Poste doch mal den Compileroutput.
------ Build started: Project: AUTONOM16AV1.22, Configuration: Debug AVR
------
Build started.
Project "AUTONOM16AV1.22.cproj" (default targets):
Target "PreBuildEvent" skipped, due to false condition;
('$(PreBuildEvent)'!='') was evaluated as (''!='').
Target "CoreBuild" in file "F:\Softwareentwicklung\Atmel Studio
7\7.0\Vs\Compiler.targets" from project
"G:\AtmelStudio\AUTONOM16AV1.22\AUTONOM16AV1.22\AUTONOM16AV1.22.cproj"
(target "Build" depends on it):
Task "RunCompilerTask"
Shell Utils Path F:\Softwareentwicklung\Atmel Studio
7\7.0\shellUtils
F:\Softwareentwicklung\Atmel Studio 7\7.0\shellUtils\make.exe all
--jobs 4 --output-sync
make: Nothing to be done for 'all'.
Done executing task "RunCompilerTask".
Task "RunOutputFileVerifyTask"
Program Memory Usage : 1324 bytes 8,1 % Full
Data Memory Usage : 81 bytes 7,9 % Full
Done executing task "RunOutputFileVerifyTask".
Done building target "CoreBuild" in project "AUTONOM16AV1.22.cproj".
Target "PostBuildEvent" skipped, due to false condition;
('$(PostBuildEvent)' != '') was evaluated as ('' != '').
Target "Build" in file "F:\Softwareentwicklung\Atmel Studio
7\7.0\Vs\Avr.common.targets" from project
"G:\AtmelStudio\AUTONOM16AV1.22\AUTONOM16AV1.22\AUTONOM16AV1.22.cproj"
(entry point):
Done building target "Build" in project "AUTONOM16AV1.22.cproj".
Done building project "AUTONOM16AV1.22.cproj".
Build succeeded.
========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped
==========
Deuter des Willens K&Rs schrieb:> Rufus Τ. F. schrieb:>> Genau so ist es. Bei Funktionsdeklarationen ist "extern" implizit, es>> eigens hinzuschreiben überflüssig aber auch nicht störend.>> So sehe ich das auch (und schrieb das auch).> Meine Frage war, wie Johann das gemeint, was er mit seinem Beitrag> beabsichtigt hat. Das selbe was ich denke, oder was anderes oder mehr?
Ich woollte lediglich klarstellen, dass das extern absolut ok ist und
der TO nicht daran rundokern muss, nur weil dasrotemopped rumrät.
Mal so eine frage am Rande könnte mal einer von euch auch mal das was
nicht funktioniert in der Simulation fahren?
bei mir stehen da OCR2 , OCR1A, OCR1B dauerhaft auf 0
Ich nehme an, Du hast auch schon probiert, die Funktion in der
zusätzlichen Datei durch ein Zeichen umzubenennen und die
Originalfunktion in main.c zusätzlich zu belassen. (so das wirklich nur
der Ort der Funktion unterschiedlich ist.)
Wenn es dabei funktioniert, bleibt nur:
dasrotemopped schrieb:> Darum vermute ich, das dein Programm ein Problem mit der Sichtbarkeit> von Variablen hat.
und zwar, dass (aus welchen Gründen auch immer) OCR1A oder B (eine
Header fehlt) an anderer Stelle gemappt wird. Korrektur: den kompletten
Code bis zum letzten #include aus main.c auch in die neue C übernehmen,
egal ob alles gebraucht wird. Falls nicht ok, auch das Makefile
überprüfen.
Sebi schrieb:> ------ Build started: Project: AUTONOM16AV1.22, Configuration: Debug AVR> ------> Build started.
[...]
> Build succeeded.> ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped> ==========
Es scheint so, als wenn Du kein Rebuild gestartet hast, sondern das
Projekt schon "Up to date" war. Daher wird auch kein C-Compiler oder
Linker aufgerufen. Und daher kann man auch keine Fehler oder Warnings
sehen, noch die verwendeten Optionen.
Entweder Du lädst alle Source-Dateien und fügst überall eine Leerzeile
oder so ein. (Irgendwas neutrales halt). Oder Du startest ausdrücklich
ein "Rebuild". Was Dir leichter fällt.
Ich habe leider kein AVRStudio 7 und werde es mir, solange ich es
vermeiden kann, auch nicht installieren. Daher kann ich Deine Projekte
nicht kompilieren. Tut mir leid.
Aber vielleicht findet sich ja jemand.