INTERRUPT PROBLEM

Re: INTERRUPT PROBLEM

Postby Manoj » Sat Apr 14, 2018 11:19 am

I will try it.
Manoj
 
Posts: 37
Joined: Mon Apr 09, 2018 8:01 am

Re: INTERRUPT PROBLEM

Postby Manoj » Tue Apr 24, 2018 5:36 am

#define STEPWAVE PORTAbits.RA7
/******************************************************************************************
void __attribute__((__interrupt__, auto_psv)) _T3Interrupt( void )
{
if (IFS0bits.T3IF)
{
// Clear the interrupt flag
IFS0bits.T3IF = 0;
PR3=8000://gives me output frequency of almost 1 khz
STEPWAVE =STEPFLG; //generates 128x frequency for filter on RA7.
STEPFLG = !STEPFLG;
StepCount++;
if (StepCount>=NoSteps){StepCount=0;}

//to check the output waveform: Change to a port pin.

}
}


I still did not checked the "LATA7" I am trying it now but the above code is also working.
PR3=8000://gives output frequency of almost 1khz but its not stable its fluctuating. PR3=1000 gives output frequency of almost 7.9khz.
Please tell me how do I generate the stable frequency squarewaves .

The moment program is uploaded the output is constantly available, I can figure out how to stop or start it using a function call.
Please.tell me how can I call a function to execute this freqency when I want it to execute.
Manoj
 
Posts: 37
Joined: Mon Apr 09, 2018 8:01 am

Re: INTERRUPT PROBLEM

Postby ric » Wed Apr 25, 2018 2:13 am

You only need to load PR3 once, in your initialisation code. There's no point reloading it again every interrupt.
There's no point checking if T3IF is set. If you got into the interrupt service, then it IS set.
That code appears to come from an old PIC with only a single interrupt service vector.

Please show the real code that is toggling the I/O pin.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 659
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Re: INTERRUPT PROBLEM

Postby Manoj » Wed Apr 25, 2018 10:19 am

This is a .h file
Code: Select all
/***********************************************************
#ifndef _HARDWARE_PROFILE_H_
#define _HARDWARE_PROFILE_H_

// Define your clock speed here

// Sample clock speed for a 16-bit processor
#if defined (__C30__)

    // Various clock values
    #define GetSystemClock()            32000000UL
    #define GetPeripheralClock()        (GetSystemClock())
    #define GetInstructionClock()       (GetSystemClock() / 2)

    // Clock values
    #define MILLISECONDS_PER_TICK       10
    #define TIMER_PRESCALER             TIMER_PRESCALER_8   // 8MHz: TIMER_PRESCALER_1
    #define TIMER_PERIOD                20000                // 10ms=20000, 1ms=2000

#elif defined( __PIC32MX__)

    #define USB_A0_SILICON_WORK_AROUND
    //#define RUN_AT_48MHZ
    //#define RUN_AT_24MHZ
    #define RUN_AT_60MHZ
   
    // Various clock values
    #if defined(RUN_AT_48MHZ)
        #define GetSystemClock()            48000000UL
        #define GetPeripheralClock()        48000000UL
        #define GetInstructionClock()       (GetSystemClock() / 2) ???
    #elif defined(RUN_AT_24MHZ)
        #define GetSystemClock()            24000000UL
        #define GetPeripheralClock()        24000000UL
        #define GetInstructionClock()       (GetSystemClock() / 2) ???
    #elif defined(RUN_AT_60MHZ)   
        #define GetSystemClock()            60000000UL
        #define GetPeripheralClock()        60000000UL  // Will be divided down
        #define GetInstructionClock()       (GetSystemClock() / 2) ???
    #else
        #error Choose a speed
    #endif   

    // Clock values
    #define MILLISECONDS_PER_TICK       10                  // -0.000% error
    #define TIMER_PRESCALER             TIMER_PRESCALER_8   // At 60MHz
    #define TIMER_PERIOD                37500               // At 60MHz

#endif


//#define USE_USB_PLL

#if defined(__PIC32MX__)
#endif


// Define the baud rate constants
#if defined(__C30__)
    #define BAUDRATE2       9600UL
    #define BRG_DIV2        4
    #define BRGH2           1
#elif defined (__PIC32MX__)
    #define BAUDRATE2       57600UL
    #define BRG_DIV2        4
    #define BRGH2           1
#endif

#if defined(__PIC24F__)
    #include <p24fxxxx.h>
    #include <uart2.h>
#elif defined(__PIC24H__)
    #include <p24hxxxx.h>
    #include <uart2.h>
#else
    #include <p32xxxx.h>
    #include <plib.h>
    #include <uart2.h>
#endif


// Select your MDD File System interface type
// This library currently only supports a single physical interface layer

//#define USE_SD_INTERFACE_WITH_SPI       // SD-SPI.c and .h
//#define USE_CF_INTERFACE_WITH_PMP       // CF-PMP.c and .h
//#define USE_MANUAL_CF_INTERFACE         // CF-Bit transaction.c and .h
#define USE_USB_INTERFACE               // USB host MSD library



/** TRIS ***********************************************************/
#define INPUT_PIN           1
#define OUTPUT_PIN          0

