Forum: Mikrocontroller und Digitale Elektronik AVR Atmelstudio 7 Projektfile Anleitung


von Warumname (Gast)


Lesenswert?

Hallo zusammen,
ich bin aktuell auf der Suche nach einer Anleitung zum erstellen eines 
Projektfiles in Atmel Studio 7. Gerne auch eine Anleitung generell zu 
Projektfiles. Ich arbeite mit C und AVR's.

Desweiteren schaffe ich es leider nicht Librarys in Atmel Studio 7 
hinzuzufügen.

Über Links zu Anleitungen oder Tipps würde ich mich sehr freuen.

Max

von Marco H. (damarco)


Lesenswert?

NewProjekt->example Project und im der Maske nach Device oder Board 
suchen.
Project aussuchen und den Anweisungen folgen -> fertig. Für das erste zu 
mindestens.

von warumname (Gast)


Lesenswert?

Ja soweit komme ich noch. Aber wie mache ich das jetzt wenn ich aus 
bereits bestehenden Dateien ein Projekt erstellen möchte?
Konkret geht es um die IRMP Libary. Ich möchte mich aber auch allgemein 
in den Aufbau einarbeiten.
Das Problem ist das in IRMP die fertige Projektdatei .aps ist und ich 
beim konvertieren in .atsln immer eine Fehlermeldung bekomme

von Kolja (Gast)


Lesenswert?

warumname schrieb:
> Das Problem ist das in IRMP die fertige Projektdatei .aps ist und ich
> beim konvertieren in .atsln immer eine Fehlermeldung bekomme

Warum läßt du dir alles aus der Nase ziehen?

- wie konvertierst du und womit?
- wie lautet die Fehlermeldung?

von Veit D. (devil-elec)


Angehängte Dateien:

Lesenswert?

Hallo,

also neues Projket ist ja nun wirklich einfach.
Datei > Neu > Projekt > auswählen ob man C oder C++ programmieren 
möchte, jeweils "Executable Projekt", Name vergeben, µC aussuchen, 
fertig.

Schwieriger ist es schon eigene oder fremde Libs einzubinden. Also wenn 
man diese immer mitschleppt von Version zu Version, gleichzeitig Backup 
der alten Version, dann liegen die Files ja immer im Projektordner. 
Diese Dateien auswählen damit sie erstmal generell verfügbar werden 
siehe Bild.

Diese inkludierst dann in " " statt in < >.

: Bearbeitet durch User
von Marco H. (damarco)


Lesenswert?

Du musst aber auch den Compiler die Verzeichnisse bekannt machen. Sonst 
gibt es beim übersetzen ein Problem.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

Marco meinst du mich?
Wenn ja, nö musste nicht. Die Files liegen in den Projetordnern, nicht 
in einem "zentralen" Lib Ordner. Wie im Bild dargestellt einfach 
hinzufügen und im Code inkludieren. Fertig. Das mache ich schon länger 
so.

Weil mir der Affentanz jedesmal die Projekteinstellungen zu ändern zu 
blöd ist. Also das was du meinst den Pfad für den Compiler bekannt 
machen. Das müsste zentral einstellbar sein und für alle Projekte gültig 
sein ohne das man das für jedes Projekt einzeln einstellen müßte.

: Bearbeitet durch User
von Marco H. (damarco)


Lesenswert?

Ja meinte ich ;). In der Regel weiß der Compiler nicht von deinen 
Verzeichnissen auch im Projekt Ordner nicht.  Wenn du diese aber mit 
Pfad inkludierst findet er diese die natürlich trotzdem.

Man vermeidet damit auch Konflikte wenn z.Bsp eine led.h mehrmals 
vorhanden ist. Bibliotheken haben aber in der Regel eine gewisse 
Struktur :) ../include/test/...

#include "test/led.h"
#include "test3/led.h"

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

warumname schrieb:
> Konkret geht es um die IRMP Libary. Ich möchte mich aber auch allgemein
> in den Aufbau einarbeiten.

