Verwendung von Ein-/Ausgängen in C-Unterfunktion

OP #2559421
Lesenswert?

Hallo,

ich möchte in einer C-Unterfunktion wechselnde Ein-Ausgangswerte 
verarbeiten.

Definiert ist z.B. ein Eingang im main.c
1
#define  IN2      PORTAbits.RA1

Diesen möchte ich in einer Funktion für eine Operation abfragen.

"25:Error [1105] symbol 'IN2' has not been defined" ist die Antwort beim 
Übersetzen. IN2 ist demnach nur im Main definiert.

Ist es gundsätzlich nicht möglich einen Eingang in einer Unterfunktion 
zu nutzen?

Danke,
Basti
#2559473
Lesenswert?

Bastian B. schrieb:
> hm. das klingt schwierig.

Ist es aber nicht.
Du musst dich nur ein wenig mit den Grundlagen auseinandersetzen.

Die erste und wichtigste Grundlage lautet:

# wenn der Compiler ein *.c File übersetzt, dann übersetzt er auch
  nur dieses eine File.
  Was in anderen *.c Files steht, ist zu diesem Zeitpunkt völlig
  uninteressant und kümmert den Compiler nicht die Bohne.

# daraus folgt:
  jedes *.c File muss für sich alleine gesehen in sich vollständig
  sein.

# Jedes *.c File wird von oben nach unten compiliert.
  Daraus folgt: Bevor etwas verwendet werden kann, muss es dem
  Compiler bekannt gemacht werden.
  Es gibt dafür 2 Möglichkeiten
  + Definition
    Eine Definition veranlasst, dass auch im Speicher dafür
    Platz reserviert wird. Eine Variablendefinition ist daher
    dasjenige, welches dafür sorgt, dass eine Variable auch
    tatsächlich erzeugt wird.
  + Deklaration
    Eine Deklaration teilt dem Compiler zur geschätzten Kentnisnahme
    mit, dass etwas woanders existiert und wie es aussieht.
    Eine Deklaration sorgt nicht dafür, dass dafür Speicherplatz
    reserviert wird. Das muss durch eine Definition geschehen

# Aus dem letzten folgt wiederrum
  Alles, auch Variablen, darf nur einmal definiert werden. Man
  kann sich aber mit beliebig vielen Deklarationen darauf beziehen.

# Eine (gloable) Variable wird definiert, indem man sie ausserhalb
  einer Funktion als Variablendefinition, zb
1
    int MeineVar;
  hinschreibt.

# Eine Variablendeklaration wird gebildet, indem man einer gedachten
  Definition das Schlüsselwort 'extern' voranstellt.
  Um sich also aus einem anderen *.c File auf die soeben definierte
  Variable mittels einer Deklaration zu beziehen, schreibt man
1
    extern int MeineVar;

Lies dir in der >>> FAQ <<< die entsprechenden Abschnitte durch:

Punkt 8: Globale Variablen über mehrere Dateien
Punkt 9: Was hat es mit volatile auf sich
Punkt 6: Header File, wie geht das?
Gast #2559474
Lesenswert?

dann mußt du dich auch noch mit "volatile" außeinandersetzen

horst schrieb:
> versuchen, sie nur in einer *.c-Datei zu benötigen und dort als static
> deklarieren
> dich mit "extern" auseinandersetzen

ist immer noch aktuell

vermutlich nicht so praktikabel in dieser situation sind named pipes als 
alternative zur parameterübergabe
OP #2559673
Lesenswert?

ok.  Das habe ich gemacht.

Jetzt gibt es nurnoch ein Problem mit dem Rückgabewert der Funktion.

Der Compiler bringt dieses jedoch in Zusammenhang mit der 
Interruptvariable meines Timers

"Error [1521] This feature is not implemented in compiler. There may be 
a definition of external symbol 'timer' found instead of its 
declaration"

Meine Interruptvariable ist jetzt im Main als
1
volatile unsigned char timer=0

und in der .c Funktion als
1
extern volatile unsigned char timer=0

die Rückgabevariable habe ich schon versucht als alles mögliche zu 
definieren.
1
return x
Gast #2559679
Lesenswert?

Bastian B. schrieb:

> Meine Interruptvariable ist jetzt im Main als
> volatile unsigned char timer=0
> und in der .c Funktion als
> extern volatile unsigned char timer=0
> die Rückgabevariable habe ich schon versucht als alles mögliche zu
> definieren.
> return x

Ist das hier die "kleine Horrorshow der C Programmierung"? Brrr lern 
doch mal anständig programmieren das ziehts einem ja die Schuhe aus.
#2559686
Lesenswert?

Bastian B. schrieb:

> und in der .c Funktion als
>
>
1
extern volatile unsigned char timer=0
>

