Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PWM on normal output pins?

Status
Not open for further replies.

MrMikey83

New Member
I need two pins to control the PWM signal to two different motors. Each one needs to be separately variable so I can make one motor go faster than the other.
I read through the datasheet and it looks like the ATmega32's PWm only outputs to 1 pin. Is there a way to make Two output pins do PWM in software?
If all else fails, I guess I could take two other ATmega chips and use them as PWM genorators.
~Mike
 
You can generate a bunch of PWM signals in software using a single timer.

Code:
BYTE Pulse_Width1 = 100;
BYTE Pulse_Width2 = 47;
Start_Timer();
while(1)
{
   if (Timer_Overflow() == TRUE)
    {
       PWM_Out_Pin_1 = 0;
       PWM_Out_Pin_2 = 0;
    }
    else
    {
       time = Read_Timer();
       if (Pulse_Width1 < time)
       {
          PWM_Out_Pin_1 = 1;
        }
       if (Pulse_Width2 < time)
       {
          PWM_Out_Pin_2 = 1;
        }
    }
}

By putting the while(1) code in an interrupt you can allow other code to run. More frequent interrupts = better PWM precision but more processor time. You can add as many PWM outputs as you want as long as you have enough processor time.
 
I tried your code and with an LED connected, it just stays on constantly. I connected my multimeter and measured 0Hz. I didn't use an interrupt, I just put it in at the end of my while loop so it should be going through it every time.
~Mike
 
The problem is probably with your Timer_Overflow function. This function should read the timer's overflow interrupt flag to see if it has been set (meaning the timer has overflowed). If the flag has been set the function clears the flag and returns true, otherwise it returns false. This section of code turns off the LEDs at the end of the timer period. If it isn't working the LEDs never turn off. Also check how TRUE is #defined. TRUE usually equals 0x01 which would cause a problem if your Timer_Overflow function uses the C convention of TRUE being any non-zero value. You don't need the == TRUE part I just put it in to be a bit more explicit.

Try replacing the PWM_Out_Pin_1 = 1; line with PWM_Out_Pin_1 ^= 1; This will rapidly toggle the pin so you can ensure that that section of the code is getting run. If there is a problem with the first "if" it's possible the compiler will "optimize" out all your code. If you have a scope you can look at the waveform and see the intended duty cycle: the pin will toggle when the PWM should be High and not toggle when the PWM should be low.
 
Well, I never got that to work, but I managed to figure out how to use the regular PWM timer outputs. Since I'm using Timer1 for a remote control input, I can use Timer0 and Timer2 for my motor controls.
Thanks for the help anyway bmcculla
~Mike
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top