| Author |
Message |
|
|
Posted: Jul 11, 2012 - 09:41 PM |
|

Joined: Jul 11, 2012
Posts: 4
|
|
Hi everyone !!!
I'm new here and new to programming ... I have a problem with adding support for the servo
Below Timer1 settings for 12MHz
Code:
ICR1 = 3750;
// Center outputs (1.5ms)
OCR1A = 1500;
// Timer 1 fast PWM mode 14
// Clear on compare, set at TOP
// /8 prescaler
TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11);
TCCR1B = (1<<WGM13)|(1<<WGM12)|(1<<CS11);
and Timer0 settings
Code:
TCCR0A |= (1<<WGM01);
TCCR0B |= (1<<CS00);
TIMSK |= (1<<OCIE0A);
OCR0A = F_CPU/1024/100 - 1; //Tick 1ms
how to send a PWM signal to PD.1 ???
and to cause the servo leaned one way, depending on the dip switch settings, connected to the PB ???
LEDs are working properly and with the servo I have a big problem
Also sorry for my English - unfortunately not the best... |
|
|
| |
|
|
|
|
|
Posted: Jul 12, 2012 - 03:44 AM |
|

Joined: Aug 25, 2005
Posts: 911
Location: U.S.A
|
|
|
|
|
|
|
Posted: Jul 12, 2012 - 07:28 AM |
|

Joined: Aug 07, 2007
Posts: 1477
Location: Czech
|
|
You need
ICR1 period = 20 ms
OCR1A = 1 ms -> servo left
OCR1A = 1.5 ms -> servo in center
OCR1A = 2 ms -> servo right
The formula for fast pwm is
register_value = (F_CPU[MHz] * time[us] / prescaler) - 1
ICR1 = ( 12 * 20000 / 8 ) - 1 = 29999
For servo left
OCR1A = ( 12 * 1000 / 8 ) - 1 = 1499
For servo in center
OCR1A = ( 12 * 1500 / 8 ) - 1 = 2249
For servo right
OCR1A = ( 12 * 2000 / 8 ) - 1 = 2999
The output is on PB3 (cannot be changed).
Do not forget to set portb.3 as output. |
|
|
| |
|
|
|
|
|
Posted: Jul 12, 2012 - 07:44 AM |
|

Joined: Aug 07, 2007
Posts: 1477
Location: Czech
|
|
|
Quote:
and to cause the servo leaned one way, depending on the dip switch settings, connected to the PB ???
Code:
while(1)
{
//step up
if(bit_is_clear(PINB, 1) // if buton1 pressed
{
if (OCR1A < 2990)
{
OCR1A = OCR1A + 10;
_delay_ms(20);
}
}
//step down
if(bit_is_clear(PINB, 2) // if buton2 pressed
{
if (OCR1A > 1510)
{
OCR1A = OCR1A - 10;
_delay_ms(20);
}
}
}
|
|
|
| |
|
|
|
|
|
Posted: Jul 13, 2012 - 12:06 PM |
|

Joined: Jul 11, 2012
Posts: 4
|
|
Hi !
Thanks for fast response ...
It's my simple code to test servo and unfortunately does not work ... Did I forget something? Sorry - this is for you can very easy - very difficult for me ...
Code:
#include <avr/interrupt.h>
#include <avr/io.h>
#include <stdio.h>
#define F_CPU 12000000
#include <util/delay.h>
int main(void)
{
//Configure TIMER1
TCCR1A|=(1<<COM1A1)|(1<<COM1B1)|(1<<WGM11); //NON Inverted PWM
TCCR1B|=(1<<WGM13)|(1<<WGM12)|(1<<CS11);
ICR1=29999; //fPWM=50Hz (Period = 20ms Standard).
DDRB|=(1<<PB3)|(1<<PB4); //PWM Pins as Out
while(1)
{
OCR1A=1499;
_delay_ms(1000);
OCR1A=2249;
_delay_ms(1000);
OCR1A=2999;
_delay_ms(1000);
}
}
|
Last edited by daniel's on Jul 13, 2012 - 01:41 PM; edited 4 times in total
|
| |
|
|
|
|
|
Posted: Jul 13, 2012 - 12:23 PM |
|


Joined: Jul 18, 2005
Posts: 62337
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
Mode 14 looks like a good choice for servos.
Setting the OCR to be between 5% and 10% (1500 and 3000) of the 30000 counting range also looks good for setting a pulse to be between 1ms and 2ms in a 20ms frame.
You didn't say what speed the AVR is running at but let's see if I can work it out.
You are saying you want the counter to count 30,000 in 20ms so the timer itself will "tick" at a period of 20ms/30000. That is 0.6us. But then you also specify a prescaler of /64 so the CPU must have a clock period of 0.6us/64 so this would seem to imply that the AVR is running at 96MHz?
Maybe it'd be best if you just say what the AVR clock speed is then you can get some sensible numbers but I'll bet /64 prescaling does not figure in the answer if you really want to get the finest granularity possible out of 16 bits.
By the way in avr-gcc the prototype for main() is:
Code:
int main(void);
|
_________________
|
| |
|
|
|
|
|
Posted: Jul 13, 2012 - 01:37 PM |
|

Joined: Jul 11, 2012
Posts: 4
|
|
sorry - my mistake with the "int main (void)", but it does not change anything
F_CPU = 12MHz |
|
|
| |
|
|
|
|
|
Posted: Jul 13, 2012 - 03:36 PM |
|


Joined: Jul 18, 2005
Posts: 62337
Location: (using avr-gcc in) Finchingfield, Essex, England
|
|
96MHz = 12MHz * 8. The implication of this is that all you need is /8 not /64 prescaling. That would be just CS11 instead of CS11 and CS10.
But wait a minute - that's what the code above now shows? I could have sworn (as I typed in my previous reply) you had CS11 and CS10 set. Have you changed the code? If so is it now working?
Quote:
but it does not change anything
Actually it does - you are now getting one less warning that you were. But more to the point did the change to /8 make it work? |
_________________
|
| |
|
|
|
|
|
Posted: Jul 13, 2012 - 05:13 PM |
|

Joined: Jul 11, 2012
Posts: 4
|
|
fact I found some "stupid" bugs and corrected code
Still don't work ... also checked the two servos and both are doing nothing - they are "soft" - the engine does not block them ...
... all of fusebits and etc. is correct ... |
|
|
| |
|
|
|
|
|
Posted: Jul 13, 2012 - 08:51 PM |
|

Joined: Aug 07, 2007
Posts: 1477
Location: Czech
|
|
The code is right.
Even if the pulses had wrong time, the servo must react.
Put an earphone on OC1A pin against ground. You should hear a sort of 50 Hz tone.
If so, test your hardware. Use an extra supply for servo, (dry cells 4.5-6V, minus to avr gnd).
Check if the servo pins are right connected.
Plus of battery is on the middle pin on a common servo. |
|
|
| |
|
|
|
|
|