Professional Documents
Culture Documents
Controlling Servo Motors With AVR Microcontrollers
Controlling Servo Motors With AVR Microcontrollers
Here we will use AVR Timer1 Module which is a 16bit timer and has two PWM channels(A and B). The
CPU frequency is 16MHz, this frequency is the maximum frequency that most AVRs are capable of
running. And so it is used in most development board like Low Cost AVR Development Board
and xBoards. We chose the prescaler as 8. So the timer will get 16MHz/8 = 2000khz. We setup Timer
Mode as Mode 8. Timer Mode 8 features are:
So the timer will count from 0 to ICR1(TOP Value). The formula for PWM frequency and calculation for
TOP value is given below
𝑓𝑐𝑝𝑢
𝑓𝑝𝑤𝑚 =
2 ∗ 𝑁 ∗ (1 + 𝑇𝑂𝑃)
16000000𝐻𝑧
𝑓𝑝𝑤𝑚 =
2 ∗ 8 ∗ (1 + 𝑇𝑂𝑃)
16000000𝐻𝑧
50 𝐻𝑧 =
16 ∗ (1 + 𝑇𝑂𝑃)
The above settings clears the OC1A (or OC1B) pin on Compare Match and SET ( to high) at BOTTOM.
The OC1A and OC1B pins are the PWM out pin in ATmega16/ATmega32 chips. This settings gives us
NON inverted PWM output.
Now the duty cycle can be set by setting OCR1A and OCR1B registers. These two register controls the
PWM high period. Since the period of timer is 1uS (16MHz/(8*2)) we can calculate values required for
following servo angles if we using HS-311 standard servo (180 degree).
Servo Angle 0 degrees require pulse width of 600 uS so value of OCR1A = 600 us/1us = 600
Servo Angle 90 degrees require pulse width of 1500 uS so value of OCR1A = 1500us/1us = 1500
Servo Angle 180 degrees require pulse width of 2.140ms(2140uS) so value of OCR1A =
2400us/1us = 2400
Program example:
#include <mega16.h>
#include <delay.h>
void main(void)
{
……………..
……………..
…………….
while (1)
{
// Place your code here
OCR1A=600; // posisi servo 0°
delay_ms(3000);
OCR1A=2400; // posisi servo 90°
delay_ms(3000);
OCR1A=1500; // posisi servo 180°
delay_ms(3000);
}
}
USING FAST PWM AND TOP=ICR1 ( TIMER MODE 14)
The timer will count from 0 to ICR1(TOP Value). The formula for PWM frequency and calculation for
TOP value is given below
𝑓𝑐𝑝𝑢
𝑓𝑝𝑤𝑚 =
𝑁 ∗ (1 + 𝑇𝑂𝑃)
16000000𝐻𝑧
𝑓𝑝𝑤𝑚 =
8 ∗ (1 + 𝑇𝑂𝑃)
16000000𝐻𝑧
50 𝐻𝑧 =
8 ∗ (1 + 𝑇𝑂𝑃)
#include <mega16.h>
#include <delay.h>
void main(void)
{
……………..
……………..
…………….
while (1)
{
// Place your code here
OCR1A=1200; // posisi servo 0°
delay_ms(3000);
OCR1A=3000; // posisi servo 90°
delay_ms(3000);
OCR1A=4800; // posisi servo 180°
delay_ms(3000);
}
}
Source:
http://extremeelectronics.co.in/avr-tutorials/servo-motor-control-by-using-avr-atmega32-
microcontroller/