Guten Morgen, ich habe da mal ein Problem: ich habe ein PIC18F25K22 der als Primäre Aufgabe hat zwei Schaltregler zu Realisieren, nur irgendwie verschwinden mir Variablen zb.: Interrupt vom Timer 1 mit 10ms:
1 | void TIMER1_INIT(void){ |
2 | OpenTimer1( TIMER_INT_ON & T1_16BIT_RW & T1_SOURCE_FOSC_4 & T1_PS_1_4 & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF, TIMER_GATE_OFF & TIMER_GATE_INT_OFF); |
3 | WriteTimer1(25536); //Timmer 1 load (10ms) |
4 | PIR1bits.TMR1IF = 0; //clear interrupt flag |
5 | IPR1bits.TMR1IP = 0; //low Prio |
6 | PIE1bits.TMR1IE = 1; //Timer 1 Interupt enabel |
7 | } |
der Interrupt sieht da so aus:
1 | //---------------------------------------------------------------------------- |
2 | // Low priority interrupt vector |
3 | |
4 | #pragma code InterruptVectorLow = 0x18 |
5 | void InterruptVectorLow (void) |
6 | { |
7 | _asm |
8 | goto InterruptHandlerLow // Sprung zur Interruptroutine |
9 | _endasm |
10 | } |
11 | // Low priority interrupt routine |
12 | #pragma code |
13 | #pragma interrupt InterruptHandlerLow |
14 | |
15 | void InterruptHandlerLow () |
16 | { |
17 | if (PIR1bits.TMR1IF){ |
18 | WriteTimer1(25536); //Timmer 1 reload (10ms) |
19 | RTC_INT(); //RTC |
20 | PIR1bits.TMR1IF = 0; //clear interrupt flag |
21 | } |
22 | } |
die Funktion RTC_INT(); ist in der timer.h und timer.c enthalten timer.h:
1 | //========================================================== |
2 | //================== Timer Header =================== |
3 | //========================================================== |
4 | #ifndef _TIMER_H |
5 | #define _TIMER_H |
6 | #include <p18f25k22.h> |
7 | #include <stdlib.h> |
8 | #include <timers.h> |
9 | #include <stdio.h> |
10 | #include "../include/hardware_conf.h" |
11 | |
12 | typedef struct{ |
13 | unsigned char counter_10ms; |
14 | unsigned char counter_100ms; |
15 | unsigned char counter_sec; |
16 | unsigned char counter_min; |
17 | unsigned char counter_h; |
18 | unsigned char counter_day; |
19 | unsigned char boot_delay; |
20 | }RTC; |
21 | |
22 | extern volatile RTC RTC_Value; |
23 | |
24 | extern volatile union{ //Status Flags |
25 | struct{ |
26 | unsigned tick_10ms:1; |
27 | unsigned tick_100ms:1; |
28 | unsigned tick_sec:1; |
29 | unsigned none:5; |
30 | } Bit; |
31 | unsigned char Byte; |
32 | } RTC_Ticks; |
33 | |
34 | extern void RTC_INIT(void); |
35 | extern void RTC_INT(void); |
36 | |
37 | extern void TIMER0_INIT(void); //L' CLK Source EXT |
38 | extern void TIMER1_INIT(void); //Low Speed RTC Counter |
39 | extern void TIMER2_INIT(void); //PWM source counter |
40 | extern void TIMER4_INIT(void); //1ms PID Interupt counter |
41 | extern void TIMER6_INIT(void); //test counter |
42 | #endif |
timer.c
1 | //========================================================== |
2 | //================== Timer Code =================== |
3 | //========================================================== |
4 | |
5 | #include "timer.h" |
6 | |
7 | volatile RTC RTC_Value; |
8 | |
9 | volatile union{ //System Ticks |
10 | struct{ |
11 | unsigned tick_10ms:1; |
12 | unsigned tick_100ms:1; |
13 | unsigned tick_sec:1; |
14 | unsigned none:5; |
15 | } Bit; |
16 | unsigned char Byte; |
17 | } RTC_Ticks; |
18 | |
19 | |
20 | void RTC_INIT(void){ |
21 | RTC_Value.counter_10ms = 0; |
22 | RTC_Value.counter_100ms = 0; |
23 | RTC_Value.counter_sec = 0; |
24 | RTC_Value.counter_min = 0; |
25 | RTC_Value.counter_h = 0; |
26 | RTC_Value.counter_day = 0; |
27 | RTC_Ticks.Bit.tick_10ms = 0; |
28 | RTC_Ticks.Bit.tick_100ms = 0; |
29 | RTC_Ticks.Bit.tick_sec = 0; |
30 | RTC_Value.boot_delay = 0; |
31 | } |
32 | void RTC_INT(void){ |
33 | RTC_Ticks.Bit.tick_10ms = 1; //10ms ticker |
34 | RTC_Value.counter_10ms++; //10ms count |
35 | |
36 | if(RTC_Value.counter_10ms >= 10){ |
37 | RTC_Ticks.Bit.tick_100ms = 1; //100ms tick |
38 | RTC_Value.counter_100ms++; //100ms count |
39 | RTC_Value.counter_10ms = 0; //reset 10ms count |
40 | } |
41 | if(RTC_Value.counter_100ms >= 10){ |
42 | RTC_Ticks.Bit.tick_sec = 1; //1 sec tick |
43 | RTC_Value.counter_sec++; //1sec count |
44 | RTC_Value.counter_100ms = 0; //reset 100ms count |
45 | } |
46 | if(RTC_Value.counter_sec >= 60){ |
47 | RTC_Value.counter_min++; //1min count |
48 | RTC_Value.counter_sec = 0; //reset sec count |
49 | } |
50 | if(RTC_Value.counter_min >= 60){ |
51 | RTC_Value.counter_h++; //1h count |
52 | RTC_Value.counter_min = 0; //reset min count |
53 | } |
54 | if(RTC_Value.counter_h >= 24){ |
55 | RTC_Value.counter_day++; //1day count |
56 | RTC_Value.counter_h = 0; //reset h count |
57 | } |
58 | if(RTC_Value.counter_day >= 365){ |
59 | RTC_Value.counter_day = 0; //reset day count |
60 | } |
61 | } |
62 | void TIMER0_INIT(void){ |
63 | OpenTimer0( TIMER_INT_OFF & T0_8BIT & T0_SOURCE_EXT & T0_EDGE_FALL & T0_PS_1_1); |
64 | WriteTimer0(0); //Timmer 1 load (50mal pro sec) |
65 | } |
66 | void TIMER1_INIT(void){ |
67 | OpenTimer1( TIMER_INT_ON & T1_16BIT_RW & T1_SOURCE_FOSC_4 & T1_PS_1_4 & T1_OSC1EN_OFF & T1_SYNC_EXT_OFF, TIMER_GATE_OFF & TIMER_GATE_INT_OFF); |
68 | WriteTimer1(25536); //Timmer 1 load (10ms) |
69 | PIR1bits.TMR1IF = 0; //clear interrupt flag |
70 | IPR1bits.TMR1IP = 0; //low Prio |
71 | PIE1bits.TMR1IE = 1; //Timer 1 Interupt enabel |
72 | } |
73 | void TIMER2_INIT(void){ |
74 | OpenTimer2( TIMER_INT_OFF & T2_PS_1_1 & T2_POST_1_16); |
75 | } |
76 | void TIMER4_INIT(void){ |
77 | OpenTimer4(TIMER_INT_ON & T4_PS_1_16 & T4_POST_1_4); |
78 | WriteTimer4(0); //Timer 4 Clear |
79 | PR4 = 250; //Timer 4 set compare level |
80 | PIR5bits.TMR4IF = 0; //clear interrupt flag |
81 | PIE5bits.TMR4IE = 1; //Timer 4 Interupt Enabel |
82 | IPR5bits.TMR4IP = 1; //Timer 4 Compare Interrupt prio High |
83 | } |
84 | void TIMER6_INIT(void){ |
85 | OpenTimer6(TIMER_INT_OFF & T6_PS_1_1 & T6_POST_1_1); |
86 | } |
so habe ich das mit AtMegas schon Problem los gemacht ... die union RTC_Ticks enthält die System Ticks die ich in der main schleife auswerte:
1 | //---------------------------------------------------------------- |
2 | //---------------------- RTC Ticks ------------------------ |
3 | //---------------------------------------------------------------- |
4 | if(RTC_Ticks.Bit.tick_sec == 1){ |
5 | if(RTC_Value.boot_delay <= BOOT_DELAY){ |
6 | RTC_Value.boot_delay++; |
7 | } |
8 | else{ |
9 | Self_Control_Menu(); //Selfcontrol Menu und Taster abfrage |
10 | test_INT(); //timming rutine für den Selbsttest |
11 | } |
12 | RTC_Ticks.Bit.tick_sec = 0; |
13 | } |
14 | |
15 | if(RTC_Ticks.Bit.tick_100ms == 1){ |
16 | if(RTC_Value.boot_delay >= BOOT_DELAY){ |
17 | Netzueberwachung(); //Netzausfall & L' überwachung |
18 | } |
19 | else{ |
20 | if(!(PORTC & 0b00000001)){ |
21 | debug_state = 0; //deaktivirt die debug anzeige |
22 | } |
23 | } |
24 | Laderegler(); //AKKU Ladung Regeln |
25 | |
26 | led_blink_gen(); //erzeugt die LED Blink Takte |
27 | RTC_Ticks.Bit.tick_100ms = 0; |
28 | } |
29 | |
30 | if(RTC_Ticks.Bit.tick_10ms == 1){ |
31 | //get_taster(); //abfrage des Prüftasters (rastent ein!!!) |
32 | //PID_fade(&LED_I); //fadet den LED PID |
33 | RTC_Ticks.Bit.tick_10ms = 0; |
34 | } |
da ist zb.: die Funktion led_blink_gen();
1 | volatile unsigned char blink_count; |
2 | |
3 | volatile union{ //Blink Statuse |
4 | struct{ |
5 | unsigned GE_blink_s:1; |
6 | unsigned GR_blink_s:1; |
7 | unsigned RE_blink_s:1; |
8 | unsigned GE_blink_f:1; |
9 | unsigned GR_blink_f:1; |
10 | unsigned RE_blink_f:1; |
11 | unsigned blinktakt_slow:1; |
12 | unsigned blinktakt_fast:1; |
13 | } Bit; |
14 | unsigned char Byte; |
15 | } blink_state; |
16 | |
17 | void led_blink_gen(void){ |
18 | blink_count++; |
19 | |
20 | blink_state.Bit.blinktakt_fast = (blink_count & 0x01); |
21 | blink_state.Bit.blinktakt_slow = ((blink_count >> 3) & 0x01); |
22 | |
23 | if (blink_state.Bit.GE_blink_s) LED_GE = blink_state.Bit.blinktakt_slow; |
24 | if (blink_state.Bit.GR_blink_s) LED_GR = !blink_state.Bit.blinktakt_slow; |
25 | if (blink_state.Bit.RE_blink_s) LED_RE = blink_state.Bit.blinktakt_slow; |
26 | |
27 | if (blink_state.Bit.GE_blink_f) LED_GE = blink_state.Bit.blinktakt_fast; |
28 | if (blink_state.Bit.GR_blink_f) LED_GR = !blink_state.Bit.blinktakt_fast; |
29 | if (blink_state.Bit.RE_blink_f) LED_RE = blink_state.Bit.blinktakt_fast; |
30 | } |
so jetzt das Problem es geht FAST immer ... die LED blink in 99% schön regelmäßig aber manchmal setz sie ein Takt aus oder Blink 2 mal direkt hintereinander ... Der interrupt kommt konstant (mit HMO und Pass/Fail Test gemessen -> 100% Pass) aber irgendwo muss da was schief laufen ... laut Microchip Support geht es im Simulator -_- ... danke für die Hiefe Microchip ... was mach ich den da falsch? ich hatte die Vermutung das es ein RAM Banking Problem ist ... oder ein Problem mit dem Stack ... aber ich nutze nur 14% vom RAM ... das sind dann nur 2 Bänke soweit ich weiss ... Stack Bank und Data0 Bank Linker Script:
1 | // File: 18f25k22_g.lkr |
2 | // Linker scrip for PIC18F4550 and storing large structs of Data |
3 | |
4 | #DEFINE _CODEEND _DEBUGCODESTART - 1 |
5 | #DEFINE _CEND _CODEEND + _DEBUGCODELEN |
6 | #DEFINE _DATAEND _DEBUGDATASTART - 1 |
7 | #DEFINE _DEND _DATAEND + _DEBUGDATALEN |
8 | |
9 | LIBPATH . |
10 | |
11 | #IFDEF _CRUNTIME |
12 | #IFDEF _EXTENDEDMODE |
13 | FILES c018i_e.o |
14 | FILES clib_e.lib |
15 | FILES p18f25k22_e.lib |
16 | |
17 | #ELSE |
18 | FILES c018i.o |
19 | FILES clib.lib |
20 | FILES p18f25k22.lib |
21 | #FI |
22 | |
23 | #FI |
24 | |
25 | #IFDEF _DEBUGCODESTART |
26 | CODEPAGE NAME=page START=0x0 END=_CODEEND |
27 | CODEPAGE NAME=debug START=_DEBUGCODESTART END=_CEND PROTECTED |
28 | #ELSE |
29 | CODEPAGE NAME=page START=0x0 END=0x7FFF |
30 | #FI |
31 | |
32 | CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED |
33 | CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED |
34 | CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED |
35 | CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED |
36 | |
37 | #IFDEF _EXTENDEDMODE |
38 | DATABANK NAME=gpre START=0x0 END=0x5F |
39 | #ELSE |
40 | ACCESSBANK NAME=accessram START=0x0 END=0x5F |
41 | #FI |
42 | |
43 | DATABANK NAME=gpr0 START=0x60 END=0xFF |
44 | DATABANK NAME=gpr1 START=0x100 END=0x1FF |
45 | DATABANK NAME=gpr2 START=0x200 END=0x2FF |
46 | DATABANK NAME=gpr3 START=0x300 END=0x3FF |
47 | DATABANK NAME=gpr4 START=0x400 END=0x4FF |
48 | |
49 | #IFDEF _DEBUGDATASTART |
50 | DATABANK NAME=gpr5 START=0x500 END=_DATAEND |
51 | DATABANK NAME=dbgspr START=_DEBUGDATASTART END=_DEND PROTECTED |
52 | #ELSE //no debug |
53 | DATABANK NAME=gpr5 START=0x500 END=0x5FF |
54 | #FI |
55 | |
56 | DATABANK NAME=sfr15 START=0xF38 END=0xF5F PROTECTED |
57 | ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED |
58 | |
59 | |
60 | //DATABANK NAME=adc START=0x600 END=0x6FF |
61 | //SECTION NAME=ADC_RAM RAM=adc |
62 | |
63 | |
64 | #IFDEF _CRUNTIME |
65 | SECTION NAME=CONFIG ROM=config |
66 | #IFDEF _DEBUGDATASTART |
67 | STACK SIZE=0x100 RAM=gpr4 |
68 | #ELSE |
69 | STACK SIZE=0x100 RAM=gpr5 |
70 | #FI |
71 | #FI |
ich kann das ganze Projekt auch per E-Mail verschicken wenn jemand eine Idee hat ... ich würde es nur ungern komplet ins World Wide Web stellen ... Gruß Sascha