#endif 
/********************************************************************

___________________________________________________________________________________________________From main program-----___________________________________________________________________
Code: Select all
/****************************************************************************
  Function:
     void InitializeClock( void )

  Description:
    This function initializes the tick timer.  It configures and starts the
    timer, and enables the timer interrupt.  We are using Timer 3 so we can
    also trigger an A/D conversion when the timer rolls over.

  Precondition:
    None

  Parameters:
    None

  Returns:
    None

  Remarks:
    None
  ***************************************************************************/

void InitializeClock( void )
{
       currentTick = 0;
        IPC2bits.T3IP = TIMER_INTERRUPT_PRIORITY;
        IFS0bits.T3IF = 0;
        TMR3 = 0;
        PR3 = TIMER_PERIOD;
        T3CON = TIMER_ON | STOP_TIMER_IN_IDLE_MODE | TIMER_SOURCE_INTERNAL |
                GATED_TIME_DISABLED | TIMER_16BIT_MODE | TIMER_PRESCALER;
        IEC0bits.T3IE = 1;

    return;
}
/****************************************************************************
  Function:
     void InitializeAnalogMonitor( void )

  Description:
    This function initializes the monitoring of the three analog inputs.
    Since we need to monitor Vbus while doing other operations, we will
    simply scan all required input channels: the temperature sensor (AN4),
    the potentiometer (AN5), and Vbus (AN8).

  Precondition:
    None

  Parameters:
    None

  Returns:
    None

  Remarks:
    None
  ***************************************************************************/

void InitializeAnalogMonitor( void )
{
    // Set up the A/D converter
       AD1PCFGL    = ~SCAN_MASK; // Disable digital input on AN4, AN5, AN8
       AD1CSSL     = SCAN_MASK;    // Scan AN4, AN5, AN8
       AD1CON3     = 0x1F05;       // 0001 1111 0000 0101;    31 Tad auto-sample, Tad = 5*Tcy
#ifdef VERSION_INSTRUMENT_5200G
       AD1CON2     = 0x240C;       // 0010 0100 0000 1100;  Scan inputs, 3 conversions per interrupt, MUX A only
#endif
  AD1CON1     = 0x8046;       // 1000 0000 0100 0110 ;  Turn on, start sampling, convert on Timer 3

    // Enable A/D interrupts
   
        IEC0bits.AD1IE = 1;

    return;
}
char ZeroSetting(void)
{
//      FILTEROUT=TRUE;
      Zeroing=FALSE;
      ReadingCount=0;
      CumZero1=0;
      CumZero2=0;
      VectorFlag=0;
//      ZEROINPUT = TRUE;
//      LongDelay(4);
      PR3=1250;         //Corresponds to 50Hzx256 so expected time = 3.125secs.
      Zeroing=TRUE;
      do {}while (Zeroing==TRUE);
//      ZEROINPUT = FALSE;
      return 1;
}
/****************************************************************************
  Function:
    void __attribute__((__interrupt__, auto_psv)) _T5Interrupt(void)

  Description:
   Timer 5 Interrupt occurs upon static condition,
   when PR corresponding to 200 RPM (PR4,5) are matched.
   Thus this int occurs if speed is below 200RPM
   Refeed PR4/5 in InitializeTimers() to change it.

  Precondition:
    None

  Parameters:
    None

  Return Values:
    None

  Remarks:
    None
  ***************************************************************************/

