mikrocontroller.net

Forum: Compiler & IDEs struct als volatile => syntax fehler ...


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Code sieht so aus:
struct time_t
{
  uint8_t hour;   // max 23
  uint8_t minute; // max 59
  uint8_t second; // max 59
};
 
volatile time_t actualtime;
Fehler vom WinAVR ist:

> "make.exe" all
avr-gcc -g -Wall -O2 -mmcu=atmega8    -c -o demo.o demo.c
In file included from demo.c:9:
demo.h:18: Fehler: Syntaxfehler vor "actualtime"
demo.h:18: Warnung: »int« ist Standardtyp in Deklaration von 
»actualtime«
demo.h:18: Warnung: Datendefinition hat keinen Typ oder Speicherklasse

Wo mache ich den Fehler ?
Kann ich ein struct nicht als volatile deklarieren ?
Danke,
Markus

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In C wird eine struct variable immer noch mit dem
Keyword 'struct' definiert.

volatile struct time_t actualtime;

time_t ist übrigens kein sehr guter Name, da es eine Standardstruktur
gleichens Namens gibt.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke ;)
Liegt einfach an dem volatile, sonst hätte ich's einfach so gemacht:
struct time_t
{
  uint8_t hour;   // max 23
  uint8_t minute; // max 59
  uint8_t second; // max 59
} actualtime;
Hmmm, geht denn auch:
volatile struct time_t
{
  uint8_t hour;   // max 23
  uint8_t minute; // max 59
  uint8_t second; // max 59
} actualtime;
????????????

