On Thursday, September 08, 2011 9:43 PM, "Josh Koffman" wrote: > On Thursday, September 8, 2011, Bob Blick wrote: > > I usually use a CCP peripheral in Compare mode to generate the pulse. > > Use a general purpose timer to let you know when to repeat. > > > > If you need to drive more than one servo you should hit them all > > round-robin style, and you can use the same CCP output pin to do it as > > an enable for diode/CMOS/TTL logic to "AND" it with a set of general > > purpose output pins. Or you can use a 3-to-8 demultiplexer, etc. > > > > But basically use the CCP compare output pin. Sorry I have only done it > > in a 16F in C. >=20 > Hi Bob, >=20 > Let me make sure I understand the method you're talking about. You're > suggesting using a regular timer set to interrup roughly every 20mS. > At that point I'd set the output pin to positive. I'd also then read > my current desired servo position and use it to trigger the CCP module > in compare mode which when triggered would drop the pin back low. Does > that sound right? Yes, exactly. =20 > If I'm doing this on a PIC running at 8MHz (internal osc) is there a > clever way to use the same timer peripheral for both the 20mS trigger > _and_ the CCP source that triggers the end of the pulse? Sure, just use TMR1 in freerunning mode, and enable interrupts for it. You won't neccessarily be setting your servo pin each time, maybe every other time or every fourth time, it depends what repetition rate you use and how many servos you are driving.=20 > What do you have the CCP interrupt do? I could conceivably have it > automatically set the output pin low, but that limits which pins I can > use this routine on. Any reason why I can't use it in interrupt only > mode and trigger the pin state change in the ISR? You don't use the CCP interrupt, don't enable it. Use the peripheral in Compare mode and have it set the pin low after the pulse width you set(must be calculated based on TMR1, you can stop TMR1 while you do the the addition). =20 > I'm not sure I entirely follow your multiple outputs ideas. I think > that what you're saying is that I should have the CCP trigger on the > differences, the use some other port outputs to trigger which servo > gets the signal. Are you suggesting that I use the same timer to start > the pulse for all servos or to alternate between servos. At 20mS > between each pulse per servo, I could easily squeeze in 8 separate > servos. Let's say you want to drive 8 servos and you can use all of PORTB to do it, and that CCP1 output is on RC2. And let's also use a two-input AND gate for each servo. One input for each AND gate goes to RC2, and the other inputs each get one of PORTB's pins. Start with all PORTB low. Timer interrupt happens, you clear PORTB. Pause TMR1. Add your servo pulse value for servo #0 and TMR1 value together and put in CCPR1. Do what it takes to set RC2 high and enable CCP1 to clear it without glitching. Set RB0 to enable servo #0 and unpause TMR1. Return from interrupt. The next time the interrupt happens, do the same thing for servo #1 and RB1. Cycle through until all servos have been serviced. So you get exact cycle times regardless of servo positions, the servos are updated round-robin so your power supply is happiest, you get the precision of .5 uS for your servo pulses. I have done it in the past with only three PORTB pins and the CCP output. Instead of eight AND gates you use a 3 line to 8 line decoder like the 74HC138. Unfortunately the output is inverted so you need a stack of inverters. Instead of using AND gates you can use a resistor and diode per pin, but it's uncool unless you are desperate, and it loads the CCP output really hard. Cheerful regards, Bob --=20 http://www.fastmail.fm - Access all of your messages and folders wherever you are --=20 http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist .