|
|
View previous topic :: View next topic |
Author |
Message |
stumax
Joined: 16 May 2008 Posts: 2
|
Help! - crazy problem driving 2 servos with a PIC |
Posted: Fri May 16, 2008 6:04 pm |
|
|
I'm trying to drive 2 servos to actuate some stuff. The PIC is a 16F877 running at 20MHz. There's a bunch of stuff going on whilst the servos are being driven so I'm doing the driving using 2 timers and interrupts. The method is:
1. Timer1 is setup to roll over every 26ms to give me the frame rate.
2. When it rolls over, its ISR resets Timer1 to 0 for next frame, then loads Timer0 with the value to allow it to roll over and interrupt for the correct pulse for servo1, enables that interrupt and sends the line for servo1 high.
3.When Timer0 interrupts it checks to see which channel we're working with:
For channel1 it sends the line for servo1 low, servo2 high then loads Timer0 with the value to allow it to roll over and interrupt for the correct pulse width for servo2. It also sets active channel to the next channel.
For channel2 it sends the line for servo2 low, resets the channel back to channel1 and disables the interrupt for Timer0.
Here's the code for the ISR's:
Code: | #int_TIMER0
void TIMER0_isr(void)
{
if (channel < 1)
{
output_low(SERVO_1);
output_high(SERVO_2);
set_timer0(128); //just a test value gives a 1.6ms pulse width
channel = 1;
}
else
{
output_low(SERVO_2);
channel = 0;
disable_interrupts(int_timer0);
}
//output_low(SERVO_1); //for testing servo1 by itself - works fine without the other stuff in this ISR
}
#int_TIMER1
void TIMER1_isr(void)
{
set_timer1(0);
set_timer0(128);
output_high(SERVO_1);
enable_interrupts(int_timer0);
}
|
Here's the setups for the timers:
Code: | setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64); //12.8us resolution, 3.2ms o'flow - for servo pulse width
setup_timer_1(T1_INTERNAL|T1_DIV_BY_2); //0.4us resolution, 26.2ms o'flow - for frame rate |
Sounds OK so far. However, when it runs, the pulse for servo1 is always about 17us, regardless of what value I load into Timer0. The pulsed width for servo2 is perfect, as is the frame rate. You'll notice in Timer0's ISR there is a line commented out. This is a test line to see if it will work fine with only 1 servo being driven, I comment out the rest of the ISR. It works fine like this, so I know that in Timer1's ISR the correct value is being loaded into Timer0.
Any ideas? I've tried a bunch of things like changing the order in which things happen in each ISR, changing the pins being driven, changing timer setup values. BTW, Timer2 is being used to generate pulses for a stepper so it can't be used. I'm considering setting up Timer1 to roll over twice as often, once for each servo. This would affect the synchronising of the servos but it won't be a problem for this machine, however I would like to know what's wrong with this code. Thanks! _________________ Stu Maxwell |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Fri May 16, 2008 6:35 pm |
|
|
I see what you're trying to do, but you missed something. It's not enough to enable/disable an interrupt whenever you wish. You also have to ensure that the interrupt isn't already set when you re-enable it. Just because an interrupt is disabled doesn't mean that the hardware that is responsible for generating it isn't chugging along in the background. This is a long-winded way of saying that timer 0 is still running and still generating interrupts even when you have its interrupt disabled. Disabling an interrupt doesn't mean that the interrupt isn't stopped from being created - it just forces the PIC into ignoring it when it does get set.
You have to alter your re-enable of timer 0 to also clear its interrupt flag in addition to resetting it to 0. The proper order would be 1. set to 0, 2. clear timer 0 interrupt flag, 3. re-enable timer 0's interrupt. |
|
|
stumax
Joined: 16 May 2008 Posts: 2
|
|
Posted: Fri May 16, 2008 6:45 pm |
|
|
Thanks for the reply. Actually I did this just after posting (ie cleared the interrupt for Timer0 before enabling it) and now it works fine. _________________ Stu Maxwell |
|
|
|
|
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
|