Forum: Mikrocontroller und Digitale Elektronik Mit Auslagerung funktionierts nicht mehr


von Jürgen (Gast)


Lesenswert?

Hallo,

ich habe mir ein kleines Versuchsboard gebastelt um in die Matherie C
wieder reinzukommen.
Ein Atmega8581 getaktet mit 4MhZ Quarz 4 Tastern und 4 LED's.

Ich arbeite mit dem AVR-Studio und dem GCC Compiler.

Ein kleines Program habe ich auch schon geschrieben:
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
//#include "warten.h"
5
6
7
//Ein - Ausgänge
8
9
#define    Taster1    PA0
10
#define    Taster2    PA1
11
#define    Taster3    PA2
12
#define    Taster4    PA3
13
#define    Taster    PINA
14
15
#define    LED1    PC0
16
#define    LED2    PC1
17
#define    LED3    PC2
18
#define    LED4    PC3
19
#define    LED5    PC4
20
#define    LED6    PC5
21
#define    LED7    PC6
22
#define    LED8    PC7
23
#define    LED      PORTC
24
25
26
27
28
//Allgemeine Variable
29
30
volatile uint8_t timer;
31
volatile uint8_t timer_m;
32
volatile uint8_t taster;
33
volatile uint16_t halt;
34
35
36
ISR(TIMER0_OVF_vect)
37
{
38
  /* Interrupt Aktion alle
39
  (4000000/64)/125 Hz = 2ms
40
  */
41
    TCNT0 = 0x83;           //Timer mit 131 vorladen
42
  timer_m ++;
43
  timer ++;
44
45
  if (!(Taster &(1<<Taster1)))  //Taster 1 gedrückt
46
  {
47
    taster = 1;
48
  }
49
50
  if (!(Taster &(1<<Taster2)))  //Taster 2 gedrückt
51
  {
52
    taster = 2;
53
  }
54
55
  if (!(Taster &(1<<Taster3)))  //Taster 3 gedrückt
56
  {
57
    taster = 3;
58
  }
59
60
  if (!(Taster &(1<<Taster4)))  //Taster 4 gedrückt
61
  {
62
    taster = 4;
63
  }
64
}
65
66
67
//Hauptprogram
68
69
int main(void)
70
{
71
  //Ein - Ausgänge Definieren
72
73
DDRC  = 0xff;    //PORTC Ausgang
74
PORTA = 0xff;    //PORTA Pullup aktivieren
75
76
// Timer 0 konfigurieren
77
    TCCR0 = (1<<CS01)| (1<<CS00);  // Prescaler 64
78
79
// Overflow Interrupt erlauben
80
    TIMSK |= (1<<TOIE0);
81
82
//Interupt starten
83
sei();
84
85
86
//Eigene Funktionen:
87
88
//Eigene Delay-Schleife
89
90
91
void warte_m(uint16_t halt)    //Mit Tasterabfrage
92
{
93
  timer_m=0;
94
  uint8_t halb;
95
  halb = halt/2;
96
97
  while (!(timer_m == halb))
98
  {
99
  
100
    if (!(Taster &(1<<Taster1)))
101
    {
102
      return;
103
    }
104
105
    if (!(Taster &(1<<Taster2)))
106
    {
107
      return;
108
    }
109
110
    if (!(Taster &(1<<Taster3)))
111
    {
112
      return;
113
    }
114
115
    if (!(Taster &(1<<Taster4)))
116
    {
117
      return;
118
    }  
119
  }
120
  return;
121
}
122
123
124
void warte(uint16_t halt)    //Ohne Tasterabfrage
125
{
126
  timer=0;
127
  uint8_t halb;
128
  halb = halt/2;
129
130
  while (!(timer == halb))
131
  {
132
  
133
  }
134
  return;
135
}
136
137
//Hauptschleife
138
139
  while (1)
140
  {
141
142
143
144
    if (taster == 1)
145
    {
146
        LED = 0x00;
147
        LED |= (1<< LED4) | (1<< LED8);
148
        LED &= ~((1<< LED2) | (1<< LED6));
149
        warte_m(500);
150
        warte_m(500);
151
        LED &= ~((1<< LED4) | (1<< LED8));
152
        LED |= (1<< LED2) | (1<< LED6);
153
        warte_m(500);
154
        warte_m(500);
155
    }
156
    
157
    if (taster == 2)
158
    {
159
160
        LED = 0b00000000;
161
        warte_m(200);
162
        LED = 0b11111111;
163
        warte_m(500);
164
        warte_m(500);
165
    }
166
    
167
    if (taster == 3)
168
    {
169
      
170
      LED = 0x00;
171
      LED = 0b00000010;
172
      warte_m(500);
173
      LED = 0b00001000;
174
      warte_m(500);
175
      LED = 0b00100000;
176
      warte_m(500);
177
      LED = 0b10000000;
178
      warte_m(500);
179
    }
180
    
181
    if (taster == 4)
182
    {
183
      
184
      LED = 0x00;
185
      LED = 0b11111101;
186
      warte_m(300);
187
      LED = 0b11110111;
188
      warte_m(500);
189
      LED = 0b11011111;
190
      warte_m(300);
191
      LED = 0b01111111;
192
      warte_m(500);
193
    }      
194
  }
195
196
}

Das funktioniert auch so wie ichs will.
Jetzt möchte ich die Funktion "void warte_m(uint16_t halt)" und "void 
warte(uint16_t halt)" auslagern. Bin folgender massen vorgegangen.
Hab eine Datei warten.h angelegt. Diese sieht so aus.
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
5
6
void warte_m(uint16_t halt)
7
void warte(uint16_t halt)

Dan eine Datei warten.c
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
#include "warten.h"
5
6
void warte_m(uint16_t halt)    //Mit Tasterabfrage
7
{
8
  timer_m=0;
9
  uint8_t halb;
10
  halb = halt/2;
11
12
  while (!(timer_m == halb))
13
  {
14
  
15
    if (!(Taster &(1<<Taster1)))
16
    {
17
      return;
18
    }
19
20
    if (!(Taster &(1<<Taster2)))
21
    {
22
      return;
23
    }
24
25
    if (!(Taster &(1<<Taster3)))
26
    {
27
      return;
28
    }
29
30
    if (!(Taster &(1<<Taster4)))
31
    {
32
      return;
33
    }  
34
  }
35
  return;
36
}
37
38
39
void warte(uint16_t halt)    //Ohne Tasterabfrage
40
{
41
  timer=0;
42
  uint8_t halb;
43
  halb = halt/2;
44
45
  while (!(timer == halb))
46
  {
47
  
48
  }
49
  return;
50
}