Diese "Library" liegt im Source vor, ist also - aus der Sicht des 
Compilers - keine Library, sondern einfach Quellcode.

1. Erstelle ein neues Projekt mit einem main.c, die lediglich eine leere 
main-Funktion enthält.

2. Suche Die main.c im Explorer auf Deiner Platte

3. Kopiere irmp.c irmp*.h in dasselbe Verzeichnis, wo Du main.c gefunden 
hast.

4. Wähle Hinzufügen -> Neues Element, wie oben bereits auf dem Bild zu 
sehen ist.

5. Gebe dort irmp.c und irmp*.h an.

6. Füge in main.c oben ein: #include "irmp.h"

7. Fülle die Funktion main() mit Inhalt.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

Mensch Marco, ich verstehe deinen Einwand nicht so recht. Ich habe 
nichts falsches geschrieben. Ich habe per Bild gezeigt wie man den Pfad 
dem Projekt bekannt macht und geschrieben das mit " " inkludiert.

von Marco H. (damarco)


Lesenswert?

Alles ok ;)...

von warumname (Gast)


Lesenswert?

Danke für eure Anleitungen :) Mir ist es nun gelungen IRMP auf nem 
ATmega328 zum laufen zu bringen. Ist echt fantastisch was der Quellcode 
alles kann. Dazu hab ich einfach den eigentlich für den ATmega8 
gedacheten Code genommen. Ging wunderbar.

Nun möchte ich das ganze aber auf nen Attiny45 schreiben. Laut Wiki 
Artikel ist das kompatibel. Vom Platz her passts auch drauf. So wie ich 
das sehe ist im Beispielcode schon die Abänderung für Attinys enthalten. 
Trotzdem funktioniert es bei mir mit folgendem Code nicht:
1
/*---------------------------------------------------------------------------------------------------------------------------------------------------
2
 * irmp-main-avr.c - demo main module to test IRMP decoder on AVR
3
 *
4
 * Copyright (c) 2009-2016 Frank Meyer - frank(at)fli4l.de
5
 *
6
 * $Id: irmp-main-avr.c,v 1.2 2016/01/12 21:15:16 fm Exp $
7
 *
8
 * This demo module is runnable on AVRs
9
 *
10
 * ATMEGA88 @ 8 MHz internal RC      Osc with BODLEVEL 4.3V: lfuse: 0xE2 hfuse: 0xDC efuse: 0xF9
11
 * ATMEGA88 @ 8 MHz external Crystal Osc with BODLEVEL 4.3V: lfuse: 0xFF hfuse: 0xDC efuse: 0xF9
12
 *
13
 * This program is free software; you can redistribute it and/or modify
14
 * it under the terms of the GNU General Public License as published by
15
 * the Free Software Foundation; either version 2 of the License, or
16
 * (at your option) any later version.
17
 *---------------------------------------------------------------------------------------------------------------------------------------------------
18
 */
