I'm making a motor driver that has too many PWM outputs to use hardware PWM, so my intent was to generate waveforms with a "tickless" timer scheme, as follows:

scheduled restack:
   for i in (pwm channels)
      stack in ascending order all pwm channels
   set OCR0A = lowest PWM channel

   toggle GPIO of lowest PWM channel
   pop next PWM channel off stack
   set OCR0A = next lowest PWM channel
   if list is empty
       schedule a restack

This is, at most, 10 or so instructions in the ISR. At 16khz TCNT, this is worst case 16khz interrupts (255 PWM channels each spaced by one count), and usual case, probably around 500Hz, which I think this microcrontroller should have no issues handling. However, from the datasheet:

The output compare unit can be used to generate interrupts at some given time. Using the output compare to generate waveforms in normal mode is not recommended, since this will occupy too much of the CPU time.

Is the proposed solution bad practice? From a purely CPU usage perspective, it seems totally within limits, despite what the datasheet says.

  • 1
    \$\begingroup\$ Note here is a question about PWM expansion, might be helpful. \$\endgroup\$
    – rdtsc
    Jan 26, 2021 at 14:24
  • 1
    \$\begingroup\$ Thanks - that's definitely good to know for the future. Unfortunately I've already re-rolled the hardware enough times and I don't want to do it again for just a hobby project \$\endgroup\$ Jan 26, 2021 at 14:52
  • 1
    \$\begingroup\$ that's an interesting way to do it. not recommended but possible (with serious limitations). how many channels? what pwm period? what mcu clock? what resolution? any other time critical activities taking place (e.g. serial rx)? \$\endgroup\$
    – Pete W
    Jan 26, 2021 at 17:21
  • 1
    \$\begingroup\$ Serialrx is going to be going on. I'm thinking of a 256 prescaler on clock0, which leaves me with a ~250hz pwm, and gives me a minimum of 256 clock cycles to handle everything in the ISR. At the moment only 3 pwm channels, but it will increase in the future. What's the "right" way to do this if it's more than the available hardware pwm channels? \$\endgroup\$ Jan 26, 2021 at 17:59
  • 1
    \$\begingroup\$ "what's the right way?" - besides different hardware (obv)? I can't think of one. Having the interrupt cycle thru a list of (pin_mask, counter_value) pairs isn't that bad, actually. you could have the timer overflow interrupt reset everything. \$\endgroup\$
    – Pete W
    Jan 26, 2021 at 18:17


Your Answer

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

Browse other questions tagged or ask your own question.