Und die Hauptdatei versuch.c habe ich wie folgt geändert:
1
#include <avr/io.h>
2
#include <stdint.h>
3
#include <avr/interrupt.h>
4
#include "warten.h"
5
6
7
//Ein - Ausgänge
8
9
#define    Taster1    PA0
10
#define    Taster2    PA1
11
#define    Taster3    PA2
12
#define    Taster4    PA3
13
#define    Taster    PINA
14
15
#define    LED1    PC0
16
#define    LED2    PC1
17
#define    LED3    PC2
18
#define    LED4    PC3
19
#define    LED5    PC4
20
#define    LED6    PC5
21
#define    LED7    PC6
22
#define    LED8    PC7
23
#define    LED      PORTC
24
25
26
27
28
//Allgemeine Variable
29
30
volatile uint8_t timer;
31
volatile uint8_t timer_m;
32
volatile uint8_t taster;
33
volatile uint16_t halt;
34
35
36
ISR(TIMER0_OVF_vect)
37
{
38
  /* Interrupt Aktion alle
39
  (4000000/64)/125 Hz = 2ms
40
  */
41
    TCNT0 = 0x83;           //Timer mit 131 vorladen
42
  timer_m ++;
43
  timer ++;
44
45
  if (!(Taster &(1<<Taster1)))  //Taster 1 gedrückt
46
  {
47
    taster = 1;
48
  }
49
50
  if (!(Taster &(1<<Taster2)))  //Taster 2 gedrückt
51
  {
52
    taster = 2;
53
  }
54
55
  if (!(Taster &(1<<Taster3)))  //Taster 3 gedrückt
56
  {
57
    taster = 3;
58
  }
59
60
  if (!(Taster &(1<<Taster4)))  //Taster 4 gedrückt
61
  {
62
    taster = 4;
63
  }
64
}
65
66
67
//Hauptprogram
68
69
int main(void)
70
{
71
  //Ein - Ausgänge Definieren
72
73
DDRC  = 0xff;    //PORTC Ausgang
74
PORTA = 0xff;    //PORTA Pullup aktivieren
75
76
// Timer 0 konfigurieren
77
    TCCR0 = (1<<CS01)| (1<<CS00);  // Prescaler 64
78
79
// Overflow Interrupt erlauben
80
    TIMSK |= (1<<TOIE0);
81
82
//Interupt starten
83
sei();
84
85
86
//Eigene Funktionen:
87
88
//Eigene Delay-Schleife
89
90
91
92
//Hauptschleife
93
94
  while (1)
95
  {
96
97
98
99
    if (taster == 1)
100
    {
101
        LED = 0x00;
102
        LED |= (1<< LED4) | (1<< LED8);
103
        LED &= ~((1<< LED2) | (1<< LED6));
104
        warte_m(500);
105
        warte_m(500);
106
        LED &= ~((1<< LED4) | (1<< LED8));
107
        LED |= (1<< LED2) | (1<< LED6);
108
        warte_m(500);
109
        warte_m(500);
110
    }
111
    
112
    if (taster == 2)
113
    {
114
115
        LED = 0b00000000;
116
        warte_m(200);
117
        LED = 0b11111111;
118
        warte_m(500);
119
        warte_m(500);
120
    }
121
    
122
    if (taster == 3)
123
    {
124
      
125
      LED = 0x00;
126
      LED = 0b00000010;
127
      warte_m(500);
128
      LED = 0b00001000;
129
      warte_m(500);
130
      LED = 0b00100000;
131
      warte_m(500);
132
      LED = 0b10000000;
133
      warte_m(500);
134
    }
135
    
136
    if (taster == 4)
137
    {
138
      
139
      LED = 0x00;
140
      LED = 0b11111101;
141
      warte_m(300);
142
      LED = 0b11110111;
143
      warte_m(500);
144
      LED = 0b11011111;
145
      warte_m(300);
146
      LED = 0b01111111;
147
      warte_m(500);
148
    }      
149
  }
150
151
}

Wenn ich jetzt compilieren möchte kommt folgene Fehlermeldung:

Build started 25.4.2010 at 14:37:03
../versuch.c: In function 'warte_m':
../versuch.c:30: error: expected '=', ',', ';', 'asm' or '__attribute__' 
before 'volatile'
../versuch.c:36: warning: 'signal' attribute only applies to functions
../versuch.c:36: warning: 'used' attribute ignored
../versuch.c:36: warning: 'externally_visible' attribute ignored
../versuch.c:37: error: expected '=', ',', ';', 'asm' or '__attribute__' 
before '{' token
../versuch.c:70: error: expected '=', ',', ';', 'asm' or '__attribute__' 
before '{' token
../versuch.c:197: error: old-style parameter declarations in prototyped 
function definition
../versuch.c:196: error: expected '{' at end of input
make: *** [versuch.o] Error 1
Build failed with 5 errors and 3 warnings...

Ich sitzte jetzt seit Freitagabend an diesem Problem und grigs nicht 
hin. Kann mir jemand helfen?

Danke, Jürgen

von Christoph (Gast)


Lesenswert?

Beim Überfliegen gesehen: in warten.h fehlt in den Zeilen

void warte_m(uint16_t halt)
void warte(uint16_t halt)

das Semikolon am Ende.

von Jürgen (Gast)


Lesenswert?

Danke für die schnelle Antwort.

Auch das habe ich schon versucht.
Dann kommt folgende Meldung:

Build started 25.4.2010 at 14:54:05
avr-gcc -mmcu=atmega8515 -Wl,-Map=versuch.map versuch.o     -o 
versuch.elf
versuch.o: In function `main':
D:\Projekte\testboard\versuch\default/../versuch.c:149: undefined 
reference to `warte_m'
D:\Projekte\testboard\versuch\default/../versuch.c:150: undefined 
reference to `warte_m'
D:\Projekte\testboard\versuch\default/../versuch.c:153: undefined 
reference to `warte_m'
D:\Projekte\testboard\versuch\default/../versuch.c:154: undefined 
reference to `warte_m'
D:\Projekte\testboard\versuch\default/../versuch.c:161: undefined 
reference to `warte_m'
versuch.o:D:\Projekte\testboard\versuch\default/../versuch.c:163: more 
undefined references to `warte_m' follow
make: *** [versuch.elf] Error 1
Build failed with 6 errors and 0 warnings...

von Klaus (Gast)


Lesenswert?

Trotzdem sind die Semikolons dort notwendig. Du hast also noch einen 
weiteren Fehler.

Hast du warten.c zum Projekt hinzugefügt, so dass es auch mit kompiliert 
wird?

von hp-freund (Gast)


Lesenswert?

Die Semikolon in warten.h müssen eingetragen werden.
Des weiteren würde ich die Deklaration:
1
//Ein - Ausgnge
2
3
#define    Taster1    PA0
4
#define    Taster2    PA1
5
#define    Taster3    PA2
6
#define    Taster4    PA3
7
#define    Taster    PINA
8
9
#define    LED1    PC0
10
#define    LED2    PC1
11
#define    LED3    PC2
12
#define    LED4    PC3
13
#define    LED5    PC4
14
#define    LED6    PC5
15
#define    LED7    PC6
16
#define    LED8    PC7
17
#define    LED      PORTC
18
19
20
//Allgemeine Variable
21
22
volatile uint8_t timer;
23
volatile uint8_t timer_m;
24
volatile uint8_t taster;
25
volatile uint16_t halt;

ebenfalls auslagern z.B. in "vars.h" . Diese dann in warten.h einbinden 
dann klappts...

...
hp-freund

von Falk B. (falk)


Lesenswert?

@  Jürgen (Gast)

Schon mal was über Netiquette gelesen? Lange Quelltexte gehören in 
den Anhang!!!

MFG
Falk

von Jürgen (Gast)


Angehängte Dateien:

Lesenswert?

Ohh, Entschuldigung.
Werds das nächste mal gleich so machen.

Ich bin hingegangen und habe die Dateien .c und .h in denn selben Ordner 
gelegt wo auch die versuch.c liegt. Muss ich sonnst noch was machen?

von Karl H. (kbuchegg)


Lesenswert?

Ja.
Du musst natürlich deiner Projektverwaltung auch noch mitteilen, dass 
die Dateien dazugehören

http://www.mikrocontroller.net/articles/FAQ#Ich_hab_da_mehrere_.2A.c_und_.2A.h_Dateien._Was_mache_ich_damit.3F

von Christoph (Gast)


Lesenswert?

Wie schon gesagt, Du musst dafür sorgen das warten.c auch kompiliert und 
gelinkt wird. Ich habe hier gerade kein AVR Studio installiert, aber 
falls Du das Projekt vom Studio verwalten lässt (also kein externes 
makefile benutzt) sollte es reichen warten.c als Quelldatei im AVR 
Studio hinzuzufügen.

Und den Kommentar von hp-freund solltest Du auch beachten: Wenn Du 
versuchst warten.c zu kompilieren wird der Compiler maulen weil er die 
ganzen "Taster" Defines nicht kennt.

von Jürgen (Gast)


Lesenswert?

Juchu, es funktioniert.
Ich muste die .h Daten im AVR-Studio einbinden und die Definitionen habe 
ich so wie oben beschrieben in eine var.H umgesiedelt.
Danke.

Thread kann geschloßen werden.

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.