Forum: Compiler & IDEs Funktionen in mehrere c files auslagern funktioniert nicht


von Florian (Gast)


Lesenswert?

Hallo Spezialisten,

ich bin gerade dabei meinen funktionierenden C-Code in mehrere .c 
Dateien zu zerstückeln um das Projekt übersichtlicher zu machen. Aber es 
klappt einfach nicht, egal wie ich es mache. Ich nutze das aktuellste 
AVR-Studio mit gcc(WINAVR).

Ich habe etliche Forumsbeiträge dazu gelesen und auch den Artikel in der 
Sammlung, aber irgendwie scheine ich auf dem Schlauch zu stehen. Klappt 
bei mir alles nicht. Auch habe ich im AVR-Studio den Pfad angegeben für 
die include-Dateien.

Hier mein Code als Beispiel wie ich es versuche:

main.c:
1
#include <avr/io.h>          
2
#include <util/delay.h>
3
#include <stdint.h> 
4
5
#include <timing.h>
6
7
#define F_CPU 11059200UL
8
9
int main (void) {  
10
11
while(1) {     
12
13
  delay_x10ms(30);
14
15
16
  PORTD |= (1 << PD6);    /* LED an */
17
18
  delay_x10ms(30);
19
20
21
  PORTD &= ~(1 << PD6);   /* LED aus */
22
  
23
   }//while(1)                     
24
 
25
   return 0;                 
26
}

Die Datei timing.c sieht so aus:
1
#include <util/delay.h>
2
#include <stdint.h> 
3
4
void delay_x10ms(uint16_t count)
5
{
6
    uint16_t count_delay_loops = 0;
7
8
  for(count_delay_loops=0;count_delay_loops < count; count_delay_loops++)
9
  {
10
     _delay_ms(10.0); // requires: #include <util/delay.h>
11
  }//for
12
13
}

Und dazu noch timing.h:
1
#include <util/delay.h>
2
#include <stdint.h> 
3
4
void delay_x10ms(uint16_t count);


In dem Beispiel soll in einer Schleife die delay_funktion mehrfach 
aufgerufen werden um das delay zu verlängern. Die LED sollte dann 
sichtbar blinken. Das klappt prima wenn alles in der main.c Datei steht, 
aber sobald ich es auslagere geht nix mehr.

Was habe ich übersehen?

Vielen Dank für Tips!!

Grüße Florian

von Stefan (Gast)


Lesenswert?

#include "timing.h"

von Frank L. (florenzen)


Lesenswert?

1
#include "timing.h"

liebe grüße
frank

von Florian (Gast)


Lesenswert?

Danke für den Hinweis.

Habe
1
#include <timing.h>

in der Datei timing.c eingetragen, es geht aber immer noch nichts. Es 
kommen wie gesagt keine Fehlermedungen, es lässt sich alles compilieren.

Grüße Florian

von Florian (Gast)


Lesenswert?

Ach ja, mit
1
#include "timing.h"

klappt es natürlich auch nicht...

von Frank L. (florenzen)


Lesenswert?

Auch an main.c gedacht?

liebe grüße
frank

Hab noch was vergessen: verschiebe F_CPU nach timing.h. _delay_ms 
braucht das.

von Florian (Gast)


Lesenswert?

Ja, hab ich auch dort eingetragen. Ich habe jetzt auch noch eine main.h 
eingefügt und die CPU-Frequenz dort definiert damit sie auch in der 
timing.c gilt. Die main.h habe ich dort natürlich eingebunden.

Alles in allem sieht mein Code jetzt so aus:

main.c
1
#include <avr/io.h>          
2
#include <util/delay.h>
3
#include <stdint.h> 
4
5
#include "main.h"     //include all definitions
6
#include "timing.h"
7
8
int main (void) {   
9
 while(1) {     
10
11
  delay_x10ms(30);
12
  PORTD |= (1 << PD6);    /* LED an */
13
  delay_x10ms(30);
14
  PORTD &= ~(1 << PD6);   /* LED aus */
15
  
16
17
   }//while(1)                     
18
 
19
   return 0;                 
20
}

Die Datei timing.c sieht so aus:
1
#include <util/delay.h>
2
#include <stdint.h> 
3
#include "timing.h"
4
#include "main.h"
5
6
void delay_x10ms(uint16_t count)
7
{
8
    uint16_t count_delay_loops = 0;
9
10
  for(count_delay_loops=0;count_delay_loops < count;  count_delay_loops++)
11
  {
12
     _delay_ms(10.0); // requires: #include <util/delay.h>
13
  }
14
15
}

Die Datei timing.h sieht so aus:
1
#include <util/delay.h>
2
#include <stdint.h> 
3
4
extern void delay_x10ms(uint16_t count);

