Forum: Mikrocontroller und Digitale Elektronik Probleme mit interrupt bitte Hilfe!!


von mohcine (Gast)


Lesenswert?

Probleme mit  interrupt  bitte Hilfe!!


Die ISR (interrupt ISR(void)) wird alle 64ms aufgerufen und
besitzt „nur“ die Aufgabe eine 10-Sekunden Zeitbasis zu erzeugen, indem 
sie ein
Botschaftsflags für das Hauptprogramm erzeugt. Damit eine Zeit von einer 
Sekunde
entsteht, muss die ISR 156-mal aufgerufen werden (156 x 64ms = 9984ms 
also ca. 10 Sekunde).   (Takt =4Mhz)

Nur wenn ich das Programm laufen lasse dann bekomme ich diese Fehler

Error[1] C:\Dokumente und Einstellungen\DELL1\Eigene Dateien\test234.c 
78 : Overlapping code  (The pointer to the next free location in each 
code page can not be  moved backwards (only forwards). This also applies 
if locations was  skipped by an earlier #pragma origin statement)

Bitte helfen sie mir!!

Danke schön

Code:


//#include<pic16f648a.h>
#include <int16CXX.H> // Ist fuer die Interrupts notwendig
#include <INLINE.H>      // Ist fuer Assembleranweisungen notwendig
#include <MATH16.H>
//#pragma library 1 //.. library functions that are deleted if unused

//#pragma Bibliothek 1     // Funktionen, werden gelöscht, wenn nicht 
genutzten


/****************** Externe Register 
***************************************************/
char FLAGISR;                // beinhaltet Botschaftsflags ISR -> HP
char ZAEHLERISR;          // Zaehlregister fuer 10-Sekunden-Zeitbasis


/****************** Bits in den externen Registern 
**************************************/

 bit FLAG10SEK  @ FLAGISR.0;

/****************** Konstanten 
**********************************************************/
/* Konstante fuer Zeitbasis */
#define KONSTISR10SEK 156

/****************** Portbelegung 
********************************************************/

 bit Pullup  @ PORTA.0;
 bit NCS @ PORTA.1;
 bit SCK @ PORTA.2;
 bit SDI @ PORTA.3;
 bit SDO @ PORTA.4;

/****************** Konstanten 
**********************************************************/


/* Konstanten fuer den Reifendruck-Sensor */

#define MESSUNG_DRUCK 0x31      // 00110001
#define RCPD 0x2C               //00101100
#define MEASURE_TEMPERATUR 0xAD //1010 1101
#define RCTMP 0xB0              //1011 0000
#define MEASURE_BATTERY 0x25    //0010 0101
#define RCBD 0x29               //0010 1001

/* Konstanten fuer die codierung */

#define Druck_Code 0x00
#define Temperatur_Code 0x01
#define battery_Code 0x02


//#define NOP()  {#asm nop #endasm }


/****************** Konfigurations 
********************************************************/
#pragma config |= 0b.11110100100010         // Konfigurationswort
                                            // Bit 4,1-0: FOSC=HS (010)
                                            // Bit 2    : WDTE=OFF (0)
                                            // Bit 3    : PWRTE=ON  (0)
                                       // Bit 5    : MCLRE( RESET-Pin 
)=1
                                        // Bit 6    : BODEN=off(0)
                                        // Bit 7    : LVP  = 0  RB4/PGM
                                        // Bit 8    : CPD =OFF (1)
                                        // Bit 12-9 : Unimplemented
                                        // Bit 13   : CP=OFF (1)

/****************** Funktionsprototypen 
*************************************************/
void INIT(void);
void send_command(char command);
char data_empfang(void);
char Tempmessung(void);
char Druckmessung(void);
char Batterymessung(void);
void delay_us(char micro);
void send(unsigned int Data);
void tastendruck (void);

