www.mikrocontroller.net

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


Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
#include <avr/io.h>          
#include <util/delay.h>
#include <stdint.h> 

#include <timing.h>

#define F_CPU 11059200UL

int main (void) {  

while(1) {     

  delay_x10ms(30);


  PORTD |= (1 << PD6);    /* LED an */

  delay_x10ms(30);


  PORTD &= ~(1 << PD6);   /* LED aus */
  
   }//while(1)                     
 
   return 0;                 
}

Die Datei timing.c sieht so aus:
#include <util/delay.h>
#include <stdint.h> 

void delay_x10ms(uint16_t count)
{
    uint16_t count_delay_loops = 0;

  for(count_delay_loops=0;count_delay_loops < count; count_delay_loops++)
  {
     _delay_ms(10.0); // requires: #include <util/delay.h>
  }//for

}

Und dazu noch timing.h:
#include <util/delay.h>
#include <stdint.h> 

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

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include "timing.h"

Autor: Frank Lorenzen (florenzen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include "timing.h"

liebe grüße
frank

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den Hinweis.

Habe

#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

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ja, mit

#include "timing.h"

klappt es natürlich auch nicht...

Autor: Frank Lorenzen (florenzen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch an main.c gedacht?

liebe grüße
frank

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

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
#include <avr/io.h>          
#include <util/delay.h>
#include <stdint.h> 

#include "main.h"     //include all definitions
#include "timing.h"

int main (void) {   
 while(1) {     

  delay_x10ms(30);
  PORTD |= (1 << PD6);    /* LED an */
  delay_x10ms(30);
  PORTD &= ~(1 << PD6);   /* LED aus */
  

   }//while(1)                     
 
   return 0;                 
}


Die Datei timing.c sieht so aus:
#include <util/delay.h>
#include <stdint.h> 
#include "timing.h"
#include "main.h"

void delay_x10ms(uint16_t count)
{
    uint16_t count_delay_loops = 0;

  for(count_delay_loops=0;count_delay_loops < count;  count_delay_loops++)
  {
     _delay_ms(10.0); // requires: #include <util/delay.h>
  }

}


Die Datei timing.h sieht so aus:
#include <util/delay.h>
#include <stdint.h> 

extern void delay_x10ms(uint16_t count);

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


Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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... ?!??!

Autor: Frank Lorenzen (florenzen)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Florian (Gast)
Datum:

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

Bei der Initialisierung wird noch folgendes gemacht:
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=In Func2=In Func1=Out Func0=In 
// State7=1 State6=1 State5=1 State4=1 State3=P State2=P State1=0 State0=T 
PORTD=0xFC;
DDRD=0xF2;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 43,200 kHz
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x04;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Low level
// INT1: On
// INT1 Mode: Low level
// INT2: Off
GICR|=0xC0;
MCUCR=0x00;
MCUCSR=0x00;
GIFR=0xC0;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x47;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// ADC initialization
// ADC Clock frequency: 86,400 kHz
// ADC Voltage Reference: AVCC pin
// Only the 8 most significant bits of
// the AD conversion result are used
ADMUX= 0xff;
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?

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Frank Lorenzen (florenzen)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Manuel Stahl (thymythos) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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:
#include "datei.h"

und
#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.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was fuer ein Controller ist das?

Autor: Florian (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Kevin Lange (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: OliverSo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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.