Wobei ich aktuell schon wieder auf'm Schlauch stehe, weil nun:
void showtime(time_t mytime)
{
.....
folgenden Fehler produziert:

> "make.exe" all
avr-gcc -g -Wall -O2 -mmcu=atmega8    -c -o demo.o demo.c
demo.c:84: Fehler: Syntaxfehler vor numerischer Konstante

Irgendwie peil ich's gerade nicht mit den structs :(
Muß ich bei Übergabe das ganze als Pointer deklarieren, oder wo hängt 
gerade mein Verstand ?
Danke,
Markus

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void showtime(time_t mytime)

sollte besser
void showtime(struct time_t mytime)
heißen.

Bist Du Dir im Klaren darüber, daß bei diesem Funktionsaufruf die 
Struktur als Wert übergeben wird? Das bedeutet, daß die gesamte Struktur 
auf den Stack kopiert wird, was zu Problemen führen kann.

Am besten also
void showtime(struct time_t *pmytime)

  

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@rufus:
Das mit dem struct hatte ich schon probiert, hat den gleichen Fehler 
gebracht :(
Und Dein Tipp mit dem Pointer war ja meine Frage ;)
Allerdings scheint mir das der Compiler wegen etwas weiter oben in 
meinem Code meckert ...
Dann müßte der eigentliche Fehler hier irgendwo liegen, denn mehr ist 
nicht "über" der angemeckerten Funktion:
ISR(TIMER0_OVF_vect)
{
// key debouncing, wait ca. 100ms to store found keys
 if(newkeys &= PIND)
 {
  keytick++;
  if(keytick == 6) // IRQ ca. every 0,016 seconds => 6x ca. 100ms 
  {
    keytick=0;
    keyspressed ^= newkeys; // store the found new keys
  }
 }

// time in second
 timetick++;
 if(timetick == 61)
 {
  timetick=0;
  actualtime.second++;

  // debug LED:
  if(actualtime.second%2)
  {
    PORTC |= (1 << PC5);
    //toggle=0;
  }
  else
  {
    PORTC &= ~(1 << PC5);
    //toggle=1;
  }
 }

//compute time
 if(actualtime.second==60)
 {
   actualtime.second=0;
   
     // debug LED:
  if(actualtime.minute%2)
  {
    PORTB |= (1 << PB1);
    //toggle=0;
  }
  else
  {
    PORTB &= ~(1 << PB1);
    //toggle=1;
  }
   
   
   if(++actualtime.minute>59)
   {
     actualtime.minute=0;
   if(++actualtime.hour>23)
   {
     actualtime.hour=0;
   }
   }
 }
 
}
Das einzige was ich aktuell geändert habe ist die Einführung von den 
structs wegen der Übersichtlichkeit.
Vorher waren das einzelne Variablen und das alte Programm (ohne structs) 
läuft aktuell ohne Probs auf dem Mega8.
D.h. alle Sekunde toggelt die eine Debug-LED und jede Minute die zweite 
...
Keys sind noch nicht angeschlossen und der Fehler:

avr-gcc -g -Wall -O2 -mmcu=atmega8    -c -o demo.o demo.c
demo.c:84: Fehler: Syntaxfehler vor numerischer Konstante

deutet meiner Meinung nach auf die actualtime ?
Oder habe ich hier schon wieder einen Hammerfehler produziert ?
Danke,
Markus

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

stell doch mal dein komplettes Projekt hier ein. Dann kann jeder das mal 
durch seinen Compiler jagen und dir evtl. Fehler einfacher aufzeigen.

Matthias

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> avr-gcc -g -Wall -O2 -mmcu=atmega8    -c -o demo.o demo.c
> demo.c:84: Fehler: Syntaxfehler vor numerischer Konstante
<
> deutet meiner Meinung nach auf die actualtime ?

Kann keiner sagen, da wir nicht wissen welches denn nun
Zeile 84 ist. Und zum Durchsuchen bin ich jetzt zu faul.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Liegt einfach an dem volatile

Das ändert nichts am Problem: Deinen C Kenntnissen.
Wenn du eine Variable definierst und diese Variable vom
Datentyp eines struct ist, dann ist das Keyword 'struct'
obligatorisch.

Und da ist er schon wieder

> Wobei ich aktuell schon wieder auf'm Schlauch stehe, weil nun:
> void showtime(time_t mytime)
> {
> .....

Selber Fehler. mytime möchtest du vom Datentyp 'struct time_t' haben.
ALso musst du das auch hinschreiben:

void showtime( struct time_t mytime )
{
  ....

> Das mit dem struct hatte ich schon probiert, hat den gleichen Fehler
> gebracht :(

Mag sein. Aber aus einem anderen Grund.


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab' den Fehler gefunden.
Es lag nicht an meinem Code,
sondern einem Header, indem frech ein
#define mytime 0
 drinstand ...
Und ich hab' mich dauernd gewundert was er mit "numerischer Konstante" 
will ...
Nächstes mal werde ich mir ALLE Header im Projekt vorher ansehen.
Oder besser alle selber schreiben !
Danke trotzdem ;)
Bye,
Markus

P.S.: Ich hab's mir zu Herzen genommen, der struct sieht nun so aus
struct timestruct
{
  uint8_t hour;   // max 23
  uint8_t minute; // max 59
  uint8_t second; // max 59
};
 
volatile  struct timestruct actualtime;
und die Funktion nun so
void showtime(struct timestruct *pmytime)
{
 char buffer[2];
 lcd_gotoxy(0,0);
 lcd_puts("Time");
 lcd_gotoxy(0,1);
 itoa(pmytime->hour,buffer,10);
 lcd_puts(buffer);
 lcd_puts(":");
 itoa(pmytime->minute,buffer,10);
 lcd_puts(buffer);
 lcd_puts(":");
 itoa(pmytime->second,buffer,10);
 lcd_puts(buffer);
}

  

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, so ist das korrekte C Syntax.

Da aber das ewige schreiben von 'struct irgendwas'
einem schnell auf den Geist geht gibt es dafür eine
Möglichkeit das abzustellen (jetzt rückt er damit
raus :-)

Du kannst einen typedef machen.
Wie geht das?
Nun definier dir (in Gedanken) eine Variable von
diesem Typ:

  struct timestruct TimeStruct;

jetzt setzt du vor das ganze einen typedef

  typedef struct timestruct TimeStruct;

und schon hast du einen 'neuen Datentyp' definiert,
der 'TimeStruct' (also der Name der gedanklichen
Variable) heist und der gleichwertig zu struct timestruct
ist.

Damit kannst du jetzt schreiben:
struct timestruct
{
  uint8_t hour;   // max 23
  uint8_t minute; // max 59
  uint8_t second; // max 59
};

typedef struct timestruct TimeStruct;

volatile TimeStruct actualtime;

void showtime(TimeStruct *pmytime)
{
 char buffer[2];
 lcd_gotoxy(0,0);
 lcd_puts("Time");
 lcd_gotoxy(0,1);
 itoa(pmytime->hour,buffer,10);
 lcd_puts(buffer);
 lcd_puts(":");
 itoa(pmytime->minute,buffer,10);
 lcd_puts(buffer);
 lcd_puts(":");
 itoa(pmytime->second,buffer,10);
 lcd_puts(buffer);
}

und bist das ewige schreiben von 'struct' los.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Karl Heinz,
das ginge auch mit z.B.
#define MYSTRUCT struct mystruct
Weil ich ja inzwischen so ziemlich alle möglichen und unmöglichen 
C-Seiten und Tutorials abgegrast habe ...
Nur um dann festzustellen das ein lieber Kollege halt mal nebenbei via 
define meinen Variablennamen als Konstante definiert hat ...
Ich wollte es ja eigentlich in C++ machen, da lassen sich dann Klassen 
schön vererben usw., aber es muß ja der kleinste gemeinsame Nenner sein 
:(
Trotzdem danke für Eure Hilfe ;)
Jezt muß ich mir nur noch was für den Capture-Eingang beim timer1 
überlegen.
Gibt's da irgendwo ein passendes Tutorial in C ?
weil hier im Tutorial finde ich nur die zu setzenden Register und mit 
der Suche werde ich irgendwie nicht fündig :(
Es soll die Frequenz der fallenden Flanke gemessen werden, als Sensor 
kommt ein Schließer zum Einsatz, der den Pin auf GND zieht.
Soweit ich das verstanden habe wird der aktuelle Timerwert des Timer1 
ins ICR1 gespeichert, wenn der Capture auftritt.
Es geht bei mir um Frequenzen von 1Hz bis zu maximal 500Hz 
(Umdrehungsmessung eines Meßrades).
Dann müßte ich doch bei 1MHz Takt und 8bit Timer des Mega8 bei ca. 3906 
Timerdurchläufen ein Hz haben und bei ca. 8 (seeehr grob :( ) die 500 Hz 
haben, oder rechne ich falsch ?
Also sollte ein struct mit drei Werten, einer für aktuelle Frequenz, 
einer für 8bit Zähler bis 256 und einer für ca. 15 als Überlaufwert 
reichen ?
Gut sind dann nur 15*256=3840 statt 3906 :(
Die 1MHz sind aber leider vorgegeben :(
Hat jemand einen Tipp damit beim Capturen nicht ein paar Hz Abweichungen 
sind ?
Danke,
Markus

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus wrote:

> sondern einem Header, indem frech ein
#define mytime 0
> drinstand ...

Pah. :)

> Nächstes mal werde ich mir ALLE Header im Projekt vorher ansehen.

Naja, in solchen mysteriösen Fällen hilft es, sich die Ausgabe des
C-Präprozessors mal anzusehen.  Wenn du das Makefile-Template von
WinAVR benutzt, das hat dafür bereits eine Regel.  Wenn deine Datei
zum Beispiel "datei.c" heißt, kannst du die Ausgabe des Präprozessors
mit "make datei.i" erzeugen.

> volatile  struct timestruct actualtime;

"actual" gehört zu den sogenannten false friends.  Du meinst sicher
nicht die tatsächliche Zeit, sondern die gegenwärtige.  Die heißt
"currenttime".

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> #define MYSTRUCT struct mystruct

Ginge im gegenwärtigen Fall schon.

Nur irgendwann kommst du auf folgende Idee:

#define P_MYSTRUCT struct mystruct *
typedef struct mystruct * p_MyStruct;

Preisfrage: Welche Variable hat jetzt welchen Datentyp?

   P_MYSTRUCT a, b;
   p_MyStruct c, d;

Antwort:
  a ist ein Pointer auf struct mystruct, b ist ein struct mystruct
  c und d sind beides Pointer auf struct mystruct

Mit Makros vorsichtig sein!
Ein mögliches Problem hast du gerade am eigenen Leib erlebt.
Makros nimmt man nur wenns gar nicht anders geht.

> Soweit ich das verstanden habe wird der aktuelle Timerwert des Timer1
> ins ICR1 gespeichert, wenn der Capture auftritt.

ganz genau.

> 8bit Timer des Mega8

Moment, der Timer1 ist ein 16-Bit Timer.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl Heinz:
Deswegen hab' ich ja gerade den STRUCT drin gelassen ;)
Ich wette da werden ein paar "Spezialisten" gleich rummeckern und 
"optimieren" :(
Das ganze Projekt ist so eine typische eierlegende Wollmilchsau ...
Das Timer1 16bittig ist weiß ich ;)
Nur der soll gleichzeitig für zwei PWMs und den Capture herhalten, ich 
sehe schon wohin das führt -> voll an die Wand !
Die PWMs sind 8bit FAST-PWMs und wenn ich jetzt nicht 150%ig 
falschliege, bedeutet das das Timer1 als 8bit Timer bis 255 zählt, oder 
steh' ich gerade wieder auf'm Schlauch ?
Mal abgesehen davon das Cheffe von jemandem den Floh des DDS ins Ohr 
gesetzt bekommen hat :(
Gaaanz einfach mit 'ner Tabelle 'nen sauberen Sinus aus'm PWM zu geben 
...
Bis jetzt hat's nur dazu geführt das die 8KB FLASH schon mit 5KB voll 
sind und kein Sinus aus den PWMs kommt ...
Zum Glück nicht meine Baustelle, wobei mir übles schwant :(
Naja, der übliche Wahnsinn halt ...
Aprospos DDS via PWM, kennt jemand eine Webseite oder C-Beispiel ?
Der Funktionsgenerator hier hat ja ein R2R-DAC ;)
Wobei wenn ich die Werte statt ins Port-Register ins OCR-Register packe 
...
Oder bin ich da wieder vollkommen falsch ?
Mist ich mache schon wieder "vorauseilender Gehorsam" :(
Na mal sehen wohins führt ;)
Danke,
Markus

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die PWMs sind 8bit FAST-PWMs und wenn ich jetzt nicht 150%ig
> falschliege, bedeutet das das Timer1 als 8bit Timer bis 255 zählt,

:-)
Alles klar. Ich muss mich erst drann gewöhnen, dass du Timer1
schreibst wenn du eigentlich Timer0 meinst.

Passiert mir auch. "Rechts, rechts, rechts. Äh. Das andere Rechts"
:-)

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl Heinz:
Nee Nee, das ist schon der 16bit Timer1, nur im FAST-PWM Mode mit 8bit !
Also so initialisiert:
void initTimer1(void)
{
    // Timer1 8bit Fast PWM, toggle OCR1A/OCR1B when compare
    TCCR1A = (1 << WGM10) | (1 << WGM12) | (1 << COM1A0) | (1 << COM1B0);
    // Timer1 full clock, input noise cancel by capture pin
    TCCR1B = (1 << CS10) | (1 << ICNC1);
}
Und nun soll ein beliebiger (!) Sinus via Tabelle aus den PWMs kommen :(
Klar, ganz einfach nur die Stützstellen in der Tabelle berechnen und 
hintereinander ausgeben ...
Das es noch nichtmal geht, wenn die Sinustabelle einfach vollständig 
ausgegeben werden soll ist ja kein Grund erstmal dieses Problem 
anzugehen ...
Wie schon gesagt der ganz "normale" Wahnsinn ...
Aprospos Wahnsinn,
kann es sein das ich bei Port-C des Mega8 kein LCD anschließen kann ?
Es wird die Bibliothek von Peter Fleury benutzt und da bieten sich die 
sechs Pins des PortsC einfach sowas von an ;)
Initialisiert ist er wie folgt:
 // PortC LCD out
  DDRC = (1 << PC0) | (1 << PC1) | (1 << PC2) | (1 << PC3) | (1 << PC4) | (1 << PC5); 
und im lcd.h sind folgende Pins definiert und korrekt angeschlossen:
#define LCD_PORT         PORTC        /**< port for the LCD lines   */
#define LCD_DATA0_PORT   LCD_PORT     /**< port for 4bit data bit 0 */
#define LCD_DATA1_PORT   LCD_PORT     /**< port for 4bit data bit 1 */
#define LCD_DATA2_PORT   LCD_PORT     /**< port for 4bit data bit 2 */
#define LCD_DATA3_PORT   LCD_PORT     /**< port for 4bit data bit 3 */
#define LCD_DATA0_PIN    0            /**< pin for 4bit data bit 0  */
#define LCD_DATA1_PIN    1            /**< pin for 4bit data bit 1  */
#define LCD_DATA2_PIN    2            /**< pin for 4bit data bit 2  */
#define LCD_DATA3_PIN    3            /**< pin for 4bit data bit 3  */
#define LCD_RS_PORT      LCD_PORT     /**< port for RS line         */
#define LCD_RS_PIN       4            /**< pin  for RS line         */

#define LCD_RW_PORT      LCD_PORT     /**< port for RW line         */
#define LCD_RW_PIN       6            /**< pin  for RW line         */
#define LCD_E_PORT       LCD_PORT     /**< port for Enable line     */
#define LCD_E_PIN        5            /**< pin  for Enable line     */
Wo liegt mein Fehler ?
Danke,
Markus

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> sechs Pins des PortsC

Schon. Aber für das LCD brauchst du 7 Pins.
RW vom LCD muss ja schliesslich auch bedient werden :-)

Die Fleury-Lib benutzt das Busy-Flag vom LCD und um das
auszulesen, muss sie mit RW wackeln können :-)
Kann man aber auch umschreiben. Einfach die Abfrage des
Busy-Flags gegen eine kleine Warteschleife austauschen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.