/****************** ISR - Timer0 
********************************************************/

  #pragma origin 4

    interrupt ISR(void)             // Interruptroutin
    {

     int_save_registers // W, STATUS (und PCLATH) retten

     // Beginn der eigentlichen ISR-Routine
      ZAEHLERISR--;
      if (ZAEHLERISR == 0)
      {
       FLAG10SEK = 1; // Botschaftsflag setzen
       ZAEHLERISR = KONSTISR10SEK; // Zaehlregister fuer den 
10-Sekundentakt mit
       // der Konstanten KONSTISR10SEK neu laden
      }
     T0IF = 0;
     // Ende der eigentlichen ISR-Routine
     int_restore_registers // W, STATUS (und PCLATH) Wiederherstellen
   }



/****************** 
********************************************************/
void send_command(char command)
{
  unsigned char mask;

  mask = 1; // bit0 ist gesetzt
  NCS=0;
  nop();
  while(mask != 0){
    if ((mask & command) != 0)
      SDI = 1;
    else
      SDI = 0;
    SCK = 1;
    nop();
    SCK = 0;
    nop();
    mask <<= 1;
  }
  NCS=1;

}


char data_empfang(void)
{ char lesen;
  char mask;

  mask = 1;
  lesen = 0;
  NCS = 0;
  nop();

  while (mask != 0){
    SCK = 1;
    if(SDO == 1){
      lesen |= mask;
    }
    SCK = 0;
    nop();
    mask <<= 1;
  }
  return lesen;
}

char Tempmessung(void)
{
  send_command(MEASURE_TEMPERATUR);
  data_empfang();
  send_command(RCTMP);
  return data_empfang();
}


char Druckmessung(void)
{
  send_command(MESSUNG_DRUCK);
  data_empfang();
  send_command(RCPD);
  return data_empfang();
}

char Batterymessung(void)
{
  send_command(MEASURE_BATTERY);
  data_empfang();
  send_command(RCBD);
  return data_empfang();
}

void delay_us(char micro)
{
    #asm
    pause  nop
           nop
           decfsz  micro,f
           goto    pause
    #endasm
}




void send(unsigned int Data)
{
  int16 i,a ;

  PORTB.0=0;    //startbit;
 for(i=0x200;i>0;i/=2)
  {
   delay_us(104); // 104 us
   a= i & Data;
  if (a !=0)   PORTB.0=1;

  else PORTB.0=0;

  }
   PORTB.0=1;  //Stoppbit
   delay_us(104); // 104 us
}




void tastendruck (void)
{


int16 Data=0;

// while(Pullup==1);

//  Delay1ms(20);
// send  data


  Data = (int16)Temperatur_Code <<8;
  Data =Tempmessung() | Data;// ???
  send(Data);

  Data =(int16) Druck_Code <<8 ;
  Data = Druckmessung()  | Data;
  send(Data);

  Data = (int16)battery_Code <<8 ;
  Data = Batterymessung()  | Data;
  send(Data);

}




void INIT(void)
{
   CMCON=0x07;                        // CMCON  = 0b00000111.... 
Porta=digital I/O
                                     // müssen die Komparatoreingänge 
deaktiviert
                                     // werden,damit die Pins überhaupt 
als digitale I/O-Pins nutzbar sind.

   TMR0 = 0; // Timer0 auf 0 voreinstellen
   OPTION = 0b.0000.0111;

   TRISA= 0b.1011.0001;              //Definition des porta
   TRISB= 0b.1111.1110;              //Definition des portb RB.0 port 
für sender(infineon)

   ZAEHLERISR = KONSTISR10SEK;

}




void main(void)
{
  INIT();
  INTCON = 0b.1010.0000; // Timer0 freigeben durch Setzen von
                         // GIE und T0IE im Register

 if (FLAG10SEK) // Alle 10 Sekunden
 {
    NCS=1;
    tastendruck ();
    FLAG10SEK = 0;
    }

}

von Falk B. (falk)


Lesenswert?

@mohcine (Gast)

>Probleme mit  interrupt  bitte Hilfe!!

Nicht nur das. Auch mit den Forenregeln.

Lange Quelltexte als ANHNANG!

Siehe auch Netiquette

>entsteht, muss die ISR 156-mal aufgerufen werden (156 x 64ms = 9984ms
>also ca. 10 Sekunde).   (Takt =4Mhz)

