Author Topic: software timer interrupt  (Read 3840 times)

prh

  • Jr. Member
  • **
  • Posts: 5
    • View Profile
software timer interrupt
« on: July 10, 2014, 05:24:57 AM »
Hi,
I'm using multiple SBC66EC with heavily modified webproject firmware. We now have a requirement for a high speed PID loop (1ms or better cycle time) based on a single analog input and a single PWM output.
I've tried inserting the code in the main loop but the co-operative multitasking of the HTTP and other tasks  make this too slow and to much variation in speed when there is web activity.

I've identified that a software timer interrupt is the way to go for the PID and was using the "ledflash_int/main.c" code as a starting point. Unfortunately timer1 is already used by the Tick.c code for system timer. What other timer may I use in the webproject and is there some example code?

Also what is the quickest way in an interrupt routine to make an ADC read of a particular pin (and how many clock cycles does that take) , and same question or setting a new PWM value for an output pin (cycle count?) - I'd like to get a feel of the latency involved so I can get some correct factors in my PID control.

Many thanks.


modtro2

  • Administrator
  • Hero Member
  • *****
  • Posts: 564
    • View Profile
Re: software timer interrupt
« Reply #1 on: July 10, 2014, 05:32:25 AM »
Hi, I will get back to you in detail tomorrow when I am back in the office. There are plenty of free timers. I will send you the sample code for implementing a timer ISR.

prh

  • Jr. Member
  • **
  • Posts: 5
    • View Profile
Re: software timer interrupt
« Reply #2 on: July 10, 2014, 06:00:00 AM »
Hi, I will get back to you in detail tomorrow when I am back in the office. There are plenty of free timers. I will send you the sample code for implementing a timer ISR.

Thank you. I've made some partial progress. I found some microchip documentation for the PIC and got the following code working:

This initializes the timer
Code: [Select]
        T2CON = 0x00; //Stops the Timer2 and reset control reg.
        TMR2 = 0x00; //Clear contents of the timer register
        PR2 = 15625; //? 15625 seems to give me ~1ms interupts ?
        IPC1bits.T2IP = 0x02; //Setup Timer2 interrupt for desired priority level
        // (this example assigns level 1 priority)
        IFS0bits.T2IF = 0; //Clear the Timer2 interrupt status flag
        IEC0bits.T2IE = 1; //Enable Timer2 interrupts
        //T2CONbits.TGATE = 1; //Set up Timer2 for operation in Gated
        //Time Accumulation mode
        T2CONbits.TON = 1; //Start Timer2

This is my PID code (some counters for debugging only so far):
Code: [Select]
void __attribute__((__interrupt__, __shadow__)) _T2Interrupt (void)
{
    PID_Counter++;  //PRH increment counter, this is unsigned so just let it wrap around
    Tick=TickGet();
    PID_Ticks=Tick-PID_Tick_Old;
    PID_Tick_Old=Tick;
   
    IFS0bits.T2IF = 0;    //Clear interrupt status bit Timer2
}

I'm not sure why (by trial an error) that 
Code: [Select]
PR2 = 15625; gives me ~1ms interrupts so I'd like to learn a bit more about setting up the timing parameters.

Next up the ADC read and PWM set....

modtro2

  • Administrator
  • Hero Member
  • *****
  • Posts: 564
    • View Profile
Re: software timer interrupt
« Reply #3 on: July 11, 2014, 03:22:50 AM »
Hi, your code looks about right. For some projects, we have used Timer 2 and 3 as a 32-bit timer to get a higher Tick resolution. So, if you would want to stay compabile with future updates of the Netcruzer Library, you might want to use timer 4 or 5. They are never used by any Netcruzer Library files. But, sounds like you have made many modifications, and probably will not update to any future Netcruzer Library releases.

When configuring your timer, you have to set the timer source, prescaler, and reload value. You should look at the PIC24FJ256GB206 datasheet for details. The PR2 register is the reload value. The timer will increment from 0 to this value(15625 in your case), and on the next count reset to 0 (when timer matches PR2). On this reset, it will trigger your timer ISR. To know how long this is, you need to know the prescaler and timer source. Looking at the PIC24FJ256GB206 datasheet, I can see that when setting T2CON to 0, your prescaler is 1:1, and your timer source is Tosc/2, which is 62.5ns for the SBC66EC. So, you timer will cause and interrupt each (15625+1)*62.5ns = 976,625us. To get exactly 1ms, use 1000,000/62.5 = 16000.

In stead of all this code, you can use the XC16 compiler's PIC24F Peripheral Library. In your XC16 compiler's installation directory, see the "../doc/periph_libs/Microchip PIC24F Peripheral Library.chm" file for help. There are functions for timers, PWM, ADC and everything else. With example code. For example, for the timer, this document has the following example:

Code: [Select]
#define USE_AND_OR /* To enable AND_OR mask setting */
#include<timer.h>

void __attribute__ ((interrupt,no_auto_psv)) _T2Interrupt (void)
{
   T2_Clear_Intr_Status_Bit;
}

void Test_Timer2(void)
{
   ConfigIntTimer2(T2_INT_ON|T2_INT_PRIOR_1);/*Enable Interrupt*/
   OpenTimer2(T2_ON,0x9C40); //Timer is configured for 10 msec
   /*
   USER CODE
   */
   CloseTimer2();
}

There are also functions and examples for using the ADC and PWM peripherals.

prh

  • Jr. Member
  • **
  • Posts: 5
    • View Profile
Re: software timer interrupt
« Reply #4 on: July 11, 2014, 07:03:50 AM »
Thank you. On a related note I was debugging my interrupt routine to detrimne/prove how regular its timing it.

I found that calls to "TickGet()" in the interrupt routine (to fetch the system timer for reference) will cause the SBC to "hang" after 1-5 minutes.

Is this a known issue?
Thanks.


modtro2

  • Administrator
  • Hero Member
  • *****
  • Posts: 564
    • View Profile
Re: software timer interrupt
« Reply #5 on: July 17, 2014, 11:19:47 PM »
Hi, when writing embedded code, you must always take care what functions you call from an interrupt ISR. Best is to keep your ISR code as short as possible, and not call any functions from it. If you have to call functions from within an ISR, special care must be taken that they are thread safe. The TickGet() function should not be called from within an ISR. Is there a work around you could use? Could you possibly post your ISR code.

prh

  • Jr. Member
  • **
  • Posts: 5
    • View Profile
Re: software timer interrupt
« Reply #6 on: July 18, 2014, 05:17:51 AM »
Hi, when writing embedded code, you must always take care what functions you call from an interrupt ISR. Best is to keep your ISR code as short as possible, and not call any functions from it. If you have to call functions from within an ISR, special care must be taken that they are thread safe. The TickGet() function should not be called from within an ISR. Is there a work around you could use? Could you possibly post your ISR code.

I have stopped using the TickGet(), as it wasn't critical to my code (at this time). However I must use adcGetChanMv(ADC_CH_X1) and  pwm4SetPercent() as part of the PID loop. I've had no problems with them to date, but can you confirm if they are ok to use in the interrupt?