Du hast im Link etwas überlesen (oder nicht darauf geachtet).
Sobald eine Initialisierung vorhanden ist, wird aus einer Deklaration 
eine Definition.

(ABer das hat nichts damit zu tun, worauf sich der COmpiler in der 
Fehlermeldung bezieht. Da kann man nur raten, weil wir ... KEINE 
HELLSEHER SIND! Zeige deinen Code, dann kann man auch was dazu sagen)
OP #2559716
Lesenswert?

hier der ganze kram in gekürzter Form...
1
//globale Variablen
2
volatile unsigned char timer=0, i=0, sekunde=0;
3
//Funktionen
4
void intcounter(void);              // Aufruf des Serviceroutinenprogramms
5
int Empfang (void);
6
//Interrupt
7

8
#pragma code Timer=0x0008      // Interrupt to CPU Vector to Location 0008h (DB S.98)
9
void High (void)                 
10
{
11
 _asm goto intcounter _endasm       // 
12
}
13

14
//Interrupt-Routine
15

16
#pragma code                     // System Codebereich
17
#pragma interrupt Test        // Kennwort interrupt veranlasst
18

19
void Test ()
20
{
21
    PIR1bits.TMR1IF=0;
22
  timer=1;
23
  if (i==76)
24
  {
25
    sekunde=1;
26
    i=0;
27
  }
28
  else
29
    i++;   
30
}
31

32

33
//Main
34

35
void main (void)
36
{
37

38
  TRISA=0b11100111;     //PORTA Ein-/Ausgänge
39
  PORTA=0;      //PORTA ausschalten
40
  ADCON1=0x0F;               //Alle Port Pins digital
41
  TRISB=0;       //PORTB - Ausgang
42
  PORTB=0;      //PORTB ausschalten
43
        CMCON = 0x07;         //Komparatoreinänge deaktivieren
44
  T1CON=0b10000001;    //Timer1 - 16bit - kein Voteiler - aktiv
45
  TMR1H=0;            //Timer1 - Highbyte = 0
46
  TMR1L=0;      //Timer1 - Lowbyte = 0
47
  INTCON=0b11000000;    //Interrupts zulassen
48
  PIE1=0b00000001;          
49

50

51
  while (1)
52
  {  
53
    if       (IN1==1)  //definierter Eingang in defines.h
54
      PORTB=Empfang();
55
  }
56
}

und nun die Funktion. ist erstmal egal was die macht. Ich will 
nurverstehen, warum es keinen rückgabewert gibt.
1
#include <p18f2550.h>
2
#include "defines.h"
3

4
extern volatile unsigned char timer=0;
5

6
int Empfang (void)
7
{
8
  unsigned int Zyklus=0;    //Zeitwert der Zeitmerssung
9

10

11

12
  while (Sender==1)
13
  {
14
          if (timer==1)   //Synchronisationsbitlänge messen (Zyklus)
15
    {
16
      timer=0;
17
      Zyklus++;
18
    }
19
  }
20
return Zyklus;
21
}

Vielen Dank
#2559725
Lesenswert?

Bastian B. schrieb:

> extern volatile unsigned char timer=0;


Fehlermeldung

"Error [1521] This feature is not implemented in compiler. There may be
a definition of external symbol 'timer' found instead of its
declaration"

Bei nochmaligem Drüber-Nachdenken könnte das trotzdem stimmen (Ich hatte 
den GCC im Hinterkopf).
Der Compiler beschwert sich, dass du versuchst in einer Deklaration eine 
Initialisierung zu machen.

Schmeiss die Initialisierung weg, so wie das in C vorgesehen ist.
#2559764
Lesenswert?

Bastian B. schrieb:
> Damit ist die Fehlermeldung schonmal weg.
>
> Dafür gibt es eine Neue.


Wird das jetzt ein Ratespielchen:

Ich programmiere und ihr sucht in meinem Code nach den Fehlern, die mir 
der Compiler meldet.

> Error - could not find definition of symbol 'intcounter' in file
> './main.o'.

Was bedeutet die Fehlermeldung, welche Wörter kommen vor, wovon ist die 
Rede.
Danach gehst du in deinen Code und siehst nach wo spezfische Wörter aus 
der Fehlermeldung (intcounter) vorkommen und wie das mit deiner 
Rohübersetzung der Fehlermeldung zuammenhängt.
Gast #2559784
Lesenswert?

Bastian B. schrieb:

> void High (void)
> {
>  _asm goto intcounter _endasm       //
> }

> //Interrupt-Routine
>
> #pragma code                     // System Codebereich
> #pragma interrupt Test        // Kennwort interrupt veranlasst
>
> void Test ()
> {
>     PIR1bits.TMR1IF=0;
>   timer=1;
>   if (i==76)
>   {
>     sekunde=1;
>     i=0;
>   }
>   else
>     i++;
> }

Siehst du den Fehler??

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren