Hi there.
I am trying to generate PWM to control a Servo from an ATMega128.
I have read, and re-read the Atmel Datasheet, however I am still a little confused on exactly how I go about adjusting the duty cycle of the wave?
As the servo (so I have read) runs on 50Hz PWM, and my Oscillator is 8Mhz, I am using a prescaler of 8, then counting to 20,000.
Fpwm = fclk/(prescaler*(1+TOP))
Fpwm = 8Mhz/(8*(20000))
Fpwm = 50hz
I am using the standard 16-bit counter1 in Fast PWM mode, which is setup to Toggle OC1A on Compare Match. I have done this with the following code:
void initTimer1(){
DDRB |= (1<<PORTB1); /* Setup OC1A as output */
TCCR1A = 0x53; /* (1<<COM1A0) | (1<<WGM11) | (1<<WGM10); -- Toggle OC1A on Compare Match */
OCR1A = 19999; /* OCR1A is TOP, count to 19,999 + 1 */
TCCR1B |= (1 << CS10) | (1<<CS11) | (1 << WGM13) | (1<<WGM12); /* Setup Timer1 (16-bit) with prescaler of 8 running from 8Mhz CLK */
}
However, this is where I get confused. My device (should) count to OCR1A, then toggle the output of OC1A. If I wanted a Duty cycle of 50%, I would want it to toggle after counting to 10000, however how do I set that?
Is there some other register I can program that offers another comparison and (hence) another toggle? Or do I have to manually check the count value in the TCNT1 register and perform the task manually?
Any help would be much appreciated, if you feel I am going about this the wrong way, please let me know, as this is my first expereicnce with the AVR series.
I am trying to generate PWM to control a Servo from an ATMega128.
I have read, and re-read the Atmel Datasheet, however I am still a little confused on exactly how I go about adjusting the duty cycle of the wave?
As the servo (so I have read) runs on 50Hz PWM, and my Oscillator is 8Mhz, I am using a prescaler of 8, then counting to 20,000.
Fpwm = fclk/(prescaler*(1+TOP))
Fpwm = 8Mhz/(8*(20000))
Fpwm = 50hz
I am using the standard 16-bit counter1 in Fast PWM mode, which is setup to Toggle OC1A on Compare Match. I have done this with the following code:
void initTimer1(){
DDRB |= (1<<PORTB1); /* Setup OC1A as output */
TCCR1A = 0x53; /* (1<<COM1A0) | (1<<WGM11) | (1<<WGM10); -- Toggle OC1A on Compare Match */
OCR1A = 19999; /* OCR1A is TOP, count to 19,999 + 1 */
TCCR1B |= (1 << CS10) | (1<<CS11) | (1 << WGM13) | (1<<WGM12); /* Setup Timer1 (16-bit) with prescaler of 8 running from 8Mhz CLK */
}
However, this is where I get confused. My device (should) count to OCR1A, then toggle the output of OC1A. If I wanted a Duty cycle of 50%, I would want it to toggle after counting to 10000, however how do I set that?
Is there some other register I can program that offers another comparison and (hence) another toggle? Or do I have to manually check the count value in the TCNT1 register and perform the task manually?
Any help would be much appreciated, if you feel I am going about this the wrong way, please let me know, as this is my first expereicnce with the AVR series.