und hier noch main.h:
1
#define F_CPU 11059200UL  // 11,059200 MHz for minimum baud rate error using RS232

von Florian (Gast)


Lesenswert?

Hat noch jemand eine Idee woran es liegen kann? Ich bin absolut 
ratlos...

Oder kann es daran liegen dass das AVR-Studio sowas gar nicht korrekt 
unterstützt? So langsam kommen mir da die Zweifel ob das generell 
klappt... kann das ein Mega-Buck sein?? Das müssten doch dann aber schon 
etliche andere festgestellt haben... ?!??!

von Frank L. (florenzen)


Lesenswert?

Du schriebst daß es schonmal funktioniert habe. Ich kann allerdings 
nirgends sehen daß du den Pin als Ausgang konfigurierst. Ist das 
verschütt gegangen?


liebe Grüße
frank

von Oliver (Gast)


Lesenswert?

>Oder kann es daran liegen dass das AVR-Studio sowas gar nicht korrekt
>unterstützt?

Nö. Das Studio kann das.

>...es geht aber immer noch nichts. Es
>kommen wie gesagt keine Fehlermedungen, es lässt sich alles compilieren.

Hast du mal in allen Fenstern des Studios nachgesehen? Denn, wenn es 
keine Fehlermeldungen gibt und alles durchläuft, woran merkst dann 
überhaupt, daß es nicht funktioniert?

Oliver

von Florian (Gast)


Lesenswert?

Ja, ich habe noch einiges an Code, habe es wegen der Übersichtlichkeit 
hier weggelassen.

Bei der Initialisierung wird noch folgendes gemacht:
1
// Input/Output Ports initialization
2
// Port A initialization
3
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
4
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
5
PORTA=0x00;
6
DDRA=0x00;
7
8
// Port B initialization
9
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
10
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
11
PORTB=0x00;
12
DDRB=0x00;
13
14
// Port C initialization
15
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
16
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
17
PORTC=0x00;
18
DDRC=0x00;
19
20
// Port D initialization
21
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=Out Func0=In 
22
// State7=1 State6=1 State5=1 State4=1 State3=P State2=P State1=0 State0=T 
23
PORTD=0xFC;
24
DDRD=0xF2;
25
26
// Timer/Counter 0 initialization
27
// Clock source: System Clock
28
// Clock value: 43,200 kHz
29
// Mode: Normal top=FFh
30
// OC0 output: Disconnected
31
TCCR0=0x04;
32
TCNT0=0x00;
33
OCR0=0x00;
34
35
// Timer/Counter 1 initialization
36
// Clock source: System Clock
37
// Clock value: Timer 1 Stopped
38
// Mode: Normal top=FFFFh
39
// OC1A output: Discon.
40
// OC1B output: Discon.
41
// Noise Canceler: Off
42
// Input Capture on Falling Edge
43
// Timer 1 Overflow Interrupt: Off
44
// Input Capture Interrupt: Off
45
// Compare A Match Interrupt: Off
46
// Compare B Match Interrupt: Off
47
TCCR1A=0x00;
48
TCCR1B=0x00;
49
TCNT1H=0x00;
50
TCNT1L=0x00;
51
ICR1H=0x00;
52
ICR1L=0x00;
53
OCR1AH=0x00;
54
OCR1AL=0x00;
55
OCR1BH=0x00;
56
OCR1BL=0x00;
57
58
// Timer/Counter 2 initialization
59
// Clock source: System Clock
60
// Clock value: Timer 2 Stopped
61
// Mode: Normal top=FFh
62
// OC2 output: Disconnected
63
ASSR=0x00;
64
TCCR2=0x00;
65
TCNT2=0x00;
66
OCR2=0x00;
67
68
// External Interrupt(s) initialization
69
// INT0: On
70
// INT0 Mode: Low level
71
// INT1: On
72
// INT1 Mode: Low level
73
// INT2: Off
74
GICR|=0xC0;
75
MCUCR=0x00;
76
MCUCSR=0x00;
77
GIFR=0xC0;
78
79
// Timer(s)/Counter(s) Interrupt(s) initialization
80
TIMSK=0x01;
81
82
// USART initialization
83
// Communication Parameters: 8 Data, 1 Stop, No Parity
84
// USART Receiver: On
85
// USART Transmitter: On
86
// USART Mode: Asynchronous
87
// USART Baud rate: 9600
88
UCSRA=0x00;
89
UCSRB=0x18;
90
UCSRC=0x86;
91
UBRRH=0x00;
92
UBRRL=0x47;
93
94
// Analog Comparator initialization
95
// Analog Comparator: Off
96
// Analog Comparator Input Capture by Timer/Counter 1: Off
97
ACSR=0x80;
98
SFIOR=0x00;
99
100
// ADC initialization
101
// ADC Clock frequency: 86,400 kHz
102
// ADC Voltage Reference: AVCC pin
103
// Only the 8 most significant bits of
104
// the AD conversion result are used
105
ADMUX= 0xff;
106
ADCSRA=0x87;

