www.mikrocontroller.net

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


Autor: mohcine (Gast)
Datum:

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

}

Autor: Falk Brunner (falk)
Datum:

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

Autor: Niels Hüsken (monarch35)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
stichwort: VOLATILE!

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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Niels Hüsken (monarch35)

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

Das verursacht aber kaum die Fehlermeldung.

MFG
Falk

Autor: Elbegucker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
versuchs doch mal mit

int main(void)

Autor: Niels Hüsken (monarch35)
Datum:

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

Autor: cela (Gast)
Datum:

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

Autor: Detlev T. (detlevt)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich rate mal, dass das statement
#pragma origin 4

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

Autor: mohcine (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke schön für dein Antwort


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

PS:mein Compiler  cc5x

Autor: Detlev T. (detlevt)
Datum:

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

Autor: holger (Gast)
Datum:

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

#include <MATH16.H>
//#pragma library 1 //.. library functions that are deleted if unused

//#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 !

Autor: mohcine (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen dank   holger

Es hat geklappt   

Autor: Michael G. (linuxgeek) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das muss man erstmal als C-Code erkennen, grausam.

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.