19
#define F_CPU 8000000UL
20
#include "irmp.h"
21
22
#ifndef F_CPU
23
#error F_CPU unknown
24
#endif
25
26
static void
27
timer1_init (void)
28
{
29
#if defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__)                // ATtiny45 / ATtiny85:
30
31
#if F_CPU >= 16000000L
32
    OCR1C   =  (F_CPU / F_INTERRUPTS / 8) - 1;                              // compare value: 1/15000 of CPU frequency, presc = 8
33
    TCCR1   = (1 << CTC1) | (1 << CS12);                                    // switch CTC Mode on, set prescaler to 8
34
#else
35
    OCR1C   =  (F_CPU / F_INTERRUPTS / 4) - 1;                              // compare value: 1/15000 of CPU frequency, presc = 4
36
    TCCR1   = (1 << CTC1) | (1 << CS11) | (1 << CS10);                      // switch CTC Mode on, set prescaler to 4
37
#endif
38
39
#else                                                                       // ATmegaXX:
40
    OCR1A   =  (F_CPU / F_INTERRUPTS) - 1;                                  // compare value: 1/15000 of CPU frequency
41
    TCCR1B  = (1 << WGM12) | (1 << CS10);                                   // switch CTC Mode on, set prescaler to 1
42
#endif
43
44
#ifdef TIMSK1
45
    TIMSK1  = 1 << OCIE1A;                                                  // OCIE1A: Interrupt by timer compare
46
#else
47
    TIMSK   = 1 << OCIE1A;                                                  // OCIE1A: Interrupt by timer compare
48
#endif
49
}
50
51
#ifdef TIM1_COMPA_vect                                                      // ATtiny84
52
#define COMPA_VECT  TIM1_COMPA_vect
53
#else
54
#define COMPA_VECT  TIMER1_COMPA_vect                                       // ATmega
55
#endif
56
57
ISR(COMPA_VECT)                                                             // Timer1 output compare A interrupt service routine, called every 1/15000 sec
58
{
59
  (void) irmp_ISR();                                                        // call irmp ISR
60
  // call other timer interrupt routines...
61
}
62
63
int
64
main (void)
65
{  DDRB |= (1<<PB0);
66
    IRMP_DATA   irmp_data;
67
68
    irmp_init();                                                            // initialize IRMP
69
    timer1_init();                                                          // initialize timer1
70
71
    sei ();                                                                 // enable interrupts
72
73
    for (;;)
74
    {
75
        if (irmp_get_data (&irmp_data))
76
        {
77
            PORTB ^=(1<<PB0);  //soll einfach LED ein bisschen zum debuggen blinken lassen                                                             // got an IR message, do something
78
        }
79
    }
80
}


Über einen Hinweis wo mein Fehler liegt würde ich mich sehr freuen :)

