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

Timer inconsistencies

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



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

Timer inconsistencies
PostPosted: Mon Oct 09, 2006 6:21 pm     Reply with quote

I have been working with timers awhile and in my current application I have noticed some inconsistencies when working with them.

I am working with a 20 MHz clock, so when doing timer calculations I use Fosc/4 or 5 MHz which produces a 0.2 us tick of the timer with no prescaler. I toggle an output and view this on an oscilloscope for timer0 and I see what is expected - A 13.107 ms pulse width (65536 * 0.2). Now, when I use set_timer0(), and I want the timer to interrupt very quickly (say on an 8 us interval) I use this logic: it needs to tick 40 times at 0.2 us per tick to interrupt every 8 us so I use set_timer(65536-40) to accomplish this. While theoretically this should work, when measured on my scope the output is approximately 18 us! I tried setting a lower value in the set_timer0() and apparently this 18us is the best that can be done because it never gets faster.

Anyone know why this is or any way to get a faster interrupt if there are limits on the pic?
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

Re: Timer inconsistencies
PostPosted: Mon Oct 09, 2006 6:34 pm     Reply with quote

Bryan wrote:
Anyone know why this is or any way to get a faster interrupt if there are limits on the pic?


The problem you are seeing is due to the context saving in the interrupt handler.

To solve the problem (varies by compiler release) use the fast keyword.
Code:
#int_timer3 Fast


You are responsible for storing any registers that might change. It get trickier in a system which has an 18F series PIC with the broken shadow register implementaion (most 18F series PICs in other words). To work around this problem you have to save and restore the BSR, Status and WReg yourself plus execute a normal "retfie 0" at the end of the handler. This will incease. Any registers used by the handler should be in the access bank (hint use #locate) unless access via movff instructions.

This will significantly reduce the interrupt handler latency.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Bryan



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

PostPosted: Mon Oct 09, 2006 7:09 pm     Reply with quote

I guess I'm not familiar with how you would do this in C. It sounds like you are referring to these operations in ASM. For timer0 could you post a simple sample code snippet showing how to restore the BSR, status, and WReg plus execute the "retfie 0"? Also, any more hints on how to use #locate to accomplis hthis last bit would be appreciated!
Bryan



Joined: 23 Apr 2005
Posts: 73

View user's profile Send private message Send e-mail AIM Address

PostPosted: Mon Oct 09, 2006 7:14 pm     Reply with quote

Another question: If I used the CCP1 interrupt could I declare this with the keyword fast as well to speed up latency? I was having trouble with my 20 MHz clock and the CCP wasn't capturing all of the edges in an 8us period pulse and I assumed it was because of my clockspeed. Now I am thinking I may be able to make it work if I use Fast interrupts. Anyone know if this might speed it up enough?
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Oct 10, 2006 12:41 am     Reply with quote

Code:

volatile int HI_STATUS;
volatile int HI_BSR;
volatile int HI_WREG;


#int_timer3 fast
void my_tmr3(void)
    {
    _asm
    movff STATUS, HI_STATUS
    movff BSR, HI_BSR
    movff WREG, HI_WREG
    _endasm

    // c code goes here

    _asm
    movff HI_STATUS, STATUS
    movff HI_BSR, BSR
    movff HI_WREG, WREG
    retfie 0
    _endasm
    }


Depending on your compiler version, you may be limited to a single high priority handler. If you need to have multiple high priority handlers then you can fool the compiler by using it to install the first handler (same as previous example) then setting up the other interrupts yourself. For example for timer 2 you would set the priority bits to high, enable the interrupt - do not use the enable_interrupts statement for this instead access the appropriate INTCONx bits directly.

You will have to clear the interrupt yourself because the compiler does not know it is there. Also you need to add the NOCLEAR directive to the original #int_Timer3 directive otherwise if you process a timer2 interrupt it will clear the timer3 flag as well so you could miss interrupts. Therefore your handler must clear its own interrupt sources.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
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