www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PIC18F25K22 + MPLABX + C18


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Elzaar (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
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

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




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 erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net