Daran liegt es nicht. Sobald ich die Funktion delay_x10ms() in der 
main.c schreibe und deklariere und den ganzen header-Kram weglasse 
klappt es und die LED blinkt langsam.

Ich bekomme es nur einfach nicht hin den Code auf mehrere c Dateien zu 
verteilen. Irgendwo gibt es sicher noch einen versteckten Haken. Nur wo?

von gast (Gast)


Lesenswert?

sorry, ist jetzt nicht unbedingt zu deinem problem, aber sowas "void 
delay_x10ms(uint16_t count);" brauchst nicht mehr. In der neuen Version 
von GCC wird das automatisch gemacht, sobald die übergebene Zahl zu groß 
ist.

von Frank L. (florenzen)


Lesenswert?

Du gibst in dem Teil den du uns verheimlicht hast den Timer-Interrupt 
frei. Sollte sich in einem nicht veröffentlichten Code auch noch ein 
sei() tummeln solltest du bedenken daß der Zugriff auf uint16 nicht 
atomar ist. Dann wäre es durchaus möglich daß dein Code nur "zufällig" 
funktioniert.

liebe grüße
frank

von Florian (Gast)


Lesenswert?

Erstmal vielen Dank für die ganzen Hinweise!

Ja, ich habe in meinem ursprünglichen Code mit Interrupts gearbeitet. Da 
nach der Aufsplittung des Codes in einzelne c Dateien nichts mehr 
funktionierte, habe ich von ganz "unten" angefangen und ein ganz neues 
Projekt angelegt und schreibe Stück für Stück dazu. Das mit der 
Blink-LED war der erste Versuch um es prinzipiell richtig zu machen. 
Geht aber leider nicht.

Es gibt keinen versteckten Code mehr. Habe alles gepostet was compiliert 
wird. Die Interrupts sind global nicht aktiviert.

Die LED brennt dauerhaft, das wars. Dem Controller ist kein Blinken zu 
entlocken sobald der Code wie gepostet in mehrere c Dateien geteilt 
wird.

Witzig: Ich habe jetzt Stunden verbracht mit Lesen im Forum, dabei habe 
ich des öfteren auch gelesen dass das AVR-Studio wohl nicht immer so 
toll ist und recht benutzerfeindlich. Ich habe mehrfach den Hinweis 
gefunden dass andere IDEs und Compiler "besser" sein sollen. Habe eine 
Demo von diesem Code-Vision  runtergeladen und dort funktioniert es auf 
Anhieb perfekt! Spricht für diesen Code-Vision. Den will ich aber 
eigentlich nicht kaufen...

Liegt es wohl doch mal wieder an der Kombination AVR-Studio und WINAVR 
??? Hat jemand ähnliche Probleme?

von Oliver (Gast)


Lesenswert?

>Liegt es wohl doch mal wieder an der Kombination AVR-Studio und WINAVR
>??? Hat jemand ähnliche Probleme?

Nö.

Ganz hilfreich wäre es, wenn du mal das ganze Studio-Projekt hier 
reinstellst, mit allen Dateien. Am besten den ganzen Projektordner 
zusammenzippen.

Oliver

von Manuel S. (thymythos) Benutzerseite


Lesenswert?

Mehrere Dinge die mir einfallen:

Du solltest F_CPU nie im Code definieren sondern im Makefile oder bei 
AVRStudio in den Projekteinstellungen, dann ist es automatisch in allen 
Dateien bekannt. Damit _delay_ms() funktioniert muss die Optimierung 
eingeschaltet sein. Ich hatte mit allem außer -O2 teilweise schon 
Probleme.

Du kennst den Unterschied zwischen:
1
#include "datei.h"

und
1
#include <datei.h>

oder solls dir mal jemand erklären?

Scheinbar bist du dir auch noch unsicher wann du überhaupt ein #include 
brauchst.

In der main.c und in der timing.h musst du z.B. util/delay.h nicht 
einbinden, da du dort nicht darauf zurückgreifst.

von P. S. (Gast)


Lesenswert?

Was fuer ein Controller ist das?

