mikrocontroller.net

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


Autor: lightninglord (Gast)
Datum:

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

Autor: Peter (Gast)
Datum:

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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

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

Autor: lightninglord (Gast)
Datum:

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


main.c
//==== Include Headers ====

#include "main.h"
#include "xxxx35.h"
#include "spi.h"
#include "hardware.h"
#include "usart.h"

#include <util/delay.h>
#include <avr/interrupt.h>


volatile uint8_t *xxxxTxData;
volatile uint8_t xxxxTxCnt;

//==== Main Routine ====

int main() {

  cli();        // Disable interrupts
  
  hwInit();      // Initialize all I/Os
  
  spiInit();      // Initialize SPI

  usartInit();


  EICRA |= (1<<ISC01);
  sei();
  

  while (1){


  uint8_t *daten ="Hallo\r";


  xxxxTx(12,daten);
    
  _delay_ms(100);

  }

  return 0;
}



//==== Interrupt Routine ====

ISR(INT0_vect){

  if(xxxxStat.Rx == 1){
  
    rxIsr();                    // if rx-mode call rx

  }else{
  
    txIsr();                // if tx-mode call tx

  }

}

xxxx35.c
//==== Include Headers ====

#include "main.h"
#include "xxxx35.h"
#include "spi.h"
#include "hardware.h"

#include <util/delay.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/io.h>

extern volatile uint8_t *xxxxTxData;
extern volatile uint8_t xxxxTxCnt;


//====  Transmit Datapacket ====

void xxxxTx(uint8_t length, uint8_t *data){

  xxxxTxData = data;
  xxxxTxCnt = length;
  xxxxStat.Tx_Busy = 1;

  while( xxxxStat.Tx_Busy == 1 );

}



//==== Resceive Interrupt Routine ====

void rxIsr(void){

/*code*/

  
}



//==== Resceive Interrupt Routine ====

void txIsr(void){

/*code*/
    xxxxStat.Tx_Busy = 0;

/*code*/

    xxxxTxCnt--;

/*code*/

}

xxxx35.h
//==== Define Headerfile ====

#ifndef   _xxxx35_h_
#define   _xxxx35_h_



//==== Include Headerfiles =====

#include <inttypes.h>
#include "cyw_config.h"
#include <avr/interrupt.h>
#include <stdbool.h>



//==== Global CYWUSB Variables ====

struct {            // Statusbits used by div. functions

  uint8_t  Rx      :1;    // XXXX in resceiving-mode
  uint8_t  Rx_Valid  :1;    // XXXX data is valid
  uint8_t  Rx_Comp    :1;    // Rx is complete
  uint8_t Tx      :1;    // XXXX in transmitting-mode
  uint8_t  Tx_Busy    :1;    // XXXX is transmitting
  uint8_t  Tx_Comp    :1;    // Tx is complete
  uint8_t PreBrustDet  :1;    // Prebrust detected
  uint8_t  StartConDet  :1;    // Startcondition detected

}cywStat;

uint8_t xxxxRxData[8];        // Datapacket for rx/tx consists of 8 Bytes:
uint8_t xxxxRxValid[8];
uint8_t xxxxRxLen;




//==== Resceive Interrupt Routine ====

void rxIsr(void);



//==== Resceive Interrupt Routine ====

void txIsr(void);




#endif

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

Autor: Peter (Gast)
Datum:

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

