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:
void TIMER1_INIT(void){
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);
WriteTimer1(25536); //Timmer 1 load (10ms)
PIR1bits.TMR1IF = 0; //clear interrupt flag
IPR1bits.TMR1IP = 0; //low Prio
PIE1bits.TMR1IE = 1; //Timer 1 Interupt enabel
}
|
der Interrupt sieht da so aus:
//----------------------------------------------------------------------------
// Low priority interrupt vector
#pragma code InterruptVectorLow = 0x18
void InterruptVectorLow (void)
{
_asm
goto InterruptHandlerLow // Sprung zur Interruptroutine
_endasm
}
// Low priority interrupt routine
#pragma code
#pragma interrupt InterruptHandlerLow
void InterruptHandlerLow ()
{
if (PIR1bits.TMR1IF){
WriteTimer1(25536); //Timmer 1 reload (10ms)
RTC_INT(); //RTC
PIR1bits.TMR1IF = 0; //clear interrupt flag
}
}
|
die Funktion RTC_INT(); ist in der timer.h und timer.c enthalten
timer.h:
//==========================================================
//================== Timer Header ===================
//==========================================================
#ifndef _TIMER_H
#define _TIMER_H
#include <p18f25k22.h>
#include <stdlib.h>
#include <timers.h>
#include <stdio.h>
#include "../include/hardware_conf.h"
typedef struct{
unsigned char counter_10ms;
unsigned char counter_100ms;
unsigned char counter_sec;
unsigned char counter_min;
unsigned char counter_h;
unsigned char counter_day;
unsigned char boot_delay;
}RTC;
extern volatile RTC RTC_Value;
extern volatile union{ //Status Flags
struct{
unsigned tick_10ms:1;
unsigned tick_100ms:1;
unsigned tick_sec:1;
unsigned none:5;
} Bit;
unsigned char Byte;
} RTC_Ticks;
extern void RTC_INIT(void);
extern void RTC_INT(void);
extern void TIMER0_INIT(void); //L' CLK Source EXT
extern void TIMER1_INIT(void); //Low Speed RTC Counter
extern void TIMER2_INIT(void); //PWM source counter
extern void TIMER4_INIT(void); //1ms PID Interupt counter
extern void TIMER6_INIT(void); //test counter
#endif
|
timer.c
//==========================================================
//================== Timer Code ===================
//==========================================================
#include "timer.h"
volatile RTC RTC_Value;
volatile union{ //System Ticks
struct{
unsigned tick_10ms:1;
unsigned tick_100ms:1;
unsigned tick_sec:1;
unsigned none:5;
} Bit;
unsigned char Byte;
} RTC_Ticks;
void RTC_INIT(void){
RTC_Value.counter_10ms = 0;
RTC_Value.counter_100ms = 0;
RTC_Value.counter_sec = 0;
RTC_Value.counter_min = 0;
RTC_Value.counter_h = 0;
RTC_Value.counter_day = 0;
RTC_Ticks.Bit.tick_10ms = 0;
RTC_Ticks.Bit.tick_100ms = 0;
RTC_Ticks.Bit.tick_sec = 0;
RTC_Value.boot_delay = 0;
}
void RTC_INT(void){
RTC_Ticks.Bit.tick_10ms = 1; //10ms ticker
RTC_Value.counter_10ms++; //10ms count
if(RTC_Value.counter_10ms >= 10){
RTC_Ticks.Bit.tick_100ms = 1; //100ms tick
RTC_Value.counter_100ms++; //100ms count
RTC_Value.counter_10ms = 0; //reset 10ms count
}
if(RTC_Value.counter_100ms >= 10){
RTC_Ticks.Bit.tick_sec = 1; //1 sec tick
RTC_Value.counter_sec++; //1sec count
RTC_Value.counter_100ms = 0; //reset 100ms count
}
if(RTC_Value.counter_sec >= 60){
RTC_Value.counter_min++; //1min count
RTC_Value.counter_sec = 0; //reset sec count
}
if(RTC_Value.counter_min >= 60){
RTC_Value.counter_h++; //1h count
RTC_Value.counter_min = 0; //reset min count
}
if(RTC_Value.counter_h >= 24){
RTC_Value.counter_day++; //1day count
RTC_Value.counter_h = 0; //reset h count
}
if(RTC_Value.counter_day >= 365){
RTC_Value.counter_day = 0; //reset day count
}
}
void TIMER0_INIT(void){
OpenTimer0( TIMER_INT_OFF & T0_8BIT & T0_SOURCE_EXT & T0_EDGE_FALL & T0_PS_1_1);
WriteTimer0(0); //Timmer 1 load (50mal pro sec)
}
void TIMER1_INIT(void){
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);
WriteTimer1(25536); //Timmer 1 load (10ms)
PIR1bits.TMR1IF = 0; //clear interrupt flag
IPR1bits.TMR1IP = 0; //low Prio
PIE1bits.TMR1IE = 1; //Timer 1 Interupt enabel
}
void TIMER2_INIT(void){
OpenTimer2( TIMER_INT_OFF & T2_PS_1_1 & T2_POST_1_16);
}
void TIMER4_INIT(void){
OpenTimer4(TIMER_INT_ON & T4_PS_1_16 & T4_POST_1_4);
WriteTimer4(0); //Timer 4 Clear
PR4 = 250; //Timer 4 set compare level
PIR5bits.TMR4IF = 0; //clear interrupt flag
PIE5bits.TMR4IE = 1; //Timer 4 Interupt Enabel
IPR5bits.TMR4IP = 1; //Timer 4 Compare Interrupt prio High
}
void TIMER6_INIT(void){
OpenTimer6(TIMER_INT_OFF & T6_PS_1_1 & T6_POST_1_1);
}
|
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:
//----------------------------------------------------------------
//---------------------- RTC Ticks ------------------------
//----------------------------------------------------------------
if(RTC_Ticks.Bit.tick_sec == 1){
if(RTC_Value.boot_delay <= BOOT_DELAY){
RTC_Value.boot_delay++;
}
else{
Self_Control_Menu(); //Selfcontrol Menu und Taster abfrage
test_INT(); //timming rutine für den Selbsttest
}
RTC_Ticks.Bit.tick_sec = 0;
}
if(RTC_Ticks.Bit.tick_100ms == 1){
if(RTC_Value.boot_delay >= BOOT_DELAY){
Netzueberwachung(); //Netzausfall & L' überwachung
}
else{
if(!(PORTC & 0b00000001)){
debug_state = 0; //deaktivirt die debug anzeige
}
}
Laderegler(); //AKKU Ladung Regeln
led_blink_gen(); //erzeugt die LED Blink Takte
RTC_Ticks.Bit.tick_100ms = 0;
}
if(RTC_Ticks.Bit.tick_10ms == 1){
//get_taster(); //abfrage des Prüftasters (rastent ein!!!)
//PID_fade(&LED_I); //fadet den LED PID
RTC_Ticks.Bit.tick_10ms = 0;
}
|
da ist zb.: die Funktion led_blink_gen();
volatile unsigned char blink_count;
volatile union{ //Blink Statuse
struct{
unsigned GE_blink_s:1;
unsigned GR_blink_s:1;
unsigned RE_blink_s:1;
unsigned GE_blink_f:1;
unsigned GR_blink_f:1;
unsigned RE_blink_f:1;
unsigned blinktakt_slow:1;
unsigned blinktakt_fast:1;
} Bit;
unsigned char Byte;
} blink_state;
void led_blink_gen(void){
blink_count++;
blink_state.Bit.blinktakt_fast = (blink_count & 0x01);
blink_state.Bit.blinktakt_slow = ((blink_count >> 3) & 0x01);
if (blink_state.Bit.GE_blink_s) LED_GE = blink_state.Bit.blinktakt_slow;
if (blink_state.Bit.GR_blink_s) LED_GR = !blink_state.Bit.blinktakt_slow;
if (blink_state.Bit.RE_blink_s) LED_RE = blink_state.Bit.blinktakt_slow;
if (blink_state.Bit.GE_blink_f) LED_GE = blink_state.Bit.blinktakt_fast;
if (blink_state.Bit.GR_blink_f) LED_GR = !blink_state.Bit.blinktakt_fast;
if (blink_state.Bit.RE_blink_f) LED_RE = blink_state.Bit.blinktakt_fast;
}
|
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:
// File: 18f25k22_g.lkr
// Linker scrip for PIC18F4550 and storing large structs of Data
#DEFINE _CODEEND _DEBUGCODESTART - 1
#DEFINE _CEND _CODEEND + _DEBUGCODELEN
#DEFINE _DATAEND _DEBUGDATASTART - 1
#DEFINE _DEND _DATAEND + _DEBUGDATALEN
LIBPATH .
#IFDEF _CRUNTIME
#IFDEF _EXTENDEDMODE
FILES c018i_e.o
FILES clib_e.lib
FILES p18f25k22_e.lib
#ELSE
FILES c018i.o
FILES clib.lib
FILES p18f25k22.lib
#FI
#FI
#IFDEF _DEBUGCODESTART
CODEPAGE NAME=page START=0x0 END=_CODEEND
CODEPAGE NAME=debug START=_DEBUGCODESTART END=_CEND PROTECTED
#ELSE
CODEPAGE NAME=page START=0x0 END=0x7FFF
#FI
CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED
CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED
CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED
CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED
#IFDEF _EXTENDEDMODE
DATABANK NAME=gpre START=0x0 END=0x5F
#ELSE
ACCESSBANK NAME=accessram START=0x0 END=0x5F
#FI
DATABANK NAME=gpr0 START=0x60 END=0xFF
DATABANK NAME=gpr1 START=0x100 END=0x1FF
DATABANK NAME=gpr2 START=0x200 END=0x2FF
DATABANK NAME=gpr3 START=0x300 END=0x3FF
DATABANK NAME=gpr4 START=0x400 END=0x4FF
#IFDEF _DEBUGDATASTART
DATABANK NAME=gpr5 START=0x500 END=_DATAEND
DATABANK NAME=dbgspr START=_DEBUGDATASTART END=_DEND PROTECTED
#ELSE //no debug
DATABANK NAME=gpr5 START=0x500 END=0x5FF
#FI
DATABANK NAME=sfr15 START=0xF38 END=0xF5F PROTECTED
ACCESSBANK NAME=accesssfr START=0xF60 END=0xFFF PROTECTED
//DATABANK NAME=adc START=0x600 END=0x6FF
//SECTION NAME=ADC_RAM RAM=adc
#IFDEF _CRUNTIME
SECTION NAME=CONFIG ROM=config
#IFDEF _DEBUGDATASTART
STACK SIZE=0x100 RAM=gpr4
#ELSE
STACK SIZE=0x100 RAM=gpr5
#FI
#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