Electronic – Generating servo signal in atmega2560

atmegaatmelavrmicrocontrollerservo

I'm new to AtmelStudio. I need to know how to generate a servo control signal using timer modules of atmega2560. I'm using an Arduino Mega board. (please refer the last paragraphs of this page for more info about servo control signals).

enter image description here

I'm not sure about how to do exact timing. The clock selection part is a bit confusing for me always.

How should I configure the timer module (TCCR registers) and how to do the timing? It's better if there's a working code example.

(I've tried using timer 0 under fast PWM mode. It gives pulses accordingly but I don't how to calculate proper timing pre-scalers. I've doubts about the primary clock used. Is it the 16MHz crystal on the Arduino board or is there some other inbuilt clock source inside the atmega2560 so that we have to explicitly mention which clock to use??)

Best Answer

Since the question asks for working AVR code for servo control, this article, though written for the ATmega32 microcontroller, would be an excellent resource.

On an Arduino board, the primary clock typically used for the Timer/Counters 0..n is the crystal on the board, typically 16 MHz, though some Arduinos / clone boards use 8 MHz or 20 MHz crystals as well. Section 18 of the datasheet addresses selection of clock source / prescaler from either external or internal clocks.

You do have the option of using the ATmega2560 "calibrated internal oscillator", essentially an inbuilt RC timer, but that lacks precision / stability, as might be needed for the servo signal, depending on the application. To use the internal oscillator, set CKSEL3:0 to 0010. From Section 10.3.1 of the datasheet:

The device is shipped with internal RC oscillator at 8.0MHz and with the fuse CKDIV8 programmed, resulting in 1.0MHz system clock. The startup time is set to maximum and time-out period enabled. (CKSEL = "0010", SUT = "10", CKDIV8 = "0").


An additional suggestion:
If precision of servo control is desirable, then instead of using Timer0 which is an 8-bit Timer/Counter, one of the 16-bit timer counters (1, 3, 4, and 5) would be a preferred option.