von Florian (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

erstmal vielen Dank für die Infos!!

Ja, ich bin kein C-Crack, manches muss ich mir noch irgendwo abschauen. 
Ich fange natürlich auch mal an zu probieren, oft kommt man ja weiter 
damit.
Ich habe irgendwann die header einfach überall eingebunden um auch 
sicher nichts zu vergessen. Eigentlich ist es somit doppelt.

Das mit dem F_CPU war auch nur ein Versuch, ich hatte es vorher nicht 
drin. Im AVR-Studio habe ich es eingestellt.

Optimierung ist an und steht auf -0s.  Die delay-Funktion geht auch, ich 
kann z.B. 30 mal hintereinander _delay_ms(10.0); aufrufen im main.c und 
die LED blinkt schön langsam. Es sollte also nicht an der delay-Funktion 
liegen. Es klappt aber nicht mehr, sobald ich es in eine andere C Datei 
auslagere...

Controller ist übrigens ein ATmega32.

Im Anhang mal das Projekt als zip so wie es bei mir nicht läuft. Es 
lässt sich wie gesagt compilieren und auch ein "build all" klappt 
reibungslos. Nach dem Flashen brennt die LED aber konstant und blinkt 
nicht so wie sie es sollte...

Vielen Dank an alle die sich das ansehen!!

Grüße Florian.

von Detlev T. (detlevt)


Lesenswert?

Hast du AVR Studio überhaupt mitgeteilt, dass noch weitere Dateien zu 
beachten sind? (Unter "Source" und "Header" Dateien eintragen) Nur in 
das Verzeichnis speichern reicht nicht!

von Kevin Lange (Gast)


Lesenswert?

Ja, das habe ich schon eingetragen. AVR Studio scheint die Dateien ja 
auch zu finden, sonst würde das Compilieren ja auch nicht funktionieren.

So langsam bin ich echt am Ende, seit 2 Tagen versuche ich ein absolutes 
Mini-Programm in 2 C- Dateien aufzuteilen und es will einfach nicht 
funktionieren. Ich kann inzwischen kaum noch glauben dass es nicht am 
AVR-Studio liegt...

von Oliver (Gast)


Lesenswert?

>Ich kann inzwischen kaum noch glauben dass es nicht am
>AVR-Studio liegt...

Das liegt nicht am Studio. Dein Projekt sieht im Studio gut aus, 
kompiliert einwandfrei, und dein Original-hex-file läuft bei mir im 
VMLAB-Simulator so, wie es soll.

main.h kannst du dir sparen, F_CPU wird schon beim Aufruf des Compilers 
definiert, ausserdem müsste es vor delay.h stehen. Das hat aber jetzt 
nichts mit deinem Problem zu tun. Das steckt irgend wo anders )-:

Oliver

von Florian (Gast)


Lesenswert?

Vielen Dank Oliver für den Test der Dateien!

Ich habe das AVR-Studio nochmals neu runtergeladen und installiert und 
WINAVR auch. Dann ganz neu nochmal ein Projekt aufgesetzt, und wieder 
das gleiche Problem. Steht alles in einer Datei, so läuft es 
einwandfrei. Sobald ich den Code in eine zweite Datei auslagere geht 
nichts mehr.

Vielleicht ist mein Rechner zu alt (P3 1,2GHz 256MB RAM mit Win2000). 
Oder das AVR-Studio läuft nicht (mehr) unter Win2000 oder sonstwas. Ich 
hab es inzwischen jedenfalls aufgegeben und jetzt in den sehr sauren 
Apfel gebissen und mir den CodeVision Compiler gekauft für 150 Euro. Tut 
weh, ist aber offensichtlich die einzigste Lösung da das AVR-Studio 
definitiv nicht ordentlich läuft. (Bitte nicht aufregen über diese 
Aussage, aber es ist nun mal einfach Tatsache).

Ich programmiere seit heute morgen im CodeVision. Klappt seit Stunden 
bestens ohne jegliche Probleme. Naja, vielleicht wird in Zukunft ja mal 
was aus dem AVR-Studio. Bisher scheint es mir eher 
Bastler-Hobby-Charakter zu haben. Würde mich interessieren ob es eine 
Firma gibt die sowas nutzt...

Danke jedenfalls nochmal an alle die sich das hier angesehen haben!!

Florian

von OliverSo (Gast)


Lesenswert?

Nun ja, wenn Geld keine Rolle spielt...

Das Studio hat mit deinem Problem mit 99,9999% Sicheheit nichts zu tun. 
Das ist ja nicht viel mehr als ein Editor mit Projektverwaltung und 
Simulator, und kann nachgewiesenermassen mit Dutzenden von source- und 
headerfiles umgehen. Kompilieren und linken tut es gar nicht, dazu nutzt 
es  WinAVR, und der ist open-source. Insofern wäre es schon nicht 
schlecht, rauszufinden, was bei dir schief geht.

Falls du das Studio noch auf der Platte hast, kannst du auch noch das 
Projektverzeichnis mit der funtionierenden Version hier einstellen? 
Vielleicht findet sich da ja doch noch was.

Oliver

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.