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

Solution for zero jitter interrupt code for 18F pics

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
dvdb



Joined: 12 Jan 2004
Posts: 6
Location: Brussels, Belgium

View user's profile Send private message

Solution for zero jitter interrupt code for 18F pics
PostPosted: Mon Dec 20, 2004 1:25 pm     Reply with quote

I am using a 18F that runs a time critical task based on timer0 that is running at the same rate as the program counter.
The intervals between actions taken some time after rollover of timer0 are critical, and interrupt driven.
To allow for some short time disables of interrupts in the main code (eg. for the internal EEPROM writing sequence) I synchonise timer0 so that it interrupts early, and then let the interrupt service code wait until timer0 reaches some predefined value.
But: here's the catch: the loop that checks timer0 obviosly generates a jitter of an amplitude that almost equals the loop time.

Eg. this simple approach (code added to measure jitter)

Code:
min=255;max=0;
SETUP_TIMER_0 (RTCC_INTERNAL|RTCC_DIV_1|RTCC_8_BIT);

for (cnt2=0;cnt2<20;cnt2++){
set_timer0(cnt2);
do{}while(get_timer0()<50);

cnt=get_timer0();
if(cnt<min){min=cnt;} //keep minimum timer value
if(cnt>max){max=cnt;} //keep max timer value

};

while(true){}; //wait for user


will give min=61, max=72.


I'd like to share a solution that allows zero jitter, provided some ASM:

Code:
for (cnt2=0;cnt2<20;cnt2++){
set_timer0(cnt2);

#ASM
movf PCL,0      //update PCLATH and PCLATU for calculated jump
wait:            //fairly straightforward waiting loop
MOVF   0xFD6,W //load timer 1
ADDLW  0xFF-40      //add offset
BNC    wait         //wait further until timer>0x40
                        //now the exact synchronising part
rlncf WREG,0               //double w first before calculated jump
addwf PCL,1                //calculated branch; 1 means store result in register
NOP
NOP
NOP

#endasm

cnt=get_timer0();
if(cnt<min){min=cnt;}
if(cnt>max){max=cnt;}
};


-> mix=max=50!, no jitter.

The idea is to jump further if timer0 is higher.

Two caveats, however:

1. the calculated jump should not cross a page boundary (unlikely but possible, so check)
BTW anybody knows how to have this checked by the compiler?

2. the ASM part should not be entered with the timer already too high, if not the calculated jump will be erratic. If not sure check before the ASM part.

Anybody has better ideas to synchronise code exactly to a timer?
_________________
Dirk Van den Berge
yerpa



Joined: 19 Feb 2004
Posts: 58
Location: Wisconsin

View user's profile Send private message Visit poster's website

Zero jitter interrupt code
PostPosted: Fri Feb 11, 2005 1:45 pm     Reply with quote

Here is some code that worked for me on an audio application using PIC 16F876. It is not original, but I don't remember where I first found it. It worked well for the audio application with sample rate of 11 KHz.

Code:
 // INTERRUPT ROUTINE FOR RTCC...

#INT_RTCC
void time0_handler(void)
{
        #asm
sync:   btfss 1, 3               //Synchronize (de-jitter) the samples.
        goto  sync
        btfss 1, 0
        nop
        #endasm
       
   PORTB=sample;                 // Write sample to DAC.
   RTCC=0x4f;
dvdb



Joined: 12 Jan 2004
Posts: 6
Location: Brussels, Belgium

View user's profile Send private message

Interesting, but how can it work
PostPosted: Fri Feb 11, 2005 3:38 pm     Reply with quote

I suppose some construction like yours should exist, but this particular one I have some difficulty with:
The first part:
Quote:
sync: btfss 1, 3 //Synchronize (de-jitter) the samples.
goto sync

is still a loop that executes 1..n times, never 1.5 times. Since the loop time is 3 cycles, at least 2 cycles worth of jitter should remain.

The second part
Quote:
btfss 1, 0
nop

can't work because it always executes in 2 cycles, regardless of the btfss skipping or not (it doesn't make a difference wether the NOP is executed or not)
So, on first sight, it doesn't appear to be able to produce zero jitter, but on occasion I'll test it, just out of curiosity.
_________________
Dirk Van den Berge
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library 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