Autor: lightninglord (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der Main.c:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
//==== Define Headerfile ====

#ifndef   _xxxx35_h_
#define   _xxxx35_h_



//==== Include Headerfiles =====

#include <inttypes.h>
#include "cyw_config.h"
#include <avr/interrupt.h>
#include <stdbool.h>



//==== Global CYWUSB Variables ====

struct {            // Statusbits used by div. functions

  uint8_t  Rx      :1;    // XXXX in resceiving-mode
  uint8_t  Rx_Valid  :1;    // XXXX data is valid
  uint8_t  Rx_Comp    :1;    // Rx is complete
  uint8_t Tx      :1;    // XXXX in transmitting-mode
  uint8_t  Tx_Busy    :1;    // XXXX is transmitting
  uint8_t  Tx_Comp    :1;    // Tx is complete
  uint8_t PreBrustDet  :1;    // Prebrust detected
  uint8_t  StartConDet  :1;    // Startcondition detected

}cywStat;

extern uint8_t xxxxRxData[8];        // Datapacket for rx/tx consists of 8 Bytes:
extern uint8_t xxxxRxValid[8];
extern uint8_t xxxxRxLen;
extern uint8_t * volatile xxxxTxData; 
extern volatile uint8_t xxxxTxCnt;
extern volatile struct cywStat xxxxStat;

//==== Resceive Interrupt Routine ====

void rxIsr(void);



//==== Resceive Interrupt Routine ====

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
//==== Include Headers ====

#include "main.h"
#include "xxxx35.h"
#include "spi.h"
#include "hardware.h"

#include <util/delay.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/io.h>

uint8_t xxxxRxData[8];        // Datapacket for rx/tx consists of 8 Bytes:
uint8_t xxxxRxValid[8];
uint8_t xxxxRxLen;
uint8_t * volatile xxxxTxData; 
volatile uint8_t xxxxTxCnt;
volatile struct cywStat xxxxStat;


//====  Transmit Datapacket ====

void xxxxTx(uint8_t length, uint8_t *data){

  xxxxTxData = data;
  xxxxTxCnt = length;

  ...

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.

Autor: lightninglord (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
main.c
//==== Include Headers ====

#include "main.h"
#include "cywusb6935.h"
#include "spi.h"
#include "hardware.h"
#include "usart.h"

#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>


//==== Main Routine ====

int main() {

  cli();        // Disable interrupts
  
  hwInit();      // Initialize all I/Os
  
  spiInit();      // Initialize SPI

  usartInit();

  
  EICRA |= (1<<ISC01);
  sei();
  

  while (1){

    uint8_t *daten ="Hallo\r";

    cywTx(12,daten);
    
    _delay_ms(100);
  }

  return 0;
}


//==== CYWUSB Interrupt Routine ====

ISR(INT0_vect){

  if(cywStat.Rx == 1){
  
    rxIsr();                // if rx-mode call rx

  }else{
  
    txIsr();                // if tx-mode call tx

  }

} 



cywusb6935.c
//==== Include Headers ====

#include "main.h"
#include "cywusb6935.h"
#include "spi.h"
#include "hardware.h"

#include <util/delay.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/io.h>

uint8_t cywRxData[8];        // Datapacket for rx/tx consists of 8 Bytes:
uint8_t cywRxValid[8];
uint8_t cywRxLen;
uint8_t * volatile cywTxData; 
volatile uint8_t cywTxCnt;
volatile struct __Stat cywStat;

//==== CYWUSB Transmit Datapacket ====

void cywTx(uint8_t length, uint8_t *data){

  cywTxData = data;
  cywTxCnt = length;
  cywStat.Tx_Busy = 1;

  usartOut(cywTxCnt);
  cywWriteByte( REG_TX_INT_EN, Tx_Emp);

  while( cywStat.Tx_Busy == 1 );

  cywRxTxOff();

}



//==== Resceive Interrupt Routine ====

void rxIsr(void){

/*code*/

}



//==== Resceive Interrupt Routine ====

void txIsr(void){

  /*code*/

    cywStat.Tx_Busy = 0;

  /*code*/

    --cywTxCnt;

  /*code*/
} 

cywusb6935.h
//==== Define Headerfile ====

#ifndef   _cywusb6935_h_
#define   _cywusb6935_h_



//==== Include Headerfiles =====

#include <inttypes.h>
#include "cyw_config.h"
#include <avr/interrupt.h>
#include <stdbool.h>



//==== Global CYWUSB Variables ====

struct __Stat{      // Statusbits used by div. functions

  uint8_t  Rx      :1;    // CYWUSB in resceiving-mode
  uint8_t  Rx_Valid  :1;    // CYWUSB data is valid
  uint8_t  Rx_Comp    :1;    // Rx is complete
  uint8_t Tx      :1;    // CYWUSB in transmitting-mode
  uint8_t  Tx_Busy    :1;    // CYWUSB is transmitting
  uint8_t  Tx_Comp    :1;    // Tx is complete
  uint8_t PreBrustDet  :1;    // Prebrust detected
  uint8_t  StartConDet  :1;    // Startcondition detected

};

extern uint8_t cywRxData[8];        // Datapacket for rx/tx consists of 8 Bytes:
extern uint8_t cywRxValid[8];
extern uint8_t cywRxLen;
extern uint8_t * volatile cywTxData; 
extern volatile uint8_t cywTxCnt;
extern volatile struct __Stat cywStat;



//==== CYWUSB Transmit Datapacket ====

void cywTx(uint8_t length, uint8_t *data);



//==== Resceive Interrupt Routine ====

void rxIsr(void);



//==== Resceive Interrupt Routine ====

void txIsr(void);


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

Autor: Oliver (Gast)
Datum:

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

Autor: lightninglord (Gast)
Datum:

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

Autor: Oliver (Gast)
Datum:

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

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.