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
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.
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
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?
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
Du musst aber auch den Compiler die Verzeichnisse bekannt machen. Sonst gibt es beim übersetzen ein Problem.
:
Bearbeitet durch User
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
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"
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.
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.
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 :(
Was funktionirt nicht? Hast du die Fuses richtig gesetzt, so dass die Taktfrequenz stimmt? Ein neuer Thread wäre besser gewesen.
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...
Und noch etwas: Ist projektweit - also in den Projekteinstellungen - F_CPU auf 8000000UL gesetzt?
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.
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
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.
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. ???
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
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.
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.
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
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.
Hallo Frank, Danke für die nähere Erklärung. Der Mechanismus dahinter war mir nicht bekannt.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.