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 CCS Technical Support

Sleep on Interrupts

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



Joined: 23 Jun 2009
Posts: 2

View user's profile Send private message

Sleep on Interrupts
PostPosted: Tue Jun 23, 2009 9:49 pm     Reply with quote

Hi,
I am working on an application that requires calling a timing interrupt repetitively and at a rate of around 32Khz. I am running my PIC at 40Mhz (With my clock setup this gives me 10 Mhz for my timer). According to my calculations I should have plenty of free time, but I seem to be hitting a threshold much earlier then expected. I noticed in the C/ASM List that sleep is called when an interrupt is called:
Code:

.................... //===================================
.................... //       Interrupt Service Routines
.................... //===================================
.................... #int_ext //External interrupt from index channel (hall effect or opto-sensor)
.................... void  indexInterrupt()
0B44:  SLEEP
.................... {
....................    int16 period;
....................    int   tempLBPeriod;     //Holds value before assigning it.
....................    period = get_timer1();   //Get period from timer 1

Why is sleep called when the microcontroller first handles the interrupt? Could this be a reason for my time loss?

Thanks,
Zach
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Wed Jun 24, 2009 1:49 am     Reply with quote

No asm code is shown in a CCS listing before the opening bracket. This looks like a kind of corrupted listing. Apart from this, the processor would never recover from a sleep inside an ISR, excecpt by a watchog reset.
Ttelmah
Guest







PostPosted: Wed Jun 24, 2009 2:35 am     Reply with quote

It is possible to get a listing like this, but the 'sleep' is not in the ISR. The ISR code comes latter, at a different address. Need to see more of the listing to make sure. The sleep is not the problem.

32KHz, is pushing the ISR rate. There is a _massive_ overhead to calling an ISR. Typically about 60+ instructions to call, and return from an ISR. This is the code to save the registers in use in the 'main' code, poll which ISR has actually occurred, call the ISR routine, return from the ISR, clear the interrupt flag, restore the registers, and then return. Even at 40Mhz, this overhead will 'cost' about 6uSec. With only 30uSec available, this becomes very significant. Generally, to go this fast, _will_ require you to start thinking very carefully. First, the _fastest_ way, will not be to use a ISR at all. Use the interrupt, but not an ISR. Disable interrupts, and poll the interrupt flag. This can bring response times down to only typically three instruction times 'worst case'. Much faster than using the hardware interrupt, which has a 'best case' response in the same order, even with no register handling at all. To use the hardware interrupt (only worth doing, if you _must_ perform other tasks at the same time), to get this sort of speed, you will _need_ to 'go custom', and look through the generated assembler for the interupt, and work out for yourself, exactly which registers are actually used in your code. Then use the 'global' interrupt handler (which is normally generated invisibly for you, and contains the main overhead), and save just the registers you need, call your handler, clear the interrupt flag yourself, restore the registers, and return. Hardware interrupts are _not_ the fastest way to make the processor work. The 'point' is allowing you to have events handled while other code is going on, not 'speed'.
I have posted in the past example code for doing generating a custom global interrupt, handling a few events, faster than the default, and a search should find this.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Jun 24, 2009 3:02 pm     Reply with quote

Here is a way to duplicate the original poster's results.
Put the #int_ext routine below the main() code, and put a function
prototype for it above main(). Then the SLEEP instruction that CCS puts
at the end of main() will appear to be part of the #int_ext routine, but it's
not really. It's just a quirk of the .LST file formatting.
Code:

.................... void main() 
.................... { 
*
00A8:  CLRF   FF8
00AA:  BCF    FD0.7
00AC:  BSF    08.7
00AE:  CLRF   FEA
00B0:  CLRF   FE9
00B2:  BSF    FC1.0
00B4:  BSF    FC1.1
00B6:  BSF    FC1.2
00B8:  BCF    FC1.3
.................... 
.................... while(1); 
00BA:  BRA    00BA
.................... } 
.................... //----------------
.................... 
.................... #int_ext
.................... void ext_isr(void)
00BC:  SLEEP
.................... {
.................... char c;
.................... c = 0x55;
*
009E:  MOVLW  55
00A0:  MOVWF  18
.................... }


Code:

#include <18F452.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4000000)

#int_ext
void ext_isr(void);

//===============================
void main()
{

while(1);
}
//----------------------------

#int_ext
void ext_isr(void)
{
char c;
c = 0x55;
}
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