Ich hab das einfach mal meinem Thread angehängt da ich nicht wusste ob 
ich lieber nen neuen machen soll oder nicht. Die Überschrift passt jetzt 
leider nicht mehr so ganz :(

von Stefan F. (Gast)


Lesenswert?

Was funktionirt nicht?
Hast du die Fuses richtig gesetzt, so dass die Taktfrequenz stimmt?
Ein neuer Thread wäre besser gewesen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Ja, IRMP kommt mit ATTiny45 problemlos zurecht. Besser wäre ein 
ATTiny85, kostet nicht wesentlich mehr, bietet aber doppelten Speicher.

Zeig mal bitte Deine Anpassungen in irmp-config.h - also nicht alles, 
sondern nur das, was Du angepasst hast. Läuft Dein Tiny auch wirklich 
mit 8MHz, ist also die Fuse korrekt gesetzt? Nicht, dass der nur mit 
1MHz läuft...

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Und noch etwas: Ist projektweit - also in den Projekteinstellungen - 
F_CPU auf 8000000UL gesetzt?

von warumname (Gast)


Lesenswert?

Stefan U. schrieb:
> Was funktionirt nicht?
> Hast du die Fuses richtig gesetzt, so dass die Taktfrequenz stimmt?
> Ein neuer Thread wäre besser gewesen.

Okay in Zukunft werde ich neue Threads anlegen. Lässt sich das ganze im 
Nachhinein noch in einen neuen Thread packen?
Die Fuses sind im Auslieferungszustand. Es zeigt an das der Attiny mit 
einem "Int. RC Osc. 8 MHz; Startuptime...." läuft. Sehe ich das richtig 
das er also mit 8 MHz läuft?



Frank M. schrieb:
> Zeig mal bitte Deine Anpassungen in irmp-config.h - also nicht alles,
> sondern nur das, was Du angepasst hast. Läuft Dein Tiny auch wirklich
> mit 8MHz, ist also die Fuse korrekt gesetzt? Nicht, dass der nur mit
> 1MHz läuft...

Ich habe darin einige nicht benötigte Protokolle deaktiviert. Zusätzlich 
noch den IR Eingangspin geändert:
1
/*---------------------------------------------------------------------------------------------------------------------------------------------------
2
 * Change hardware pin here for ATMEL ATMega/ATTiny/XMega
3
 *---------------------------------------------------------------------------------------------------------------------------------------------------
4
 */
5
#if defined (ATMEL_AVR) || defined (__AVR_XMEGA__)                      // use PB6 as IR input on AVR
6
#  define IRMP_PORT_LETTER                      B
7
#  define IRMP_BIT_NUMBER                       1



Frank M. schrieb:
> Und noch etwas: Ist projektweit - also in den Projekteinstellungen
> -
> F_CPU auf 8000000UL gesetzt?

Wo finde ich die Projekteinstellungen? Ich finde nur 
Projekteigenschaften. Da gibt es aber nix wo ich F_CPU ändern könnte.

Danke das ihr euch die Zeit nehmt und mir helft.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

standardmäßig laufen alle mit internen RC, meistens sind das eben 8MHz. 
Aber zusätzlich ist noch die Fuse 1/8 Teiler aktiv, sodass er nur mit 
1MHz läuft bzw. 1/8 des internen RCs. Ich vermute den Grund damit er 
erstmal mit jeder rüden Spannungsversorgung klar kommt und überhaupt 
erstmal läuft und verwendbar ist.

Oben bei meinem Screenshot, gehste nich auf hinzufügen sondern runter im 
Menü auf Eigenschaften. In dem sich öffnenden Fenster auf Toolchain, 
hier haste für C und C++ Compiler dann die Einträge Symbols usw ....

Dabei darauf achten das Release bzw. alle Konfig ausgewählt ist.

Allerdings höre ich von dieser Einstellmöglichkeit auch zum erstenmal. 
Ich mach das auch immer nur im main Code mittels #define F_CPU 
8000000UL. Und weil das immer an erster Stelle steht, sollte das auch 
für alles berücksichtigt werden. Die includes kommen nämlich erst 
danach.

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Veit D. schrieb:
> Allerdings höre ich von dieser Einstellmöglichkeit auch zum erstenmal.

Es wurde hier schon öfter über die Sinnhaftigkeit von globalen Symbolen, 
welche man projektweit einstellen kann, diskutiert. Die Mehrheit 
befürwortet die Verwendung, statt solche Preprocessor-Konstanten quer 
über den Source zu verteilen.

Einen Grund zum Beispiel lieferst Du hier selbst:

> Ich mach das auch immer nur im main Code mittels #define F_CPU
> 8000000UL. Und weil das immer an erster Stelle steht, sollte das auch
> für alles berücksichtigt werden.

Das klappt nur, wenn Dein Projekt lediglich aus main.c besteht. Es gibt 
durchaus Projekte, welche aus 10 oder mehr C-Dateien bestehen. Es ist 
hier Unsinn, in all diese Sources ein #define F_CPU einzubauen. Ändert 
sich dieser Wert später mal, hast Du jede Menge Arbeit - und Stress.

> Die includes kommen nämlich erst danach.

Siehe oben. Hier würde eher ein gemeinsames include, welches in allen 
C-Dateien aufgerufen wird, die Sache eher noch retten. Aber vergisst man 
mal eins und hat dann ausgerechnet auch noch so etwas im Source stehen:
1
#ifndef F_CPU
2
#define F_CPU 16000000UL
3
#endif

Dann ist es reines Glücksspiel, ob alle C-Dateien einheitlich mit ein- 
und derselben Taktfrequenz kompiliert werden.

In jeder IDE, welche C- oder C++-Compiler unterstützt, kann man 
projektweit C-Preprocessor-Konstanten setzen - ohne Ausnahme. Naja, eine 
gibt es: Arduino. Aber man kann darüber streiten, ob das wirklich eine 
IDE ist.

Verwendet man keine IDE, kann man diese Konstanten selbstverständlich 
auch im Makefile setzen.

Jetzt konkret AtmelStudio7:

Projekt -> meinProjekt Properties -> Defined symbols
Eintragen:

F_CPU=8000000UL

Sowohl für Debug (Ha, da ist ja schon DEBUG gesetzt, kann man prima mit 
#ifdef DEBUG nutzen!) als auch für Release.

Und voilà: Jetzt gilt die Konstante für den kompletten Source. Sie wird 
nämlich dem C-Compiler mit -DFCPU=8000000UL übergeben. Und das versteht 
auch jeder C-Compiler seit 1970.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

verstehe das noch nicht ganz. Die includes sind doch auch c Files und h. 
Files. #define steht an erster Stelle im main.c , demnach denke ich das 
genau das dann für alle anderen Files die eingebunden werden auch gilt, 
eben weil F_CPU vor allen definiert wurde. ???

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Veit D. schrieb:
> verstehe das noch nicht ganz. Die includes sind doch auch c Files und h.
> Files. #define steht an erster Stelle im main.c , demnach denke ich das
> genau das dann für alle anderen Files die eingebunden werden auch gilt,
> eben weil F_CPU vor allen definiert wurde. ???

Was ist mit irmp.c oder irsnd.c - jetzt mal ganz konkret? Auch irsnd.c 
braucht den Wert von F_CPU. Wenn Du das in main.c definierst, ist das 
noch lange nicht in irsnd.c definiert. Nein, irsnd.c oder jede andere 
C-Datei, die zum Projekt gehört ist kein include, sondern eine neben 
main.c gleichberechtigte C-Datei.

Offenbar hast Du noch nie größere Mikrocontroller-Projekte erstellt, 
sondern arbeitest nur mit einer C-Datei.

Nehmen wir mal

   https://www.mikrocontroller.net/articles/WordClock24h

Das Projekt besteht aus insgesamt 43 C-Dateien - ohne die includes. Hier 
kommst Du gar nicht drumherum, globale Symbole in der IDE (bzw. 
Makefile) zu definieren, um den Source mit dem gleichen Stand zu 
übersetzen.

Aus diesem Grunde findest Du auch in irsnd.c oder anderen Modulen der 
IRMP-Bibliothek, wo immer auf F_CPU zurückgegriffen wird:
1
#ifndef F_CPU
2
#error F_CPU unknown
3
#endif

Der einzig saubere Weg ist es, F_CPU global im Makefile bzw. in der IDE 
zu definieren. Alles andere gibt Datensalat.

: Bearbeitet durch Moderator
von Veit D. (devil-elec)


Lesenswert?

Hallo,

nein, habe noch nie Projekte erstellt oder damit hantiert die außer 
includes andere Files im Projekt hatten. Aber jetzt weiß ich es, Danke.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

muss doch nochmal fragen. Wenn die anderen c Files nicht inkludiert 
werden, woher weiß dann main.c das es sie gibt und benötigt? Irgendwie 
muss doch main.c mit allen benötigten Files bekannt gemacht werden. 
Woher sonst soll der Compiler an Hand von main.c wissen was er alles 
kompilieren muss. Also irgendwelche Dateien die da so nebenbei rumliegen 
und dann doch irgendwie Verwendung finden, daran glaube ich ehrlich nun 
doch nicht. Irgendein Verweis auf deren Existenz muss wo angegeben 
werden.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Veit D. schrieb:
> muss doch nochmal fragen. Wenn die anderen c Files nicht inkludiert
> werden, woher weiß dann main.c das es sie gibt und benötigt?

Okay, fangen wir bei Adam und Eva an:

main.c
1
#include <stdio.h>
2
#include "calc.h"
3
4
int main ()
5
{
6
    int sum;
7
    sum = summe (3, 4);
8
9
    printf ("Summe von 3 und 4 = %d\n", sum);
10
    return 0;
11
}

calc.h:
1
extern int summe (int, int);

calc.c
1
int summe (int a, int b)
2
{
3
    return a + b;
4
}

Compilieren:

cc -c main.c
cc -c calc.c

Linken:

cc main.o calc.o -o rechenmaschine.exe

Oder beide Schritte zusammen:

cc main.c calc.c -o rechenmaschine.exe

Wie weiß main() nun etwas von summe()? Durch das include calc.h. Denn 
dort wird angezeigt ("deklariert"), dass es eine Funktion summe() gibt, 
die zwei Argumente braucht und einen int-Wert zurückliefert.(*)

Der Linker ("verbinder") ist es, der die beiden Funktionen zusammenfügt, 
nicht der Compiler.

Okay, ich könnte da jetzt noch stundenlang drüber reden, aber da gibt es 
genügend Literatur im Internet darüber, so dass ich jetzt keinen 
22-seitigen Aufsatz schreiben muss, oder?

> daran glaube ich ehrlich nun doch nicht.

Das hat nichts mit Glauben zu tun, sondern mit Wissen. Das musst Du Dir 
schon selbst aneignen. Das Internet gibt Dir genügend Möglichkeiten 
dazu. Nutze sie.

(*) Übrigens: Wenn der Compiler auf eine bisher unbekannte Funktion aus 
einer anderen Übersetzungseinheit stößt, die NICHT vorher deklariert 
wurde, dann wird automatisch angenommen, dass diese Funktion vom Typ int 
ist und genau diese Anzahl und Typen von Parametern akzeptiert, die Du 
angegeben hast. Das ist aber eine implizite Annahme, die keinesfalls 
stimmen muss. Aus diesem Grunde meckern heutzuzage C-Compiler zumindest 
mit einer Warnung, dass Du eine ihm bis dato unbekannte Funktion 
aufrufst, deren Interface (Parameter und Return-Typ) durchaus abweichen 
kann und der (naive) Aufruf der Funktion ohne korrekte 
extern-Deklaration auch zu einem Absturz des ganzen Programms führen 
kann.

: Bearbeitet durch Moderator
von warumname (Gast)


Lesenswert?

Veit D. schrieb:

> standardmäßig laufen alle mit internen RC, meistens sind das eben 8MHz.
> Aber zusätzlich ist noch die Fuse 1/8 Teiler aktiv, sodass er nur mit
> 1MHz läuft bzw. 1/8 des internen RCs.

Daran lag es. Jetzt läuft IRMP auf dem Attiny. Danke :)

Zusätzlich hab ich define CPU in die Projekt Eigenschaften gesetzt.

Frank M. schrieb:

> Okay, ich könnte da jetzt noch stundenlang drüber reden, aber da gibt es
> genügend Literatur im Internet darüber, so dass ich jetzt keinen
> 22-seitigen Aufsatz schreiben muss, oder?

Kennst du eine gute Literatur zu dem Thema im Internet? Ich weiß da nie 
nach was ich genau suchen soll. Wäre super wenn du mir ne gute Literatur 
dazu nennen könntest.
Bin auch allgemein auf der Suche nach Anleitungen zu erstellen und 
benutzen von mehreren Dateien in einem Projekt.

von Veit D. (devil-elec)


Lesenswert?

Hallo Frank,

Danke für die nähere Erklärung. Der Mechanismus dahinter war mir nicht 
bekannt.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

warumname schrieb:
> Kennst du eine gute Literatur zu dem Thema im Internet?

Es gibt hunderte dazu. Als ich C in den 80er Jahren lernte, ging das 
noch mit Büchern ;-)

Google einfach mal nach "C compiler linker" und Du wirst eine Menge über 
den Aufbau von C-Compilern, Präprozessoren und Linkern erfahren. Allein 
die ersten beiden Google-Treffer-Seiten (20 Links) sollten Dir genug 
erzählen - auf deutsch oder englisch.

von warumname (Gast)


Lesenswert?

okay Danke

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.