INTERRUPT PROBLEM

INTERRUPT PROBLEM

Postby Manoj » Mon Apr 09, 2018 8:13 am

I want to create squrewave on an output pin using T3 interrupt. The frequency of the square wave will increase by 2% after every second starting from 1hz to 10 khz. using a 8Mhz oscillator,with pic24fj256gb110 chip. I will appreciate your help .
thanking you Manoj
Manoj
 
Posts: 37
Joined: Mon Apr 09, 2018 8:01 am

Re: INTERRUPT PROBLEM

Postby ric » Mon Apr 09, 2018 8:25 am

Have you written any code yet?
It's really hard to guess what sort of help you need without knowing what level you are at now.
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 » Mon Apr 09, 2018 12:45 pm

I have a code already made by a previous employee. It is running and working ,but I do not understand it and no one here can help me . I need to modify the code only. I have skipped the main program and only provided the parts with timers and interrupts . please check the last portion where there is"STEPWAVE"this going to pinn ra7,but this part is incomplete. I have to start from here. just tell me how to control its frequency I thought about using DELAY().but don't know whether I can control the time difference. Thank YOU

Code: Select all
#define STOP_TIMER_IN_IDLE_MODE             0x2000
#define TIMER_SOURCE_INTERNAL               0x0000
#define TIMER_ON                            0x8000
#define GATED_TIME_DISABLED                 0x0000
#define TIMER_16BIT_MODE                    0x0000
#define TIMER_PRESCALER_1                  0x0000
#define TIMER_PRESCALER_8                     0x0010
#define TIMER_PRESCALER_64                0x0020
#define TIMER_PRESCALER_256                0x0030
#define TIMER_INTERRUPT_PRIORITY           0x0002

#define PLL_96MHZ_OFF   0xFFFF
    #define PLL_96MHZ_ON    0xF7FF

_CONFIG3(GWRP_OFF)      // GWRP_OFF :   General Segment Write Protect: Writes to program memory are allowed
_CONFIG2(FNOSC_PRIPLL & FCKSM_CSECMD & POSCMOD_HS & PLL_96MHZ_ON & PLLDIV_DIV2) // Primary HS OSC with PLL, Clock Switching Enabled with Failsafe Monitor, USBPLL /2
_CONFIG1(JTAGEN_OFF & FWDTEN_OFF & ICS_PGx2 )   // JTAG off, watchdog timer off
/******************************************************************************************
// Let compile time pre-processor calculate the PR1 (period)
#define FOSC                72E6    //29414  .
#define PB_DIV              8
#define PRESCALE            256
#define TOGGLES_PER_SEC     1
#define T2_TICK             (FOSC/PB_DIV/PRESCALE/TOGGLES_PER_SEC) 

OSCCON = 0x3402;    // Enable secondary oscillator
            CLKDIV = 0x0000;    // Set PLL prescaler (1:1)
/********************************************************************
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;
}
/***************************
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;       //   Scan inputs, 3 conversions per interrupt, MUX A only [from example, AD1CON2 = 0; // use MUXA, AVss and AVdd are used as Vref+/-]

 AD1CON1     = 0x8046;       // 1000 0000 0100 0110; Turn on, start sampling, convert on Timer 3
/*****************************************************
/* This initialises the Timers 4+5 to run as the main cycle timer in 32bit mode.
The INT0 interrupt will start this timer, and read the last accumulated value.
The TMR5 interrupt will occur on overflow when rotor is static. */

void   InitializeTimers(void)
{      T4CON=0x00;       // Stop any 16/32-bit Timer4 operation
      T5CON=0x00;
      TMR5=0x00;          // Clear contents of the TMR4 and TMR5
      TMR4=0x00;
      PR5=0x0049;       
      PR4=0x3E00;
      IPC7bits.T5IP2=TRUE;
      T4CONbits.T32=TRUE;      //enable 32 bit mode
      IFS1bits.T5IF   = 0;       // Clear Timer 5 Interrupt Flag
      IEC1bits.T5IE=TRUE;         // Enable Timer5 interrupt
      T4CONbits.TON=TRUE;         // Start Timer
      T3CON=0b1000000000000000;      
  IPC2bits.T3IP = TIMER_INTERRUPT_PRIORITY;
        IFS0bits.T3IF = 0;
        TMR3 = 0;
        IEC0bits.T3IE = 1;



//Setup TMR2 for Keyboard scan and tick count:
      T2CON=0x00;
      TMR2=0x00;
      PR2=20000;         //for 10msec
      IFS0bits.T2IF=0;
      IEC0bits.T2IE=1;
}

void IntialiseInterrupts(void)
{
//Setup INT0 Interrupt: Bydefault it is +edge triggered.
      IPC0bits.INT0IP=5;         //Priority 5
      IFS0bits.INT0IF =0;
      IEC0bits.INT0IE=TRUE;         //Enable it
}
/**************************************************************************
void __attribute__((__interrupt__, auto_psv)) _T5Interrupt( void )
{
    if (IFS1bits.T5IF)
    {
        // Clear the interrupt flag
            IFS1bits.T5IF   = 0;
         OverflowFlag      = TRUE;
         Error3         = TRUE;
         SyncFlag      = 0;
    }
}
/*************************************************************
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;                                 
    }
}
/**********************************************************************************************   
void __attribute__((__interrupt__, auto_psv)) _T3Interrupt( void )
{
    if (IFS0bits.T3IF)
    {
        // Clear the interrupt flag
            IFS0bits.T3IF   = 0;

      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.

    }
}
Last edited by ric on Thu Apr 12, 2018 1:00 am, edited 1 time in total.
Reason: Added code tags
Manoj
 
Posts: 37
Joined: Mon Apr 09, 2018 8:01 am

Re: INTERRUPT PROBLEM

Postby AussieSusan » Tue Apr 10, 2018 3:41 am

That code is a real mix of programming styles, and some of them are just plain wrong.
I don't think you have posted everything as there are some values (e.g. TIMER_PRESCALER) that is not defined - TIMER_PRESCALER_1 is defined so is this a mistake?
Also some places you set complete register values (which is not wrong but makes life hard to understand what is going on by using 'magic numbers') and in other places you set bit field (which is more the 'standard' way of coding these MCUs). Also, the general advice is to set up a peripheral (timer in this case) then *then* turn it on. I think the timers are OK here but there are peripherals that simply do not initialise and work correctly if they are turned on and then initialised, which can happen if you write to the whole register at once.
In the ISR, there is no need to test if the xxIF bit is set - the ISR will not be called unless it is. This may be a 'hang over' from the style often used in the 8-bit family of devices and if so, it shows that whoever wrote the code probably didn't understand the MCU properly.
In my experience you almost never need to set the interrupt priorities. An ISR should not run for long and therefore should not hold up other interrupts from begin called.
You initialise the variables OSCCON and CLKDIV outside of any function - I'm surprised that the compiler does not throw an error at this.
I can't see where the variables are defined but they should be defined as 'volatile' if they are updated inside an ISR but read outside. (This applies even to being read in an ISR if you are using the nested ISR capability.)
What is the code actually doing? I suspect that it is being written in a very complex way where it could be much simpler but you have only told us one of the functions that I think it is trying to perform.
I would suggest that you strip out all of the code except that required to simply generate the square wave and get that working. After that you can add back in whatever else the code is supposed to do.
The way I'd go about this is to look at the Output Comparator and set that up in PWM mode to give you the the basic period. You can then update that configuration each second to adjust the PWM period/duty cycle. You will need to work out the basic period so that you can get the steps you need (the range from 1Hz to 10kHz is very large!) but that way the hardware can do the work for you.
Susan
AussieSusan
Verified identity
 
Posts: 173
Joined: Mon Jun 16, 2014 4:45 am
PIC experience: Experienced Hobbyist

Re: INTERRUPT PROBLEM

Postby Manoj » Wed Apr 11, 2018 5:18 am

okay .I am trying now.there was another harwareprofile.h file which forgot to provide here.
please inform me what are relations between thse here
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 
/********************************************************************

I am not asking anything about the usb.

what effect will it have on the below mentioned functions having pll on, off

"AD1CON3 = 0x1F05; // 0001 1111 0000 0101; 31 Tad auto-sample, Tad = 5*Tcy" what is tad? is it always "Tad = 5*Tcy"?

"AD1CON2 = 0x240C; // Scan inputs, 3 conversions per interrupt, MUX A only " how 3 convertions per interrupt?

" PR3=6400;//coresponds to a sampling frequency of 2.5Khz" HOW value of PR3=6400 corresponds to sampling frequency of 2.5khz?

"PR3=1250; //Corresponds to 50Hzx256 so expected time = 3.125secs. " How value of PR3=1250 Corresponds to 50Hzx256 so expected time = 3.125secs?

I figued out Fosc=8mhz, fcy=4mhz,
Fcy = Fosc/2
Fprescalar = Fcy/prescalar( i used 1:x) //can't figure out whether prescalar 256 or 1 or 8 . the results are not matching.
Ttimer= 1/Fprescalar

value in PR3 register = ??ms / Ttimer

I will be glad if you can kindly provide me some explanation with examples.
Thank you.
Last edited by ric on Thu Apr 12, 2018 1:02 am, 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 » Thu Apr 12, 2018 1:17 am

Manoj wrote:...
" PR3=6400;//coresponds to a sampling frequency of 2.5Khz" HOW value of PR3=6400 corresponds to sampling frequency of 2.5khz?

"PR3=1250; //Corresponds to 50Hzx256 so expected time = 3.125secs. " How value of PR3=1250 Corresponds to 50Hzx256 so expected time = 3.125secs?

Those calculations correspond to an Fosc = 32MHz, so Fcy = 16MHz
If PR3 = 6400, then the timer will roll over at Fcy/6400 = 16MHz / 6400 = 2500

If PR3 = 1250, then the timer will roll over at Fcy/1250 = 16MHz / 1250 = 12800 = 50 * 256

I'm glossing over the fact that the actual PRx register should be loaded with one less than the period.
i.e. to get a period of 6400 counts, PR3 should actually be loaded with 6399. The real period is (PR+1).
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 » Thu Apr 12, 2018 4:50 am

ok I got it.
But .How value of PR3=1250 makes expected time = 3.125secs?
Please kindly inform me if u know
Thank you
Manoj
 
Posts: 37
Joined: Mon Apr 09, 2018 8:01 am

Re: INTERRUPT PROBLEM

Postby ric » Thu Apr 12, 2018 2:10 pm

What is the context?
That line you quote doesn't appear in any of the source code you posted.
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 » Fri Apr 13, 2018 5:59 am

Code: Select all
#define STEPWAVE               PORTAbits.RA7
BOOL            STEPFLG;

/****************************************************************************
  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;
      
      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.

    }
}

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

Actually I am looking for a way to generate square waves at pin RA7(stepwave).
So, is it possible anyway to generate the squarewave of desired frequency using T3 or any other timer by varrying the PRx period or by any means. I have the pcb ready and pin RA7 is fixed.
Or is there any way the "DELAY()" function time length can be varied like DELAY(10); //for 100ms
Please need your help.
Last edited by ric on Fri Apr 13, 2018 11:45 am, edited 1 time in total.
Reason: added "code tags" around the code.
Manoj
 
Posts: 37
Joined: Mon Apr 09, 2018 8:01 am

Re: INTERRUPT PROBLEM

Postby ric » Fri Apr 13, 2018 11:52 am

the delay() macro is not a good way to get accurate delays when you have interrupts running, because the delay is simply implemented by executing a known number of instructions.
That means any time spent servicing interrupts is added to the total time.

If you want to switch an output pin, change this
#define STEPWAVE PORTAbits.RA7
to
#define STEPWAVE LATAbits.LATA7

Only use PORTx registers for reading pins, not writing to them.

Once you do that, the "STEPFLG variable becomes redundant, so this code
Code: Select all
          STEPWAVE = STEPFLG;         //generates 128x frequency for filter on RA7.
             STEPFLG = !STEPFLG;

can be reduced to
Code: Select all
          STEPWAVE = !STEPWAVE;         //generates 128x frequency for filter on RA7.


Is that pin toggling at all now?
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

Next

Return to PIC24

Who is online

Users browsing this forum: No registered users and 3 guests

cron