CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

service the wrong interrupt

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
wynnet



Joined: 02 Dec 2003
Posts: 15

View user's profile Send private message

service the wrong interrupt
PostPosted: Wed Apr 21, 2004 11:42 am     Reply with quote

I have a timer0 interrupt as a clock.
the program works ok
I also would like to generate a long pulse (2 seconds) on port A bit3 at different interval of times.

so I use timer3 for this task.
I have:
setup_timer_3(T3_INTERNAL,T3_DIV_BY_8);
enable_interrupts (GLOBAL);

When I want to make the long pulse:
output_low (PIN_A3);
set_timer3 (0x1111); // any 16 bit number
enable_interrupts(int_timer3);

when the interrupt timer3 overflow
#int_timer3
void timer3_isr()
{
output_high(PIN_A3);
disable_interrupts (int_TIMER3);
}

My problem is the pulse goes low as expected
However, it returns to high in about 60 microseconds. very short
I change the value in set_timer3 from 0x0000, 0x0001, 0xffff
there is no change in the pulse width/time.
The only thing I can think of right now is the timer3_isr () is called by the timer0 when it's overflow.
MY VERSION IS 3.18
and IC 18F452 it does have timer3 and timer0.

I need help with two Timer interrupts.
DragonPIC



Joined: 11 Nov 2003
Posts: 118

View user's profile Send private message

other interrupts
PostPosted: Wed Apr 21, 2004 12:13 pm     Reply with quote

If you suspect other interrupts, disable them. Break your code down to the simplest form possible to test just the part of code you are having problems with.
dyeatman



Joined: 06 Sep 2003
Posts: 1912
Location: Norman, OK

View user's profile Send private message

Timer
PostPosted: Wed Apr 21, 2004 12:54 pm     Reply with quote

It sounds like to me you have a program logic issue. Post your code so we can see what you are doing that may be causing the problem.
RKnapp



Joined: 23 Feb 2004
Posts: 51

View user's profile Send private message

PostPosted: Wed Apr 21, 2004 2:24 pm     Reply with quote

I haven't tested this or consulted the data sheet to see how timer3 behaves, but is it possible that you don't need to disable the timer3 interrupt?

I'm thinking there could be an "extra" interrupt at time zero that fires, and that's why the value you load into the timer itself is irrelevant.

The plan could be, sure, load the timer, enable interrupts, then let the interrupt fire & go to the ISR (interrupt service routine), then reload the timer from within the ISR. But don't disable the interrupt from within the ISR. This way, you should get regularly timed interrupts.

Another plan, the timer0 interrupt is probably firing more often than 2 seconds. Why not put in a strobe inside it and skip timer3? E.g., if it is firing at 1Khz and you're traveling into its #int_rtcc isr every millisecond, why not use a counter in there, and once every 2000 trips, flip the state of your A3 pin? Inside my #int_rtcc ISR, I have lots of "stock" strobe intervals that are set up as little booleans that I use elsewhere in my program.

Just a thought, good luck,

Smile Robert
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: service the wrong interrupt
PostPosted: Wed Apr 21, 2004 2:33 pm     Reply with quote

wynnet wrote:

set_timer3 (0x1111); // any 16 bit number
enable_interrupts(int_timer3);


This is not good because you are not clearing the interupt before enabling it. The interupt flag is not cleared by enabling the interupt. The interupt flag is set when the timer overflows reguardless of if the interupt is enabled. The flag is probably already set when you load the timer and enable the interupt.

The latest versions of the compiler have a clear interupt function documented in the readme file.
wynnet



Joined: 02 Dec 2003
Posts: 15

View user's profile Send private message

service the wrong interrupt
PostPosted: Wed Apr 21, 2004 6:46 pm     Reply with quote

somehow the answer from RKnapp is correct.

I comment out the disable interrupt inside the isr
and I get 100ms pulse. 1/10 of a second

I only need one single pulse (no repeat).
my crystal is 4.19Mhz
with div_by_8 and timer load with 0x0001,
the longest pulse I can get is 100msecond. Is this correct?
assuming I need longer (time) pulse, what should I do? beside xtal
RKnapp



Joined: 23 Feb 2004
Posts: 51

View user's profile Send private message

PostPosted: Wed Apr 21, 2004 11:40 pm     Reply with quote

Actually, I think that Neutone and I are saying the same thing in different words. Glad that you're making some progress.

But you say you only need one pulse... so it seems to me you'd want to use an ISR to give you "counts" and in the main thread, add up those counts until they reach some huge number that you like...

... then use this long pulse to increment another int32 main thread counter...

.. then cascade as many of these as you want until you're counting for many years... and when you've reached your target, set your pin!

Good luck,

Smile Robert
wynnet



Joined: 02 Dec 2003
Posts: 15

View user's profile Send private message

service wrong interrupt
PostPosted: Fri Apr 23, 2004 12:08 pm     Reply with quote

Thank you,
so after the timer overflow, I get an interrupt, and instead of set my pin high, I just increment a variable by one. and have an if statement to say if (variable == xinterrupts) { set pin high};

I would like be clear about this interrupt thing.
by coding:
set_timer3 (0x0001); // I load the timer with a number for it to count
// up to 0xffff generate an overflow.
you say I don't have to have enable_interrupts (timer3);
statement. to enable the interrupt and therefore I don't have to disable
the interrupt inside the isr function(); would you clarify this please

Another question: so in the isr function() do I reload the timer with a statement set_timer3 (0x0001); again
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

Re: service wrong interrupt
PostPosted: Fri Apr 23, 2004 12:25 pm     Reply with quote

wynnet wrote:
Thank you,
so after the timer overflow, I get an interrupt, and instead of set my pin high, I just increment a variable by one. and have an if statement to say if (variable == xinterrupts) { set pin high};

I would like be clear about this interrupt thing.
by coding:
set_timer3 (0x0001); // I load the timer with a number for it to count
// up to 0xffff generate an overflow.
you say I don't have to have enable_interrupts (timer3);
statement. to enable the interrupt and therefore I don't have to disable
the interrupt inside the isr function(); would you clarify this please

Another question: so in the isr function() do I reload the timer with a statement set_timer3 (0x0001); again


When the timer overflows the timer interupt flag will be set.
The timer never stops incrementing. It goes from 0xFFFF to 0
If both the timer interupt flag and timer interupt enable flag are set, the program will jump to the interupt code, run it, and jump back to main.
The compiler will cause the interupt flag to be cleared after the interupt code is run.
The time between interupts is a fixed value for a given timer setup. You can count these fixed intervals to time events.
Loading the timer with a value will change the interval time but also causes jitter in the interval time.
RKnapp



Joined: 23 Feb 2004
Posts: 51

View user's profile Send private message

PostPosted: Fri Apr 23, 2004 1:28 pm     Reply with quote

Neutone,

Causes jitter? Have you checked this? And if so, how do you avoid this?

Here's the top of my "clock" routine which is called when my 1Khz timer's interrupt fires. I wouldn't be getting 1KHz interrupts out except by virtue of preloading that timer.

Code:

/* ===========================================================================
Function Name:   ISRclock
Purpose:         Timer0 ("RTCC") ISR.

               Note: We're using a 20MHz clock, and this is divided by the
               8720 into four "zones of quadrature" resulting in 5Mhz operation.
                  There is a possible pre-scale of the clock into the timer0
               accumulator, and then the possibility of "pre-loading" the
               accumulator so that it rolls over more quickly than 8 or 16
               bits would normally roll over.  Timer0 generates an interrupt
               when its accumulator rolls over; servicing the interrupt via
               this code somehow clears the interrupt unless NOCLEAR is used.

============================================================================*/
#int_rtcc
void ISRclock ()                         // do not pass parameters to an ISR
{
   // Local data:

   // Macros:

   // Begin Procedure ==========================================================
   set_timer0  (TIMER0_PRELOAD);          // decreases time to next interrupt

   x_RTtime.t_frmticks ++;                  // increment the "fastest tick"

   if ( x_RTtime.t_frmticks >= TICKS_IN_ONE_FRAME )   // => reached end of frame
   {
      x_RTtime.l_waiting      = FALSE;    // F: time to start the next frame
      x_RTtime.t_frmticks      = 0;        // reset within-frame-tick counter


      // 100Hz output:----------------------------------------------------------
      x_RTtime.lTime2SendMsg   = TRUE;
      // -----------------------------------------------------------------------


... etc.

(and by just cascading a bunch of ifs & counting variables inside this ISR, I can count long intervals such as:)


         // Count TOTAL minutes since chip startup:  (will be summed on EEPROM):
         x_RTtime.t_seconds0to59++;
         if ( x_RTtime.t_seconds0to59 > 59 )
         {
            x_RTtime.t_seconds0to59 = 0;       // 0..59
            x_RTtime.t_minutes++;         // is not reset; time since startup
         }



}



Now in my case, though this will vary by clock speed, as far as I know, I have to have, in a header file:

Code:

#use     delay(clock=20000000)
   // Timing Parameters:
   // 1000 Hz interrupts (ticks): for ISRclock:
   #define  TICKS_IN_ONE_FRAME      10
   #define  TICKS_IN_ONE_SECOND     1000
   #define  TIMER0_PRELOAD          101
   #define  TIMER0_SETUP_BYTE       ( RTCC_INTERNAL | RTCC_DIV_32  | RTCC_8_BIT)
   // 100 Hz interrupts:
   //#define  TICKS_IN_ONE_FRAME      1
   //#define  TICKS_IN_ONE_SECOND     100
   //#define  TIMER0_PRELOAD          62
   //#define  TIMER0_SETUP_BYTE       ( RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT)



and in the main body of code, to get this baby cranked up:

Code:

enable_interrupts ( INT_RTCC );

enable_interrupts ( GLOBAL );


Note that I'm always happening to use the 8-bit timer0, not its 16-bit capability. The datasheet explains this, if not quite as clearly as Neutone's comments above. As PCM often reminds us -- quite appropriately -- please see the datasheet.

So wynnet, YES, unless Neutone has a better way, I don't see how else other than preloading the timer (with a value you calculate) you can achieve timing pips at desired intervals. But once you've got that lovely heartbeat (1Khz in my case) you just say, well shucks, 1000 of those is a second, 60 secs is a minute, 60 of those are ... and you're off to the races.

Good luck,

Smile Robert
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Fri Apr 23, 2004 2:08 pm     Reply with quote

There are some functions that require the interupts disabled for a few instruction. If the interupts are disabled while in interupt occurs and then the interupts are then re-enabled the interupt will then fire a few instructions late. You also have the condition where another interupt is being run when the timer overflows. That causes an added delay before running the interupt routine. The best method I know of to suite your use would be to read the timer and add a fixed amount but this does not work as well when the timer has a prescaler. The amount of jitter is small but it does add over time.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group