-1

I'm not gonna waste your time, and just post the code along with the explanation

#define F_CPU 8000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>

int main(void){
    sei(); //Enable interrupts 
    DDRB = (1 << PORTB3);//Set pin P3 as an output and other pins as inputs
    //PORTB = 0xff;
    DDRA = (1 << PORTA7);//Set pin A7 as an output and other pins as inputs
    //PORTA = (1 << PORTA7);
    TCCR0 = (1 << WGM00) | (1 << WGM01) | (1 << COM01);//Enable PWM, and configure Timer
    TIMSK = (1 <<  TOIE0);//Enabling an interrupt
    OCR0 = 255;//Setting comparison value for the Output compare unit
    TCCR0 |= (0b110 << CS00);//Selecting the clock as the falling edge on a certain pin

    while(1){
    /*
     * The portion of the code creates a square wave with a period of 39 us, which means that the falling edge occurs at a period of 78us, and since the output period of 
     * the PWM is 50Hz for a servo, that fits perfectly (1/(79*10^-6 * 256) ~ 50), but for some reason, the servo doesn't move...*/
       PORTA ^= (1<< PORT7);
       _delay_us(39);
    }
}

So, what's the problem?? I don't really have an oscilloscope to measure the frequency, so don't ask me to do that, but a peculiar thing that I did notice was that the voltage across the servo power wires was 2.7V when it should've been 5V, but the power supply itself was supplying 5V, and this only happened when I connected the signal pin to the PWM pin, and it happened regardless of whether the 5V rail was connected to the servo or not... Any ideas on what the problem is??

Shahe Ansar
  • 314
  • 2
  • 12

1 Answers1

0

Your PWM output has a 50% duty cycle, so the effective port output voltage is reduced from 5v to 2.5v when measured with a voltmeter. Assuming you are measuring the voltage against Ground, it won't make any difference if 5v power line is connected to the servo, but it will make a difference if the PWM signal is not connected.

If the servo is bidirectional, then it is possible that the 50% duty cycle keeps it stationary - try a different duty cycle, it looks as if you have hard coded the PWM period, inverting the output every half-cycle. Try something like

PORTA ^= (1<< PORT7);
_delay_us(28);
PORTA ^= (1<< PORT7);
_delay_us(50);
Weather Vane
  • 33,872
  • 7
  • 36
  • 56
  • You've got it wrong, the signal on PORTA goes to T0, which is the clock source for the timer – Shahe Ansar Jun 19 '16 at 13:19
  • Also, It's a 100% dutycycle, since OCR0 is an 8 bit register, but had the voltage been between the PWM pin (PB3) and GND, it'd have made sense, but in this case it's between the + and - power pins of the servo, which is NOT a good sign... and yes the grounds are all tied together – Shahe Ansar Jun 19 '16 at 13:20
  • Well that's a strange way of doing it. Using a software loop to drive a timer. – Weather Vane Jun 19 '16 at 13:23
  • If you want a 50% duty cycle then OCR0 would be set to `128`. – Weather Vane Jun 19 '16 at 13:35
  • As I said, try a different duty cycle, if 50% means stationary. – Weather Vane Jun 19 '16 at 13:44