void __attribute__((__interrupt__, auto_psv)) _T5Interrupt( void )
{
    if (IFS1bits.T5IF)
    {
        // Clear the interrupt flag
            IFS1bits.T5IF   = 0;
         OverflowFlag      = TRUE;
         Error3         = TRUE;
         SyncFlag      = 0;
    }
}

/****************************************************************************
  Function:
    void __attribute__((__interrupt__, auto_psv)) _INT0Interrupt(void)

  Description:
    Timer ISR, used to update the tick count.  Since we are using Timer 3, we
    can also trigger an A/D conversion off of the timer.

  Precondition:
    None

  Parameters:
    None

  Return Values:
    None

  Remarks:
    None
  ***************************************************************************/

void __attribute__((__interrupt__, auto_psv)) _INT0Interrupt( void )
{
    if (IFS0bits.INT0IF)
    {   
           IFS0bits.INT0IF   = FALSE;      // Clear the interrupt flag
//If it comes here then no overflow if speed >200:
//This divides the T3 time period by 256 to run ADC interrupt via T3

         TimerLoCount=TMR4;                           //first read Lo count
         TimerHiCount=TMR5HLD;                        //stick the TMR5 held value
         PeriodCountNew=(TimerHiCount*65536+TimerLoCount);   //while the period is computed.
         CountLoLimit=0.98*PeriodCountNew;               //+/- 2% deviation permitted so limits are computed
         CountHiLimit=1.02*PeriodCountNew;
         PR3=PeriodCountNew/NoSteps;                     //PR3 is loaded to generate steps for A/D   
         StepCount=0;                              //Step counter is zeroed on each interrupt.
         CycleCount++;                              //Cycle count is inc.

            if (CycleCount==NoOfCycles)
            {VectorFlag=0;                           //completed 32 cycles averaging.
            }

         OverflowFlag=0;
         if ((PeriodCountOld>=CountLoLimit)&(PeriodCountOld<=CountHiLimit))            
            {
            SyncFlag=1;                              //Sync status is determined with this
                  
            }
         else {SyncFlag=0;}
         PeriodCountOld=PeriodCountNew;                  //Latest reading becomes older one before returning. Stays till the next int. Used for RPM computation in UpdateRPM()
         TMR4=0;                  //reset the timers      //and the timer 4/5 is reset to zero to start the next cycle count.
         TMR5=0;                                 
    }
}

            
/****************************************************************************
  Function:
    void __attribute__((__interrupt__, auto_psv)) _T3Interrupt(void)

  Description:
    Trigger of an A/D conversion off of the timer. PR varies as per T4/5 count
  ***************************************************************************/

void __attribute__((__interrupt__, auto_psv)) _T3Interrupt( void )
{
    if (IFS0bits.T3IF)
    {
        // Clear the interrupt flag
            IFS0bits.T3IF   = 0;
   PR3=1000;
      STEPWAVE = STEPFLG;         //generates 128x frequency for filter on RA7.
      STEPFLG = !STEPFLG;
         StepCount++;
         if (StepCount>=NoSteps){StepCount=0;}
         
                           //to check the output waveform: Change to a port pin.

    }
}

