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; } }
@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
stichwort: VOLATILE! Die definition der variable "FLAG10sek" ist nicht als volatile definiert und wird vom compiler optimiert. Deshalb entsteht eine endlosschleife.
@Niels Hüsken (monarch35)
>und wird vom compiler optimiert. Deshalb entsteht eine endlosschleife.
Das verursacht aber kaum die Fehlermeldung.
MFG
Falk
Falk Brunner wrote:
> Das verursacht aber kaum die Fehlermeldung.
Nein, das war auch nur als Hinweis gedacht, das der Code so nicht
funktionieren wird.
Danke schön für ihre Vorschläge aber leider klappt bis jetzt nicht Hat jemanden noch eine Idee bitte!!
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.
danke schön für dein Antwort
>Besser mit SIGNAL arbeiten.
aber was meinst du mit SIGNAL ??
PS:mein Compiler cc5x
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?
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 !
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.