0

I'm making a program for a small robot arm controlled by four servos. Problem: I need for PWM outputs, timer1 has three so i need to use timer3 for the last one

The main program and the timer1 outputs work great, the robot arm is functional. My problem is in the initialization of the PWM's. The PWM for timer1 is set to phase-correct, 64 pre-scaling and using WGM1[0-3] to 1010 so that i can use ICR1 as the top value, leaving OCR1[0-2] for counting up so output is on OCR[0-2].

According to the ATMEGA 2560 data book I should be able to initialize an identical PWM with timer3 with just one output in just the same way, but it just won't give me any output at all on OC3A.

Any help is greatly appreciated! :)

PS this is for a class project, so no servo libraries, and no major changes to the program (the current code is already approved by my professor, also the due date is in 24 hours so i don't have the time. Yes I know that sounds like trouble, but the project is technically done, I'd just really really like to get a full range of motion on my little Plexiglas robot)

PWM.c:

// INITIALIZE PHASE CORRECT PWM ------------------------------------------------------------------------------
void initPWM()
{
    DDRB |= (1<<DDB7);      // Output pin 5 OC3A
    DDRB |= (1<<DDB5);      // Output pin 11 OC1A
    DDRB |= (1<<DDB6);      // Output pin 12 OC1B
    DDRB |= (1<<DDB7);      // Output pin 13 OC1C


    // Initialize TIMER1 for OC1A, OC1B, OC1C:
    TCCR1A |= (1<<COM1A1)|(1<<COM1B1)|(1<<COM1C1)|(1<<WGM11);     // Clear OCnA on compare match (non inverting mode), Phase correct ICRn top Mode      
    TCCR1B |= (1<<WGM13)|(1<<CS11)|(1<<CS10);                     // Phase correct ICRn top Mode, Pre-scaling 64 for 50Hz signal
    // Initialize TIMER3 for OC3A
    TCCR3A |= (1<<COM3A1)|(1<<WGM31);                            // Clear OCnA on compare match (non inverting mode), Phase correct ICRn top Mode
    TCCR3B |= (1<<WGM33)|(1<<CS31)|(1<<CS30);                     // Phase correct ICRn top Mode, Pre-scaling 64 for 50Hz signal


    // TIMER1 Top and bottom value:
    ICR1 = 5000;
    TCNT1 = 0;
    // TIMER3 Top and bottom value:
    ICR3 = 5000;
    TCNT3 = 0;


    // Start PWM in OCR = 200 (mid value for servo)
    OCR3A = 200;
    OCR1A = 200;
    OCR1B = 200;
    OCR1C = 200;


}
1

I can see nothing wrong in your program except this:

DDRB |= (1<<DDB7);      // Output pin 5 OC3A

This is setting pin PB7 as an output, whereas digital pin 5 (OC3A) is PE3.

| improve this answer | |
  • I found that out a few hours after posting, despite having raked through my code for two days and now i feel like a bit of an idiot... Thank you very much for the help – Star_bb Dec 7 '19 at 16:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.