Das sind aber 16ms Fehler pro 10s, macht 96ms/min, 5,76s/Stunde oder 
138s/Tag. Das muss nicht sein.

AVR - Die genaue Sekunde / RTC

>Nur wenn ich das Programm laufen lasse dann bekomme ich diese Fehler

Du lässt es nicht laufen, du willst es compilieren.

>Error[1] C:\Dokumente und Einstellungen\DELL1\Eigene Dateien\test234.c
>78 : Overlapping code  (The pointer to the next free location in each
>code page can not be  moved backwards (only forwards). This also applies
>if locations was  skipped by an earlier #pragma origin statement)

Ich würde mal das hier entfernen.

 #pragma origin 4

MFG
Falk

von Niels H. (monarch35)


Lesenswert?

stichwort: VOLATILE!

Die definition der variable "FLAG10sek" ist nicht als volatile definiert 
und wird vom compiler optimiert. Deshalb entsteht eine endlosschleife.

von Falk B. (falk)


Lesenswert?

@Niels Hüsken (monarch35)

>und wird vom compiler optimiert. Deshalb entsteht eine endlosschleife.

Das verursacht aber kaum die Fehlermeldung.

MFG
Falk

von Elbegucker (Gast)


Lesenswert?

versuchs doch mal mit

int main(void)

von Niels H. (monarch35)


Lesenswert?

Falk Brunner wrote:

> Das verursacht aber kaum die Fehlermeldung.

Nein, das war auch nur als Hinweis gedacht, das der Code so nicht 
funktionieren wird.

von cela (Gast)


Lesenswert?

Danke schön für ihre Vorschläge  aber leider klappt bis jetzt nicht
Hat jemanden noch eine Idee  bitte!!

von Detlev T. (detlevt)


Lesenswert?

Ich rate mal, dass das statement
1
#pragma origin 4

das Problem ist. Der Compiler dürfte diesen Bereich schon für die 
Interruptvektoren reserviert haben. Besser mit SIGNAL arbeiten.

von mohcine (Gast)


Lesenswert?

danke schön für dein Antwort


>Besser mit SIGNAL arbeiten.
aber was meinst du mit  SIGNAL ??

PS:mein Compiler  cc5x

von Detlev T. (detlevt)


Lesenswert?

mohcine wrote:
> aber was meinst du mit  SIGNAL ??
>
> PS:mein Compiler  cc5x

Stimmt, ich hatte an GCC-AVR gedacht. Mit dem Compiler kenne ich mich 
nicht aus.

Schon einmal geguckt, was in Zeile 78 steht?

von holger (Gast)


Lesenswert?

Das ist ja ein abgefahrener Fehler ;) Mach das mal so:

Entferne #include <MATH16.H>
vor dem #pragma und häng es hinter die Interruptroutine
1
  #pragma origin 4
2
3
    interrupt ISR(void)             // Interruptroutin
4
    {
5
6
     int_save_registers // W, STATUS (und PCLATH) retten
7
8
     // Beginn der eigentlichen ISR-Routine
9
      ZAEHLERISR--;
10
      if (ZAEHLERISR == 0)
11
      {
12
       FLAG10SEK = 1; // Botschaftsflag setzen
13
       ZAEHLERISR = KONSTISR10SEK; // Zaehlregister fuer den
14
10-Sekundentakt mit
15
       // der Konstanten KONSTISR10SEK neu laden
16
      }
17
     T0IF = 0;
18
     // Ende der eigentlichen ISR-Routine
19
     int_restore_registers // W, STATUS (und PCLATH) Wiederherstellen
20
   }
21
22
#include <MATH16.H>
23
//#pragma library 1 //.. library functions that are deleted if unused
24
25
//#pragma Bibliothek 1     // Funktionen, werden gelöscht, wenn nicht

Wenn du math16.h vor der Interruptroutine einsetzt wird bereits
Code erzeugt der über Adresse 4 rübergeht (overlapped).


PS: Deine main() hat keine while(1) Loop !

von mohcine (Gast)


Lesenswert?

Vielen dank   holger

Es hat geklappt   

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Das muss man erstmal als C-Code erkennen, grausam.

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.