/****************************************************************************
/****************************************************************************
  Function:
    void __attribute__((__interrupt__, auto_psv)) _T2Interrupt(void)

  Description:
    Timer ISR, used to update the tick count as also the Keyboard scan

  Precondition:
    None

  Parameters:
    None

  Return Values:
    None

  Remarks:
    None
  ***************************************************************************/

void __attribute__((__interrupt__, auto_psv)) _T2Interrupt( void )
{
    if (IFS0bits.T2IF)
    {
        // Clear the interrupt flag
            IFS0bits.T2IF   = 0;
           currentTick++;
         Update_KBD();
    }
}

/*******************************************************************************
Function:       void __attribute__((__interrupt__, auto_psv)) _DefaultInterrupt(void)

This is just here to catch any interrupts that we see during debugging.

*******************************************************************************/

void __attribute__((interrupt, auto_psv)) _DefaultInterrupt(void)
{
//  UART2PrintString( "!!! Default interrupt handler !!!\r\n" );
  while (1)
  {
      Nop();
      Nop();
      Nop();
  }
}

void __attribute__((interrupt, auto_psv)) _OscillatorFail(void)
{
//  UART2PrintString( "!!! Oscillator Fail interrupt handler !!!\r\n" );
  while (1)
  {
      Nop();
      Nop();
      Nop();
  }
}


void __attribute__((interrupt, auto_psv)) _AddressError(void)
{
//  UART2PrintString( "!!! Address Error interrupt handler !!!\r\n" );
  while (1)
  {
      Nop();
      Nop();
      Nop();
  }
}      

________________________________________________________________________
I still don't understand how pr3=1250 corresponds to 3.125 sec.

"The reset value for PR3 is 0xFFFF , which means that your timer will overflow every 65536*65535+1001 timer ticks. " I found this in an article .can you explain how pr3 value controls the overflow and frequency in case of 16 bit timer ?

The PR3 concept is totally unclear to me .If you can kindly provide me any sources ,links where this is explained with examples that will be a great help.

thanks in advance
Last edited by ric on Thu Apr 26, 2018 9:30 pm, edited 1 time in total.
Reason: Placed "code" tags around the code.
Manoj
 
Posts: 37
Joined: Mon Apr 09, 2018 8:01 am

Re: INTERRUPT PROBLEM

Postby AussieSusan » Thu Apr 26, 2018 3:46 am

The use of the PRx registers is explained in the data sheet for your MCU (albeit rather briefly and also in the diagrams) and also in the "Timers' FRM section related to your MCU (see Section 14.6 for a diagram that shows what happens when the timer counter matches the PRx value.
Susan
AussieSusan
Verified identity
 
Posts: 173
Joined: Mon Jun 16, 2014 4:45 am
PIC experience: Experienced Hobbyist

Re: INTERRUPT PROBLEM

Postby ric » Thu Apr 26, 2018 9:33 pm

The timer counts from zero until it reaches the value in PR3, then resets back to zero again.
That means the total count is PR3+1 (including zero).
From there, it's simple mathematics to calculate how long it takes to count PR3+1, allowing for your clock speed, and any pre/post-scalers you have enabled.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 659
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Re: INTERRUPT PROBLEM

Postby Manoj » Tue May 01, 2018 10:18 am

I am using this block to generate squarewave. as you can see prescalar is 1:1.Fcy=16MHz.(PLL32MhZ)
I am providing you a table acording to my observation ,PR2 vs output frequency

