Forum: Mikrocontroller und Digitale Elektronik AVR-Studio 5 Fehlermeldung


von Jimmy (Gast)


Lesenswert?

Hallo Leute

ich habe gerade das AVR-Studio 5 installiert und wollte mich in die 
C-Programmierung einarbeiten. Als Test habe mal ein einfaches Programm 
aus dem Internet geladen um einen Einstieg zu finden. Beim Compalieren 
bekomme ich folgenden Fehler: "invalid storage class for function 
_delay_loop_1"
Der Fehler bezieht sich auf die Datei DELAY_BASIC.h
Kann mir mal bitte jemand diesen Fehler erklären?
/*
 * ATtiny13 LED Flasher
 * File: main.c
 */
#include <stdlib.h>
#include <util/delay.h>
int main(void)
{
    const int msecsDelayPost = 100;

    // Set up Port B pin 4 mode to output
    DDRB = 1<<DDB4;

    // Set up Port B data to be all low
    PORTB = 0;

    while (1) {
        // Toggle Port B pin 4 output state
        PORTB ^= 1<<PB4;

        // Pause a little while
        _delay_ms (msecsDelayPost);
    }
    return 0;
}

von Hartmut G. (Gast)


Lesenswert?

> #include <stdlib.h>

Wenn ich mich nicht täusche, ist die für C++, daher wohl auch die 
Fehlermeldung mit "Storage class...". Meinst Du evtl. die <stdint.h>?

von Jimmy (Gast)


Lesenswert?

Ich habe den Code kopiert und wollte nur daraus lernen, keine Ahnung ob 
die <stdlib.h> falsch ist. Der Code soll für den Attiny13 sein und 
stammt von dieser Seite:
http://brownsofa.org/blog/archives/191
Die Fehlermeldung muß doch zu erklären sein.....

von ... (Gast)


Lesenswert?

Der Code ist ziemlicher Mist.
Die stdlib.h könntest Du drin lassen, das sind z.B. itoa/utoa/... usw. 
drin, brauchen tust Du sie nicht. Fehlen tut aber auf jeden Fall:
1
#include <avr/io.h>
Und _delay_ms mit einer Variablen aufzurufen ist gar keine gute Idee.
Versuch mal folgenden Code:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
4
static void var_delay_ms(unsigned int ms)
5
{
6
  while(ms) {
7
    _delay_ms(1);
8
    ms--;
9
  }
10
}
11
12
int main(void)
13
{
14
    const int msecsDelayPost = 100;
15
16
    // Set up Port B pin 4 mode to output
17
    DDRB = 1<<DDB4;
18
19
    // Set up Port B data to be all low
20
    PORTB = 0;
21
22
    while (1) {
23
        // Toggle Port B pin 4 output state
24
        PORTB ^= 1<<PB4;
25
26
        // Pause a little while
27
        var_delay_ms(msecsDelayPost);
28
    }
29
    return 0;
30
}
Irgendwo muß aber noch das Makro F_CPU definiert werden. Keine Ahnung, 
wo das im AS5 gemacht wird, im AS4 gibt es extra eine Einstellung in den 
Projektsettings dafür. Im Notfall schreib noch folgende Zeile an den 
Anfang (vor die #include..):
1
#define F_CPU  1000000ul
Falls Dein AVR mit einer anderen Frequenz als 1MHz läuft mußt Du die 
Zahl entsprechend anpassen.
Vergiß auch nicht den korrekten AVR im AS5 auszuwählen.

PS: Heißt denn Deine Datei tatsächlich "main.c" mit kleinem C am Ende?

von Jimmy (Gast)


Lesenswert?

Danke

dein Code funktioniert fehlerfrei. Und warum sollte man _delay_ms nicht 
mit einer Variable aufrufen?

von ... (Gast)


Lesenswert?

Jimmy schrieb:
> Und warum sollte man _delay_ms nicht
> mit einer Variable aufrufen?

Man sollte halt auch mal die Doku lesen!
Zitat von 
http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html
1
In order for these functions to work as intended, compiler optimizations
2
must be enabled, and the delay time must be an expression that is a known
3
constant at compile-time. If these requirements are not met, the resulting
4
delay will be much longer (and basically unpredictable), and applications
5
that otherwise do not use floating-point calculations will experience
6
severe code bloat by the floating-point library routines linked into the
7
application.

PS: Die Doku zur AVR Libc sollte sich auch irgendwo in den 
Installationsverzeixhnissen von AS5 auf Deiner Platte befinden.

von Jimmy (Gast)


Lesenswert?

... schrieb:
> and the delay time must be an expression that is a known
> constant at compile-time

Die Variable ist nach meinem Verständnis als Constante definiert und 
damit sollte das doch o.k. sein?
Wie gesagt, ich möchte mich in das Thema einarbeiten und wollte mit dem 
ersten Code nur mal eine Lernvorlage haben. Desshalb habe ich auch noch 
nicht jede Doku gelesen bzw. verstanden.
Den ursprünglichen Fehler war habe ich auch noch nicht verstanden. Es 
stellen sich immer mehr fragen. Das oben genannte Makro F_CPU soll 
scheinbar die aktuelle Frequenz sein, aber warum heisst es hier Macro? 
Oder habe ich das falsch verstanden?

von ... (Gast)


Lesenswert?

Jimmy schrieb:
> Die Variable ist nach meinem Verständnis als Constante definiert und
> damit sollte das doch o.k. sein?

Nee, böse Falle, das gilt nur für C++ nicht für C !!! Siehe z.B. letzter 
Abschnitt "Differences with C":
http://www.mi.uni-koeln.de/c/mirror/www.codeguru.com/cpp/tic/tic_html.zip/tic0092.html

Jimmy schrieb:
> Den ursprünglichen Fehler war habe ich auch noch nicht verstanden.

Die genaue Ursache kann ich Dir jetzt auch nicht sagen, dazu müßte man 
sich mal ansehen, was der Preprozessor aus Deinem ursprünglich Code 
gemacht hat (z.B. via -save-temps Option vom GCC). Das Ergebnis war dann 
jedenfalls, daß aufgrund fehlender defines/typedefs/wasauchimmer aus der 
im Fehler angegeben Stelle in delay_basic.h ein ungültiges C-Konstrukt 
wurde.

Jimmy schrieb:
> Das oben genannte Makro F_CPU soll scheinbar die aktuelle Frequenz sein

Genau, die delay Funktionen brauchen diesen Wert um auszurechnen, 
wieviele Prozessortakte gewartet werden muß. Und deshalb muß es auch vor 
dem #include <util/delay.h> stehen.

Jimmy schrieb:
> aber warum heisst es hier Macro?

Weil man #define nun mal Makros definiert :)
Das es davon zwei unterschiedliche Sorten gibt (object-like und 
function-like) spielt dabei keine Rolle.
http://en.wikipedia.org/wiki/C_preprocessor

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
Noch kein Account? Hier anmelden.