1

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;
}
asked Dec 7, 2019 at 0:26

1 Answer 1

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.

answered Dec 7, 2019 at 8:57
1
  • 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 Commented Dec 7, 2019 at 16:32

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.