Forum: Mikrocontroller und Digitale Elektronik Anfänge in C


von Gerd V. (gerald)


Lesenswert?

Hallo,

nach etlichen Jahren Programmiererei in Assembler wollte ich mir jetzt 
das Leben etwas einfacher machen und meine AVR-Projekte in C 
programmieren.
Ich verwende das AVR-Studio und GCC-Compiler.
Jetzt bekomme ich schon bei den kleinsten Anfängen Probleme.
Ich will nichts anderes machen als eine include-File in mein 
Hauptprogramm einbinden.

Ständig kommt der Fehler:

D:\Entwicklung\Modellbau\Nautiksteuerung\Nautiksteuerung\default/../Naut 
iksteuerung.c:26:  undefined reference to `LED_Init'

Im Moment habe ich drei Files geschrieben:
als main Nautiksteuerung.c
und eine include-File LEDcontrol.c
zusätzlich dazu LEDcontrol.h

das Hauptprogramm:
1
 
2
  #include <avr/io.h>
3
  #include "LEDcontrol.h"
4
5
  /**************************************************
6
  
7
  Folgende Funktionen sind implementiert:
8
9
    LED_Init
10
  
11
  **************************************************/
12
13
  int main (void)
14
  {
15
    LED_Init();
16
  }

Die include-File .c
1
 
2
  #include <avr/io.h>
3
  #include "LEDcontrol.h"
4
5
  /*** Funktion LED_Init ***/
6
7
  void LED_Init (void);
8
  {
9
  DDRB |= (1<<DDB0) | (1<<DDB1);
10
  PORTB |= (1<<PB0) | (1<<PB1);
11
  }

und ebenso diese .h -File
1
  /***** verwendete Definitionen ********/
2
3
  void  LED_Init (void);

Alle Files stehen im gleichen Verzeichnis.

die make-File hat diesen Inhalt:
1
###############################################################################
2
# Makefile for the project Nautiksteuerung
3
###############################################################################
4
5
## General Flags
6
PROJECT = Nautiksteuerung
7
MCU = atmega162
8
TARGET = Nautiksteuerung.elf
9
CC = avr-gcc
10
11
## Options common to compile, link and assembly rules
12
COMMON = -mmcu=$(MCU)
13
14
## Compile options common for all C compilation units.
15
CFLAGS = $(COMMON)
16
CFLAGS += -Wall -gdwarf-2 -Os -std=gnu99 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
17
CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d 
18
19
## Assembly specific flags
20
ASMFLAGS = $(COMMON)
21
ASMFLAGS += $(CFLAGS)
22
ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2
23
24
## Linker flags
25
LDFLAGS = $(COMMON)
26
LDFLAGS +=  -Wl,-Map=Nautiksteuerung.map
27
28
29
## Intel Hex file production flags
30
HEX_FLASH_FLAGS = -R .eeprom -R .fuse -R .lock -R .signature
31
32
HEX_EEPROM_FLAGS = -j .eeprom
33
HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
34
HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0 --no-change-warnings
35
36
37
## Objects that must be built in order to link
38
OBJECTS = Nautiksteuerung.o 
39
40
## Objects explicitly added by the user
41
LINKONLYOBJECTS = 
42
43
## Build
44
all: $(TARGET) Nautiksteuerung.hex Nautiksteuerung.eep Nautiksteuerung.lss size
45
46
## Compile
47
Nautiksteuerung.o: ../Nautiksteuerung.c
48
  $(CC) $(INCLUDES) $(CFLAGS) -c  $<
49
50
##Link
51
$(TARGET): $(OBJECTS)
52
   $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)
53
54
%.hex: $(TARGET)
55
  avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@
56
57
%.eep: $(TARGET)
58
  -avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@ || exit 0
59
60
%.lss: $(TARGET)
61
  avr-objdump -h -S $< > $@
62
63
size: ${TARGET}
64
  @echo
65
  @avr-size -C --mcu=${MCU} ${TARGET}
66
67
## Clean target
68
.PHONY: clean
69
clean:
70
  -rm -rf $(OBJECTS) Nautiksteuerung.elf dep/* Nautiksteuerung.hex Nautiksteuerung.eep Nautiksteuerung.lss Nautiksteuerung.map
71
72
73
## Other dependencies
74
-include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)

Meine Frage nun, was mache ich falsch?


Gruss

Gerald

von Kasperle (Gast)


Lesenswert?

void LED_Init (void);
  {
  DDRB |= (1<<DDB0) | (1<<DDB1);
  PORTB |= (1<<PB0) | (1<<PB1);
  }

Semikolon hinter (void)?

von yalu (Gast)


Lesenswert?

LEDcontrol sollte ebenfalls als Bestandteil des Projekts angegeben
werden. Ändere also im Makefile die Zeile

  OBJECTS = Nautiksteuerung.o

in

  OBJECTS = Nautiksteuerung.o LEDcontrol.o

sonst findet der Linker die Funktion LED_Init nicht.

von Gast (Gast)


Lesenswert?

1
  void LED_Init (void);
2
  {
3
  DDRB |= (1<<DDB0) | (1<<DDB1);
4
  PORTB |= (1<<PB0) | (1<<PB1);
5
  }

Mach mal das Semikolon hinter "void LED_Init(void)" weg, ist mir spontan 
beim Überfliegen aufgefallen

von Peter (Gast)


Lesenswert?

Auf die schnelle sieht das ganze gut aus, ist wirklich alles Copy+Paste? 
Gross- und Kleinschreibung?

Kopiere mal alles in die Main-Datei "Nautiksteuerung.c" und lasse 
"LEDcontrol.c" und "LEDcontrol.h" weg!

von Kasperle (Gast)


Lesenswert?

Ha, ich war schneller.

von yalu (Gast)


Lesenswert?

PS: Ich kenne das AVR-Studio nicht. Möglicherweise gibt es dort eine
Klickibunti-Methode (Menü o.ä.), um eine Datei dem Projekt hinzuzufügen.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

1. .c Quelldateien bezeichnet man nicht als [[Include-Files (C)]]. .h 
Dateien sind Includefiles und diese werden mit #include ... eingebunden. 
.c Dateien bindet man über das Makefile in ein Projekt ein.

2. Dein Makefile weicht stark von dem Beispiel Makefile ab.

Bei dem Beispiel Makefile würde man die Haupt-C-Source als Target 
nehmen (Nautiksteuerung.c) so wie es auch in [[AVR-GCC-Tutorial/Exkurs 
Makefiles]] beschrieben ist
1
# Target file name (without extension).
2
TARGET = Nautiksteuerung

und weitere Sourcen (LEDcontrol.c) in der Zeile mit dem SRC am Anfang 
aufnehmen
1
# List C source files here. (C dependencies are automatically generated.)
2
SRC = $(TARGET).c LEDcontrol.c

von yalu (Gast)


Lesenswert?

Kasperle schrieb:

> Ha, ich war schneller.

Grrr ;-)

Aber: Der von dir entdeckte Fehler ist nicht der einzige. Er wäre vom
Compiler angemeckert worden, sobald der die betreffende Datei zu Gesicht
bekommen hätte. Das ist aber wegen des von mir genannten Fehlers bisher
gar nicht der Fall gewesen :)

von Stefan B. (stefan) Benutzerseite


Lesenswert?

yalu schrieb:
> PS: Ich kenne das AVR-Studio nicht. Möglicherweise gibt es dort eine
> Klickibunti-Methode (Menü o.ä.), um eine Datei dem Projekt hinzuzufügen.

Gibt es

*Mit AVR-Studio*

Alle *.c Dateien müssen im Projekt aufgenommen werden. Dann erscheinen 
sie auch in dem automatisch generierten Makefile. Ein Beispiel wie das 
Aufnehmen aussieht, steht hier: 
http://www.mikrocontroller.net/articles/Pollin_Funk-AVR-Evaluationsboard#Z.C3.A4hler_mit_LCD-Anzeige

von Peter D. (peda)


Lesenswert?

yalu schrieb:
> PS: Ich kenne das AVR-Studio nicht. Möglicherweise gibt es dort eine
> Klickibunti-Methode (Menü o.ä.), um eine Datei dem Projekt hinzuzufügen.

Ja, gibt es.
Mit dem Makefile muß (sollte) man sich nicht rumplagen.

Mach mal ein Zip von Deinen Sorcefiles und der Projektdatei *.aps.
Dann kann man im Nu sagen, wos klemmt.

Die Integration des WINAVR in das ARVStudio ist sehr gut gelungen.


Peter

von Gerd V. (gerald)


Lesenswert?

Hallo,

ich danke allen, die so schnell geantwortet haben.
Der entscheidende Hinweis kam von Stefan B.
Stefan ich danke Dir.
Schade ist, daß sowas nicht im Tut. beschrieben wird, habe nach solchen 
Hinweisen ca. 2 Tage gesucht auch in AVR-Büchern, bloss nichts 
Brauchbares gefunden.
Egal jetzt, kann endlich mit meinem "Befehlsbasteln" anfangen.
Programmieren kommt wohl erst im laufe der Zeit sfg.

Ich wünschen Euch noch einen schönen Abend

Gerald

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.