Hallo an alle,
ich muss ein Projekt verwirklichen, das die Programmierung eines µC
(Atmel 89C51CC03) beinhaltet.
Als Compiller verwende ich Kyle µVision 3.
In diesem Projekt muss ich zum ersten mal mit Klassen und Ponter
Arbeiten.
Wenn ich nun mein Code übersetzen lasse, bringt mir Kyle ein Fehler, den
ich nicht beseitigen kann.
Hier mein Programm das sehr einfach gehalten ist. Es dient lediglich
dazu, Klassen und Pointer zu verstehen und anwenden zu können:
#include "at89c51cc03.h"
#include <stdio.h>
class ADC
{
private:
public:
ADC() //Konstruktor
{
}
Berechnung (int *a) //Funtkion Berechnung
{
*a++ //Wert in a um 1 erhöhen
}
~ADC() //Destruktor
{
}
};
void main()
{
while (1) //Endlosschleife
{
int a; //Variable a als int initalisieren
a=0;
ADC ADCclass; //Der Klasse ADC ein Namen zuweisen
ADCclass.Berechnung(&a); //Funktion Berechnung aufrufen
P1=0x33; //Wert 33 an Port 1 ausgeben
P3=a; //Wert aus a an Port 3 ausgeben
}
}
Fehlerbeschreibung laut Kyle:
main.c(7): error C129: missing ';' before 'ADC'
(Klasse ADC wird mit Pfeil angezeigt)
Kann mir jemand bei diesem Problem helfen?
Habe ich die Pointer richtig eingesetzt?
Vielen Dank für die Hilfe.
Sascha K. wrote:
> main.c(7): error C129: missing ';' before 'ADC'
******
Eine Datei mit der Endung *.c wird von den meisten Compilern
als C-Source Code betrachtet. In C gibt es aber keine Klassen
bzw. was du willst ist eigentlich der C++ Compiler.
-> Im Handbuch des Compilers nachsehen, wie du ihn dazu bringst
das ganze als C++ aufzufassen. Bei vielen Compilern genügt
es die Dateiendung auf *.cpp zu ändern.
> Habe ich die Pointer richtig eingesetzt?
Grundsätzlch ja.
Sascha K. wrote:
> Als Compiller verwende ich Kyle µVision 3.
Noch nie davon gehört, haste mal nen Link darauf?
Ich kenne nur Keil µVision 3 für 8051.
Und da bin ich mir zu 99,9999% sicher, daß der garkein C++ kann.
Peter
Danke für die schnelle Antwort.
Ja ich meine Keil µVision3. Habe es falsch geschrieben.
Ok dann wird es klar warum es nicht funktioniert.
Danke nochmal.
Ich schreibe mein Programm in Keil µVision 3 und zur Übertragung auf
mein AT89C51CC03 verwende ich das Tool Flip von Atmel.
Ich muss nicht unbeding mit Klassen Arbeiten. Funktionen genügen auch.
Ich wollte aber Testen, ob es mit Klassen funktionieren würde damit ich
ein besseres Verständniss für die ganze Thema bekomme.
Ich wollte wissen, was funktionieren würde und was nicht. Das Keil kein
cpp kann wusste ich nicht.
Nun habe ich aber eine andere Frage: Kann ich hier überhaupt mit Pointer
arbeiten?
Der hintergrund sieht so aus:
Der µC hat 8 interne AD Wandler. Die Wandlung wird in einer Funktion
realisiert.
Ich will nun aus meinem main auf die gewandelten Werte in der Funtion
zugreifen. Das wollte ich über Pointer machen.
Ist das überhaupt möglich?
Entschuldigung für die vielen Fragen aber ich will das Thema selber
kapieren und mir nicht die Lösung irgendwo her holen.
@die ???
Danke für Info bezüglich dem Semikolon. Das hat aber auch keine Änderung
ergeben.
Hallo Sascha,
Du kannst doch mit Funktionen mit Übergabewert (=Kanal-Nr) und
Rückgabewert (=Messwert) arbeiten, wenn Du die Kanäle einzeln
nacheinander wandelst.
Willst Du in der Funktion alle Kanäle auf einmal wandeln, dann nimm
einfach globale Variablen(Feld) zum Abspeichern der Messwerte. Auf diese
Variablen kannst Du dann von überall her zugreifen.
Viele Grüße
Carlos
Sascha K. wrote:
> Der µC hat 8 interne AD Wandler. Die Wandlung wird in einer Funktion> realisiert.> Ich will nun aus meinem main auf die gewandelten Werte in der Funtion> zugreifen. Das wollte ich über Pointer machen.> Ist das überhaupt möglich?
Pointer sind auch in C möglich.
Du kannst allerdings auch einfach den ADC-Wert als Returnwert von der
Funktion übergeben lassen.
Dann muß der Compiler nicht umständlich mit Pointern rechnen, sondern
hat den Wert gleich in Registern (R6,R7).
Peter
@Peter
Return Wert geht leider nicht weil ich in der Funktion mehrere
Rückgabewerte habe.
@Carlos
Ich würde gerne die gesammte Wanndlung in einer Funktion haben. Dann
gestaltet sich die Rückgabe etwas schwerer.
Globale Variablen wären mir am liebsten. Das habe ich auch schon
getestet aber habe es nicht zum laufen gebracht.
Mein Problem ist, das ich bis jetzt nur in Visual Studio gearbeitet habe
und Werte über das Ausgabefenster angezeigt habe.
Das Programmieren für µC ist doch etwas anderst. Oft sind es nur
Kleichnichkeiten aber die machen es eben aus.
So nun mal ein Beispiel von mir zu Pointer das aber so leider
nicht läuft:
#include "at89c51cc03.h"
#include <stdio.h>
unsigned int value_AN3=0x0000;
extern void umwandlung (int);
void main(void)
{
while(1)
{
umwandlung(&value_AN3);
P3=value_AN3;
}
}
Nun die Ausgelagerte Funktion (AD Wandlung meines µC)
#include "at89c51cc03.h"
#include <stdio.h>
unsigned int value_converted=0x0000;
bit end_of_convertion=0;
void umwandlung (int *value_AN3){
ADCF = 0xFF;
ADCLK = 0x06;
ADCON = 0x20;
EA = 1;
EADC = 1;
ADCON &= ~0x07;
ADCON |= 0x06;
ADCON &= ~0x40;
ADCON |= 0x08;
while(!end_of_convertion);
end_of_convertion=0;
*value_AN3=value_converted;
}
Diese Funktion ist so vom Hersteller vorgegeben aber ich kann sie an
meine Ansprüche anpassen.
Den Namen der Funktion umwandlung habe ich selber vergeben.
Die ganze AD Wandlung funktioniert so. Das habe ich schon getestet (ich
arbeite dann mit Rückgabewert)
Aber sobald ich mit Pointer Arbeite (siehe oben) funktioniert es nicht
mehr.
Sascha K. wrote:
> Ich würde gerne die gesammte Wanndlung in einer Funktion haben. Dann> gestaltet sich die Rückgabe etwas schwerer.> Globale Variablen wären mir am liebsten. Das habe ich auch schon> getestet aber habe es nicht zum laufen gebracht.
? Da muss ich mich aber schon wundern. Globale Variablen sind so
ziemlich das Primitivste was man sich vorstellen kann.
> Mein Problem ist, das ich bis jetzt nur in Visual Studio gearbeitet habe> und Werte über das Ausgabefenster angezeigt habe.> Das Programmieren für µC ist doch etwas anderst. Oft sind es nur> Kleichnichkeiten aber die machen es eben aus.
Nicht wirklich. Die grundlegenden Mechanismen, wie Parameterübergabe,
Werte retournieren funktionieren auf allen C-Systemen gleich. Muss
auch so sein, denn schliesslich ist die Sprache ja genormt.
> Aber sobald ich mit Pointer Arbeite (siehe oben) funktioniert es nicht> mehr.
Vergleich mal Folgendes:
In main.c steht:
1
externvoidumwandlung(int);
Dort wird also behauptet, die Funktion umwandlung bekommt einen int
übergeben.
In deinem 2-ten File steht aber
1
voidumwandlung(int*value_AN3)
Die Funktiohn umwandlung will einen Pointer auf int.
Was gilt den nun? Die Funktion kann ja nicht gleichzeitig
wahlweise einen int oder einen Pointer auf int erhalten.
Wenn du deinen Compiler anlügst, darfst du dich nicht wundern ...
Wie kann programmieren, dass man so einen Fehler kein 2-tes mal
macht?
Die Lösung dafür sind Header Files.
Du schreibst den Protoyp nicht direkt in main.c hinein, sondern
ziehst ihn über ein Header File hinein.
Umwandlung.h
************
1
voidumwandlung(int*value_AN3);
(Das extern braucht an dieser Stelle kein Mensch)
main.c:
*******
1
#include"at89c51cc03.h"
2
#include<stdio.h>
3
#include"umwandlung.h" // <---- hier kommt der Protoyp für die Funktion
4
5
unsignedintvalue_AN3=0x0000;
6
7
voidmain(void)
8
{
9
while(1)
10
{
11
umwandlung(&value_AN3);
12
P3=value_AN3;
13
}
14
}
und ganz wichtig: In deinem File, in dem die Funktion residiert,
ziehst du ebenfalls den Protoypen rein.
1
#include"at89c51cc03.h"
2
#include<stdio.h>
3
#include"umwandlung.h" // <--- hier ebenfalls der Protoyp
4
5
unsignedintvalue_converted=0x0000;
6
bitend_of_convertion=0;
7
8
voidumwandlung(int*value_AN3){
9
10
ADCF=0xFF;
11
ADCLK=0x06;
12
ADCON=0x20;
13
EA=1;
14
EADC=1;
15
16
ADCON&=~0x07;
17
ADCON|=0x06;
18
ADCON&=~0x40;
19
ADCON|=0x08;
20
while(!end_of_convertion);
21
end_of_convertion=0;
22
*value_AN3=value_converted;
23
}
Dadurch kann der Compiler vergleichen, ob der Protoyp mit der
tatsächlichen Funktion übereinstimmt und gegebenenfalls einen
Fehler melden.
Karl heinz Buchegger wrote:
> Sascha K. wrote:>>> Ich würde gerne die gesammte Wanndlung in einer Funktion haben. Dann>> gestaltet sich die Rückgabe etwas schwerer.>> Globale Variablen wären mir am liebsten. Das habe ich auch schon>> getestet aber habe es nicht zum laufen gebracht.>> ? Da muss ich mich aber schon wundern. Globale Variablen sind so> ziemlich das Primitivste was man sich vorstellen kann.
Auch haben Probleme, vor denen man davonläuft, die unangenehme
Eigenschaft, einen ständig wieder einzuholen und dabei jedesmal größer
zu werden.
Globale Variablen müssen funktionieren, das sind Grundlagen ohne die Du
das Programmieren gleich an den Nagel hängen kannst.
Frag ruhig, wenn Du eine Fehlermeldung nicht verstehst.
Peter
@ Herr Karl heinz Buchegger
Vielen Dank für ihre Hilfe.
Mit einer Headerdatei funktioniert alles wunderbar.
Vielen Dank für ihre Infos und Tipps.
Ab jetzt Arbeite ich immer mit Header.
@ Herr Peter Dannegger
Ich werde mich an die globalen Variablen machen.
Ich werde ein paar Übungen programmieren um mich damit vertraut zu
machen.
Aus meinem main konnte ich auf die globalen Variablen zugreifen.
Ich hatte aber Probleme, wenn ich von meinen ausgelagerten Funktionen
darauf zugreifen wollte.
Im Grunde ist das sehr simpel, wenn man eine Regel beachtet:
Es darf immer nur eine Definition einer globalen Variablen geben.
Die muss es dann aber auch geben.
Mittels extern teilt man dem Compiler mit, dass eine Variable
irgendwo anders existiert, aber diesen und jenen Datentyp
hat. So was ist dann eine Deklaration. Und davon darf es beliebig
viele geben.
Bsp:
foo.c
*****
1
externintVar1;// Var1 existiert und ist vom Typ int
2
3
voidfoo()
4
{
5
Var1=5;// da der Compiler weiß, dass es Var1 gibt
6
// geht das auch gut. Var1 existiert (könnte
7
// ja auch ein Tippfehler sein) irgendwo anders
8
}
main.c
******
1
intVar1;// und hier existiert die Variable Var1 tatsächlich
2
3
voidfoo(void);
4
5
intmain()
6
{
7
Var1=0;
8
foo();// foo setzt Var1 auf 5
9
}
Auch globale Variablen sind heisse Kandidaten für Header Files
denn eines muss klar sein. Die Definition und die Deklaration
müssen unbedingt im Datentyp übereinstimmen!
In der Praxis macht man das dann so
global.h
********
1
externintVar1;
foo.c
*****
1
#include"global.h" // dadurch bekommt man die Deklaration
2
// von Var1 hereingezogen
3
4
voidfoo()
5
{
6
Var1=5;
7
}
main.c
******
1
#include"global.h" // bringt wieder die Deklaration herein
2
// bis jetzt existiert die Variable
3
// aber noch nicht. Das wird jetzt
4
// nachgeholt
5
intVar1;
6
7
voidfoo(void);
8
9
intmain()
10
{
11
Var1=0;
12
foo();
13
}
Dadurch, dass in main.c wiederrum beides vorhanden ist, Deklaration
und Definition, gibt man dem Compiler wiedrrum die Möglichkeit zu
überprüfen, ob beides übereinstimmt.
Das ging aber sehr schnell. Vielen Dank.
Ich hab ein ähnliches Beispiel wie Sie geschrieben mit Header. Jedoch
ohne das extern bei int Var1.
Aus diesem Grund hatte ich Fehlermeldungen und das Programm lief nicht.
Nach dem ich ihren Beitrag gelesen habe, habe ich einfach das extern
hinzugefügt und es lief.
Ich möchte mich nochmals bei Ihnen für die schnelle und sehr gut
beschriebene Hilfe danken.
Ich habe jetzt einiges an meinem Programm verändert.
Dabei bin ich jetzt noch auf etwas gestoßen.
Beispiel:
header.h
********
extern unsigned int ch0;
main.c
******
#include <header.h>
void main ()
{
funktion (&ch0)
}
Ich will eine Variable (ch0) im header als globale Variable
initialisieren.
Im main will ich per Pointer die Variable ch0 an eine Funktion
weitergeben.
Nun bekomme ich aber ein Warnung und das Programm ist nicht lauffähig.
Ist es überhaupt möglich, eine globale Variable über ein Ponter im main
an eine ausgelagerte Funktion weiter zu geben?
Sascha K. wrote:
> Beispiel:>> header.h> ********> extern unsigned int ch0;>>> main.c> ******> #include <header.h>>> void main ()> {> funktion (&ch0)> }>> Ich will eine Variable (ch0) im header als globale Variable> initialisieren.
Du hast im Header keine Variable definiert. Du hast im Header
lediglich bekannt gegeben, dass irgendwo eine derartige
Variable existieren würde.
Allerdings hast du in deinem Programm anscheinend vergessen,
die Variable auch tatsächlich anzulegen. Es reicht nicht
immer nur zu sagen, dass diese Variable schon irgendwo existieren
würde. Irgendwann muss sie auch tatsächlich erzeugt werden!
Aus Mangel an besseren Plätzen: Warum nicht im main.c
main.c
******
1
#include<header.h>
2
3
unsignedintch0;
4
5
voidmain()
6
{
7
funktion(&ch0)
8
}
> Nun bekomme ich aber ein Warnung und das Programm ist nicht lauffähig.
Es ist schon spät und meine Glaskugel ist schon abgeschaltet.
Verrätst du uns noch den Wortlaut der Warnung?
> Ist es überhaupt möglich, eine globale Variable über ein Ponter im main> an eine ausgelagerte Funktion weiter zu geben?
Sicher. Warum sollte das nicht gehen. Eine globale Variable ist
auch nur eine Variable. Und als solche hat sie eine Adresse im
Speicher.
Hallo Herr Buchegger,
das war wirklich das Problem. Ich hatte keine Variable direkt angelegt.
Ich dachte es würde reichen, wenn ich sie im Header anlege.
>Es ist schon spät und meine Glaskugel ist schon abgeschaltet.>Verrätst du uns noch den Wortlaut der Warnung?
Ich habe mit Absicht keine Fehlermeldung angegeben.
Ich wollte nur die Antwort auf meine obige Frage
(Ist es überhaupt möglich, eine globale Variable über ein Ponter im main
an eine ausgelagerte Funktion weiter zu geben?) und dann selber den
Fehler finden und mein Programm verbessern.
Meine Meinung ist, das man sowas nur richtig lernen und vorallem
versetehen kann, wenn man es selber macht. Wenn man die Lösung von
anderen bekommt, ist der Lerneffekt viel geringer als wenn man es selber
macht.
Sascha K. wrote:
> Ich habe mit Absicht keine Fehlermeldung angegeben.
Wenn Du diese im Original posten würdest und dazu das File im Anhang,
damit man die Zeilennummer zuordnen kann, dann:
1. bekommst Du schneller und besser Hilfe.
2. lernst Fehlermeldungen selber zu deuten.
Peter
> Ist es überhaupt möglich, eine globale Variable über ein Ponter im main> an eine ausgelagerte Funktion weiter zu geben?
Natürlich, macht aber wenig Sinn, wenn du immer die gleiche globale
Variable übergeben willst - die aufgerufene Funktion kann auch einfach
so darauf zugreifen.
Du hast vorher nur C++ programmiert, oder? Schau dir mal C genauer an.