[En-Nut-Discussion] RE: Control function to drive a RC servo

ptlinux ptlinux at optushome.com.au
Sun Jun 15 04:43:57 CEST 2003


Date: Wed, 11 Jun 2003 01:22:27 +0200
From: Alessandro Zummo <azummo-enutdisc at towertech.it>
To: en-nut-discussion at egnite.de
Subject: Re: [En-Nut-Discussion] RE: Control function to drive a RC
servo
Organization: Tower Technologies
Reply-To: en-nut-discussion at egnite.de

On Wed, 11 Jun 2003 00:39:41 +1000
"ptlinux" <ptlinux at optushome.com.au> wrote:

> 1. Timer0 is 8-bit with PWM but according to Harald it is been use by 
> the OS. Timer1/Timer3 are 16-bit timer... So it will give me higher 
> resolution or accuracy I should say?!

Exactly.

> 2. I don't really understand what how to use the attributes TOP, OCR3A

> and ICR3 mean.. I know they are registers but I don't see how it can 
> be used in the context of creating PWM... It seems like I need to be 
> comparing against an input value... And TOP is the point which I 
> trigger an interrupt?! Sorry.. It is very vague to me... Can you 
> please explain more. I couldn't find an example in the datasheet which

> refers to theses values to create a PWM.
> 
> The period of my PWM is 20ms, my required wave form is as follows.. 
> How does TOP, OCR3A and ICR3 comes into play?!
>  *  between 1ms-2ms
>       |--|        |--|
> ------|  |--------|  |.........
> | 20 ms  |


The timer counts from BOTTOM (0) to TOP (the value you put in ICR3)
and rolls over.

To calculate the value for ICR3 you need to use the formula in the
datasheet, which
takes into account the system frequency and the prescaler setting.
See the description on page 121-123 of the datasheet.

This gives you the frequency, 
now you need to set the PWM duty cycle. For a 50% duty cycle, you can
set

  OCR3A = ICR3 / 2.

Adjust accordingly to your needs.
 
> 3. I don't think I will using an OVERFLOW (ISR).. Because the
dutycycle
> (1ms-2ms) will be controlled by user... I am planning to allow user to
> input + or - to ethernut... And + and - will increment/decrement the
> dutycycle accordingly. Therefore think I need to write a custom ISR
say
> and register it as say INT0 (interrupt vector) and in the ISR modify
the
> dutycycle. 

The you can keep ICR constant and only adjust OCR3A in your main cycle,
you don't even have to use interrupts. If you want to be very clean,
you can change OCR3A on the OVERFLOW interrupt.


-- 

 Best regards,

 Alessandro Zummo,
  Tower Technologies - Turin, Italy

  http://www.towertech.it


I have been doing a bit of research on google's Newsgroups... I found
out that I don't really need to use PWM to drive the RC servo.. It is
adequate to use a timer and set the timer to 20ms... Which is the
frequency of the servo period. And I call a function everytime the timer
reaches 20ms... Set the PORT output pins high for 1 ~ 2ms...

I have something like this in my code,


void Servo(HANDLE timer, void *arg)
{
	mask = 1;
	/* set output pin high */
	outp(inp(PORTD) | mask, PORTD);
	
	delay.. Between 1 ~ 2 ms.. ????  <---- how is it going to be
done?can I use NutDelay()?
	
	/* set output pin low */
	outp(inp(PORTD) & ~mask, PORTD);
}


int Main(void) 
{
	u_long timer_ms = 20;
    
	HANDLE timer1;
	HANDLE event1 = 0;
	
	/* initialise servo io pins */
	outp(0xff,DDRD);         /* use all pins on PortD for output */
	outp(0xff,PORTD);   	 /* clear pins */ 
    
	timer1 = NutTimerStart(timer_ms, Servo, &event1, 0); 
	
}

How do I go about making the thread to wait for 1-2ms? Do I just
introduce a for(;;) loop for x iteration?! Can I use NutDelay() Any
other better way?!

Regards,

PT 





More information about the En-Nut-Discussion mailing list