Forum: Compiler & IDEs Variable in Interrupt übergeben ( in eigenem c-File )


von lightninglord (Gast)


Lesenswert?

Hallo zusammen, ich haben ein kleines Probelm, nämlich das eine Variable 
(1 Byte) nicht in die Interrupt-Routine übergeben wird, obwohl ich sie 
mit volatile definiert hab:

Mein Programm:

main.c

#include "Funktion1.h"
#include <avr/interrupts.h>

Hier rufe ich eine Funktion1 auf, diese liegt im Funktion.c. Diese 
Funktion1 verändert die Variable X.
Ebenso liegt hier der ISR (vector), in diesem wird eine Funktion2 
aufgerufen (  diese liegt ebefalls im Funktion.c ) in der die Variable X 
verändert wird.


Funktion.c
( im Funktion.h: volatile uint8_t X; )

Funktion1: Verändere Variable X, Loop bis X von Funktion2 ( welche in 
dem Interrupt aufgerufen wird ) verändert wird


Interrupt: Rufe Funktion2 auf ( oder eine andere, aber die tut nix zur 
sache )


Jetzt wird die Variable in der Funktion1 gesetzt funktioniert das auch, 
allerdings ist sie in der Funktion2 ( welche DANACH! vom Interrupt 
aufgerufen wird ) immer 0. Das ich irgenwo einen Fehler gemacht hab ist 
mir klar, nur leider finde ich den Fehler nicht, der Compiler meckert 
auch nicht, also werden zumindest alle Files eingebunden.


Grüßle lightninglord

von Peter (Gast)


Lesenswert?

im Funktion.h: volatile uint8_t X;

wenn du in der Funktion eine neue Variabel anlegst dann ist klar das sie 
anders ist. Du musst die variable Global machen.

Etwas mehr quelltext zu zeigen ist aber auch nicht falsch.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> ( im Funktion.h: volatile uint8_t X; )

Das ist eine Definition, die hat in der Headerdatei nichts verloren.

Wenn es denn überhaupt erforderlich ist, X außerhalb des Moduls 
"funktion.c" anzusprechen, dann gehört in die Headerdatei ein

   extern volatile uint8_t X;

und in "funktion.c"

   volatile uint8_t X;

(und gegebenenfalls eine Initialisierung)

von lightninglord (Gast)


Lesenswert?

Hier mein Code, ich hab soviel reincopiert wie es mir möglich ist.


main.c
1
//==== Include Headers ====
2
3
#include "main.h"
4
#include "xxxx35.h"
5
#include "spi.h"
6
#include "hardware.h"
7
#include "usart.h"
8
9
#include <util/delay.h>
10
#include <avr/interrupt.h>
11
12
13
volatile uint8_t *xxxxTxData;
14
volatile uint8_t xxxxTxCnt;
15
16
//==== Main Routine ====
17
18
int main() {
19
20
  cli();        // Disable interrupts
21
  
22
  hwInit();      // Initialize all I/Os
23
  
24
  spiInit();      // Initialize SPI
25
26
  usartInit();
27
28
29
  EICRA |= (1<<ISC01);
30
  sei();
31
  
32
33
  while (1){
34
35
36
  uint8_t *daten ="Hallo\r";
37
38
39
  xxxxTx(12,daten);
40
    
41
  _delay_ms(100);
42
43
  }
44
45
  return 0;
46
}
47
48
49
50
//==== Interrupt Routine ====
51
52
ISR(INT0_vect){
53
54
  if(xxxxStat.Rx == 1){
55
  
56
    rxIsr();                    // if rx-mode call rx
57
58
  }else{
59
  
60
    txIsr();                // if tx-mode call tx
61
62
  }
63
64
}

xxxx35.c
1
//==== Include Headers ====
2
3
#include "main.h"
4
#include "xxxx35.h"
5
#include "spi.h"
6
#include "hardware.h"
7
8
#include <util/delay.h>
9
#include <inttypes.h>
10
#include <avr/interrupt.h>
11
#include <avr/io.h>
12
13
extern volatile uint8_t *xxxxTxData;
14
extern volatile uint8_t xxxxTxCnt;
15
16
17
//====  Transmit Datapacket ====
18
19
void xxxxTx(uint8_t length, uint8_t *data){
20
21
  xxxxTxData = data;
22
  xxxxTxCnt = length;
23
  xxxxStat.Tx_Busy = 1;
24
25
  while( xxxxStat.Tx_Busy == 1 );
26
27
}
28
29
30
31
//==== Resceive Interrupt Routine ====
32
33
void rxIsr(void){
34
35
/*code*/
36
37
  
38
}
39
40
41
42
//==== Resceive Interrupt Routine ====
43
44
void txIsr(void){
45
46
/*code*/
47
    xxxxStat.Tx_Busy = 0;
48
49
/*code*/
50
51
    xxxxTxCnt--;
52
53
/*code*/
54
55
}

xxxx35.h
1
//==== Define Headerfile ====
2
3
#ifndef   _xxxx35_h_
4
#define   _xxxx35_h_
5
6
7
8
//==== Include Headerfiles =====
9
10
#include <inttypes.h>
11
#include "cyw_config.h"
12
#include <avr/interrupt.h>
13
#include <stdbool.h>
14
15
16
17
//==== Global CYWUSB Variables ====
18
19
struct {            // Statusbits used by div. functions
20
21
  uint8_t  Rx      :1;    // XXXX in resceiving-mode
22
  uint8_t  Rx_Valid  :1;    // XXXX data is valid
23
  uint8_t  Rx_Comp    :1;    // Rx is complete
24
  uint8_t Tx      :1;    // XXXX in transmitting-mode
25
  uint8_t  Tx_Busy    :1;    // XXXX is transmitting
26
  uint8_t  Tx_Comp    :1;    // Tx is complete
27
  uint8_t PreBrustDet  :1;    // Prebrust detected
28
  uint8_t  StartConDet  :1;    // Startcondition detected
29
30
}cywStat;
31
32
uint8_t xxxxRxData[8];        // Datapacket for rx/tx consists of 8 Bytes:
33
uint8_t xxxxRxValid[8];
34
uint8_t xxxxRxLen;
35
36
37
38
39
//==== Resceive Interrupt Routine ====
40
41
void rxIsr(void);
42
43
44
45
//==== Resceive Interrupt Routine ====
46
47
void txIsr(void);
48
49
50
51
52
#endif

Es geht sich um die Variable xxxxStat und xxxxTxCnt, beide werden nicht 
übergeben ( auch nach änderung laut Antwort 1 ;-) )

von Peter (Gast)


Lesenswert?

leider ist den dem code nicht ersichtlich wo die variable  xxxxTxCnt 
deklariert wird. So könnte lässt er sich nicht compilieren.

von lightninglord (Gast)


Lesenswert?

In der Main.c:

...
volatile uint8_t *xxxxTxData;
volatile uint8_t xxxxTxCnt;
...

von Karl H. (kbuchegg)


Lesenswert?

lightninglord schrieb:
> In der Main.c:
>
> ...
> volatile uint8_t *xxxxTxData;
> volatile uint8_t xxxxTxCnt;
> ...


So wie du das hast, wächst sich das schnell zum Nightmare aus. (Wo ist 
überhaupt xxxxStat?)

Schmeiss mal alle xxxx... überall raus.

Und dann machst du

xxxx.35
1
//==== Define Headerfile ====
2
3
#ifndef   _xxxx35_h_
4
#define   _xxxx35_h_
5
6
7
8
//==== Include Headerfiles =====
9
10
#include <inttypes.h>
11
#include "cyw_config.h"
12
#include <avr/interrupt.h>
13
#include <stdbool.h>
14
15
16
17
//==== Global CYWUSB Variables ====
18
19
struct {            // Statusbits used by div. functions
20
21
  uint8_t  Rx      :1;    // XXXX in resceiving-mode
22
  uint8_t  Rx_Valid  :1;    // XXXX data is valid
23
  uint8_t  Rx_Comp    :1;    // Rx is complete
24
  uint8_t Tx      :1;    // XXXX in transmitting-mode
25
  uint8_t  Tx_Busy    :1;    // XXXX is transmitting
26
  uint8_t  Tx_Comp    :1;    // Tx is complete
27
  uint8_t PreBrustDet  :1;    // Prebrust detected
28
  uint8_t  StartConDet  :1;    // Startcondition detected
29
30
}cywStat;
31
32
extern uint8_t xxxxRxData[8];        // Datapacket for rx/tx consists of 8 Bytes:
33
extern uint8_t xxxxRxValid[8];
34
extern uint8_t xxxxRxLen;
35
extern uint8_t * volatile xxxxTxData; 
36
extern volatile uint8_t xxxxTxCnt;
37
extern volatile struct cywStat xxxxStat;
38
39
//==== Resceive Interrupt Routine ====
40
41
void rxIsr(void);
42
43
44
45
//==== Resceive Interrupt Routine ====
46
47
void txIsr(void);

in alle anderen *.c includierst du lediglich xxxx35.h (und definierst 
keines deiner xxxxTx... dort selber)

lediglich in xxxx35.c kommt rein
1
//==== Include Headers ====
2
3
#include "main.h"
4
#include "xxxx35.h"
5
#include "spi.h"
6
#include "hardware.h"
7
8
#include <util/delay.h>
9
#include <inttypes.h>
10
#include <avr/interrupt.h>
11
#include <avr/io.h>
12
13
uint8_t xxxxRxData[8];        // Datapacket for rx/tx consists of 8 Bytes:
14
uint8_t xxxxRxValid[8];
15
uint8_t xxxxRxLen;
16
uint8_t * volatile xxxxTxData; 
17
volatile uint8_t xxxxTxCnt;
18
volatile struct cywStat xxxxStat;
19
20
21
//====  Transmit Datapacket ====
22
23
void xxxxTx(uint8_t length, uint8_t *data){
24
25
  xxxxTxData = data;
26
  xxxxTxCnt = length;
27
28
  ...

Ob die volatile da jetzt alle stimmen bin ich mir insbesondere bei der 
struct nicht ganz sicher, aber zumindest ist so erst mal ausgeschlossen, 
dass du mehrere (lokale) Variablen gleichen Namens hast.

von lightninglord (Gast)


Lesenswert?

main.c
1
//==== Include Headers ====
2
3
#include "main.h"
4
#include "cywusb6935.h"
5
#include "spi.h"
6
#include "hardware.h"
7
#include "usart.h"
8
9
#include <util/delay.h>
10
#include <avr/interrupt.h>
11
#include <avr/sleep.h>
12
13
14
//==== Main Routine ====
15
16
int main() {
17
18
  cli();        // Disable interrupts
19
  
20
  hwInit();      // Initialize all I/Os
21
  
22
  spiInit();      // Initialize SPI
23
24
  usartInit();
25
26
  
27
  EICRA |= (1<<ISC01);
28
  sei();
29
  
30
31
  while (1){
32
33
    uint8_t *daten ="Hallo\r";
34
35
    cywTx(12,daten);
36
    
37
    _delay_ms(100);
38
  }
39
40
  return 0;
41
}
42
43
44
//==== CYWUSB Interrupt Routine ====
45
46
ISR(INT0_vect){
47
48
  if(cywStat.Rx == 1){
49
  
50
    rxIsr();                // if rx-mode call rx
51
52
  }else{
53
  
54
    txIsr();                // if tx-mode call tx
55
56
  }
57
58
}


cywusb6935.c
1
//==== Include Headers ====
2
3
#include "main.h"
4
#include "cywusb6935.h"
5
#include "spi.h"
6
#include "hardware.h"
7
8
#include <util/delay.h>
9
#include <inttypes.h>
10
#include <avr/interrupt.h>
11
#include <avr/io.h>
12
13
uint8_t cywRxData[8];        // Datapacket for rx/tx consists of 8 Bytes:
14
uint8_t cywRxValid[8];
15
uint8_t cywRxLen;
16
uint8_t * volatile cywTxData; 
17
volatile uint8_t cywTxCnt;
18
volatile struct __Stat cywStat;
19
20
//==== CYWUSB Transmit Datapacket ====
21
22
void cywTx(uint8_t length, uint8_t *data){
23
24
  cywTxData = data;
25
  cywTxCnt = length;
26
  cywStat.Tx_Busy = 1;
27
28
  usartOut(cywTxCnt);
29
  cywWriteByte( REG_TX_INT_EN, Tx_Emp);
30
31
  while( cywStat.Tx_Busy == 1 );
32
33
  cywRxTxOff();
34
35
}
36
37
38
39
//==== Resceive Interrupt Routine ====
40
41
void rxIsr(void){
42
43
/*code*/
44
45
}
46
47
48
49
//==== Resceive Interrupt Routine ====
50
51
void txIsr(void){
52
53
  /*code*/
54
55
    cywStat.Tx_Busy = 0;
56
57
  /*code*/
58
59
    --cywTxCnt;
60
61
  /*code*/
62
}
cywusb6935.h
1
//==== Define Headerfile ====
2
3
#ifndef   _cywusb6935_h_
4
#define   _cywusb6935_h_
5
6
7
8
//==== Include Headerfiles =====
9
10
#include <inttypes.h>
11
#include "cyw_config.h"
12
#include <avr/interrupt.h>
13
#include <stdbool.h>
14
15
16
17
//==== Global CYWUSB Variables ====
18
19
struct __Stat{      // Statusbits used by div. functions
20
21
  uint8_t  Rx      :1;    // CYWUSB in resceiving-mode
22
  uint8_t  Rx_Valid  :1;    // CYWUSB data is valid
23
  uint8_t  Rx_Comp    :1;    // Rx is complete
24
  uint8_t Tx      :1;    // CYWUSB in transmitting-mode
25
  uint8_t  Tx_Busy    :1;    // CYWUSB is transmitting
26
  uint8_t  Tx_Comp    :1;    // Tx is complete
27
  uint8_t PreBrustDet  :1;    // Prebrust detected
28
  uint8_t  StartConDet  :1;    // Startcondition detected
29
30
};
31
32
extern uint8_t cywRxData[8];        // Datapacket for rx/tx consists of 8 Bytes:
33
extern uint8_t cywRxValid[8];
34
extern uint8_t cywRxLen;
35
extern uint8_t * volatile cywTxData; 
36
extern volatile uint8_t cywTxCnt;
37
extern volatile struct __Stat cywStat;
38
39
40
41
//==== CYWUSB Transmit Datapacket ====
42
43
void cywTx(uint8_t length, uint8_t *data);
44
45
46
47
//==== Resceive Interrupt Routine ====
48
49
void rxIsr(void);
50
51
52
53
//==== Resceive Interrupt Routine ====
54
55
void txIsr(void);
56
57
58
#endif

So jetzt hab ich nochmal alles so geändert wies vorgeschlagen wurde, ich 
hab auch alle Variablen nochmal überarbeitet. Er Compiliert mir jetzt 
alles, der rest vom Code wird alles so verarbeitet wie es soll, aber die 
Variablen cywStat und cywTxCnt werden immer noch nicht übergeben. Kann 
es sein das es nicht geth das die ISR und die Funktionen in 
verschiedenen Files liegen?


Ja es gibt eine App mit CYWUSB6935, das kann ich ja verraten ;-) Als 
grobe Vorlage dient die Cypress-Software, aber wirklich nur als grobe 
Vorlage, denn deren Protokoll sind für meine Zwecke nicht verwendbar, 
mir gehts hauptächlich um die Ansteuerung vom CYWUSB, der Rest 
funktioniert schon fast, nur mit meiner RF erfahrung kann ich ned gerade 
glänzen.

von Oliver (Gast)


Lesenswert?

>...aber die Variablen cywStat und cywTxCnt werden immer noch nicht übergeben.

Übergeben wird da nichts, die Variablen sind global, und damit im 
gesamten Programm definiert und sichtbar.

>Kann es sein das es nicht geth das die ISR und die Funktionen in
>verschiedenen Files liegen?

Nein. Die beiden Variablen sind richtig deklariert, wenn es so nicht 
funktioniert, liegt es nicht an diesen globalen Variablen.

Der Sourcecode zusammengezippt, kompilierbar, und als Anhang wäre 
schöner gewesen.

Oliver

von lightninglord (Gast)


Lesenswert?

So ich hab mal alle relevanten Funktionen und Files in nen eigenes 
Projekt gepackt und siehe da die Variable wird richtig übergeben. Das 
überrascht mich nicht da ich ja sonst nix verändert hab außer nur die 
Notwendigen Funktionen zu kopieren. Auf die Variable wird außer in den 
Funktionen NICHT! zugegriffen. Komisch. Was könnte den das sein?

von Oliver (Gast)


Lesenswert?

>Was könnte den das sein?

Ein Fehler in Zeile 42.

Solange die einzige Fehlerbeschreibung lautet "geht nicht", und kein 
vollständiger Sourcecode (mit makefile oder Projektfiles) vorliegt, ist 
das alles nur fruchtlose Raterei.

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.