|
|
View previous topic :: View next topic |
Author |
Message |
Jim Guest
|
OSC off by a factor of 10 |
Posted: Thu May 04, 2006 6:28 am |
|
|
I am setting up RTCC and it seems to trigger 10x slower then it should.
I am trying to setup a 50hz pulse for a servo and I am doing something wrong...
100,000hz=8mhz/(4*20) //no prescaler and the preload the clock at 235
so 50hz "should" be every 2000 interrupts
but it only work at 200 interrupts and I don't know why.
#include<18f4331.h>
#fuses INTRC,NOWDT,NOPROTECT,NOLVP, NOBROWNOUT
#use delay(clock=8000000) //8Mhz
#use rs232(baud=9600,xmit=PIN_A5,rcv=PIN_B1,parity=n,bits=8,INVERT)
setup_oscillator(OSC_8MHZ);
/////////////////////////// globals ////////////////////////////////////////
#define SERVO_PERIOD 200;
int16 freq; //
int16 width; //
int16 servo1;
int16 count =0;
///////////////////////////// inturrupts /////////////////////////////////////
//// timer interupt ////
#int_RTCC
void servo_pulse(void)
{
if(--freq == 0)
{
freq = SERVO_PERIOD;
servo1 = width;
count++;
if(count %50==0)
{
printf("\n\n\r%ld",width);
///////////// should be ~100 to 250
if(++width>45) {width=5; }
}
}//if freq =0
if(servo1)
{
output_high(PIN_E2);
servo1--;
}//if width
else
{
output_low(PIN_E2);
}//else ! width
set_rtcc(235); // only 20 clicks till reset
}//servo_pulse
/////////////////////////////// MAIN () /////////////////////////////////////
main()
{
freq = SERVO_PERIOD;
///////////// should be ~100 to 250
width=50; //1.25ms or 0 deg
setup_counters(RTCC_INTERNAL,RTCC_8_BIT|RTCC_DIV_1);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
set_rtcc(0); // trigger frist event
while(true)
{
printf("\n\n\rStarting sweep");
}//while true
// NOOP should never reach here...
}//main() |
|
|
Ttelmah Guest
|
|
Posted: Thu May 04, 2006 6:50 am |
|
|
Your problem is the time taken to handle an interrupt.
You are 'attempting' to trigger an interrupt every twenty instructions...
The interrupt global handler alone, will involve perhaps 80 instructions, then add the code in your handler sub, and you are an order of magnitude from being able to handle this sort of frequency. You need to be interrupting far less often. Frequencies of perhaps 1/500th of the clock rate, should be considered the maximum for an interrupt handler, and even at this rate, care is needed.
Given you have a chip with the other hardware timers, use Timer2, with an /16 prescaler, automatically counting to 249 (gives 250 counts), and an /10 postscaler, to actually give you a 50Hz interrupt.
Best Wishes |
|
|
sjbaxter
Joined: 26 Jan 2006 Posts: 141 Location: Cheshire, UK
|
|
Posted: Thu May 04, 2006 7:02 am |
|
|
Another few additions that will be possibly causing problems or incorrect results:
You need to be very careful where you use printf statements. I understand that you may have added them in order to do some debugging, but inside interrupts is a major cause of problems and most likely adding to them.
Also, put the
Code: | printf("\n\n\rStarting sweep");
|
before the while(TRUE), i.e.
Code: | printf("\n\n\rStarting sweep");
while(true)
{
// in the main loop here
}//while true
|
you dont want your application bogged down by continuously printing this message ! _________________ Regards,
Simon. |
|
|
Jim Guest
|
the frequancy |
Posted: Thu May 04, 2006 7:32 am |
|
|
Thanks.. I'll just have to give up the 2 pins and use a crystal and go from 8mhz to 40mhz... The reason I want the the speed is to fine tune the pulse with which has to be far smaller then the 50mhz.. Thanks guys. |
|
|
Guest
|
Re: the frequancy |
Posted: Thu May 04, 2006 7:51 am |
|
|
Jim wrote: | the pulse with which has to be far smaller then the 50mhz.. Thanks guys. |
sorry
the pulse width, that has to be far smaller then 50hz.. :-D |
|
|
Ttelmah Guest
|
|
Posted: Thu May 04, 2006 7:58 am |
|
|
Make the interrupt 50Hz, and use the CTC to hardware generate the pulse. Using high speed interrupts, is wasting a hell of a lot of processor time, and is a 'sledgehammer/nut interface solution'. Basically you can program the CTC, to reset it's output pin after a count. Just set the pin in the timer interrupt, and set the CTC, and it'll automatically clear after the programmed interval. This way the processor has time left to be doing other things.
Best Wishes |
|
|
Jim Guest
|
Thanks |
Posted: Thu May 04, 2006 8:15 am |
|
|
Could you give me a quick code snipet? |
|
|
jim Guest
|
thanks got it |
Posted: Thu May 04, 2006 4:56 pm |
|
|
Thanks.. I used RTCC for 50hz reset and CCP1 for the pulse.
Your help was appreciated. |
|
|
|
|
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
|