pr2--------------frequency
200--------------none
250---------------40hz
300---------------100hz
400---------------1.7khz
450---------------9.2khz
500----------------16khz
1000--------------7.820hz
4000---------------1.7khz
8000---------------730hz
10000--------------720Hz
15000-------------360hz
20000--------------340hz
30000hz--------------none
I could not understand the math yet.
I want to generate maximum of 128000Hz. maximum frequency received 15 khz at pr2=500 . Please tell me what to do.
Code:-
Code: Select all
void FrequencyScan(void)
{
TRISA=(TRISA&0b1111111101111111);
T2CON = 0x00; //Stops the Timer1 and reset control reg.
TMR2 =0x00; //Clear contents of the timer register
PR2 = 500;
//IPC0bits.T2IP = 0x02; //Setup Timer1 interrupt for desired priority level
// (This example assigns level 1 priority)
IFS0bits.T2IF = 0; //Clear the Timer1 interrupt status flag
IEC0bits.T2IE = 1; //Enable Timer1 interrupts
T2CONbits.TON = 1; //Start Timer1 with prescaler settings at 1:1 and
T2CONbits.TCKPS = 0b00;
DispFirstLine(0);
Put_String_LCD(" ok ");
DispSecLine(0);
Put_String_LCD(" running ");
if (KEY_PRESSED == S2)
{
KEY_PRESSED=0;
mainstate = OPENING_SCREEN;
return;
}
KEY_PRESSED=0;

}

/*
void __attribute__((__interrupt__, auto_psv)) _T2Interrupt( void )
{
// Interrupt Service Routine code goes here
IFS0bits.T1IF = 0; //Reset Timer1 interrupt flag and Return from ISR

STEPWAVE=STEPFLG;
STEPFLG=!STEPFLG;

}

Thanks
Last edited by ric on Tue May 01, 2018 2:04 pm, edited 1 time in total.
Reason: Placed "code" tags around the code.
Manoj
 
Posts: 37
Joined: Mon Apr 09, 2018 8:01 am

Re: INTERRUPT PROBLEM

Postby ric » Tue May 01, 2018 2:09 pm

Is that your real code?
The ISR is clearing the wrong IF flag.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 659
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products

Re: INTERRUPT PROBLEM

Postby Manoj » Wed May 02, 2018 4:50 am

As expected,=> 1/F=>T=>{1/fcy}*Prescalar*prx;
so,{1/16000000}*1*500=1/16000hz;
and prx=1000,gives,T=1/8000hz;
upto this is expected outcome,
but,prx=400 should give 20000hz,in my case it is incorrect.
can a 32 bit timer solve the problem?

Sorry. I made a mistake ,this is the code .
correct Code:--
void __attribute__((__interrupt__, auto_psv)) _T2Interrupt( void )
{
// Interrupt Service Routine code goes here
IFS0bits.T2IF = 0; //Reset Timer2 interrupt flag and Return from ISR

STEPWAVE=STEPFLG;
STEPFLG=!STEPFLG;

}
thanks
Manoj
 
Posts: 37
Joined: Mon Apr 09, 2018 8:01 am

Re: INTERRUPT PROBLEM

Postby AussieSusan » Wed May 02, 2018 5:00 am

I'd like to see the config bits and the code to initialise the oscillator to make sure that you have set it up correctly.
However when I took the value of PR2=500 and the measured output of 16KHz, then that does create an Fp of 16MHz.
How do STEPWAVE and STEPFLG get connected to an output pin that you are measuring? If one of these is a macro that expands to a LAT register bit then there should be a fairly direct relationship between your PR2 setting and the output frequency, but that is not reflected in your table of results. If not then all bets are off!
Is your table correct? Are you really getting 1.7KHz for PR2 values of both 400 AND 4000? Are the frequency measurements for PR2 set to 250 and 300 correct - i.e. are they really only a few Hertz?
Also, you do have all of that other code you have shown us before still in your app? I would strongly recommend that you create a new program that contains only the config settings, the oscillator initialisation, the timer initialisation and ISR, and the main line. Get that working correctly and then add in the rest of the code. IF that doesn;t work then you can show us *all* of it so we can see what might be going wrong.
Susan
AussieSusan
Verified identity
 
Posts: 173
Joined: Mon Jun 16, 2014 4:45 am
PIC experience: Experienced Hobbyist

PreviousNext

Return to PIC24

Who is online

Users browsing this forum: No registered users and 13 guests

cron