AVR Software PWM

One way to do software pwm is setting up a timer with interrupt corresponding to each pwm step. then in the interrupt routine check whether each pwm channel should be on or off.

The key question here is how fast and how many steps should be the PWM.
All depends in how much processing time you need for other tasks, and how many PWMs to run.

A good aproach that works for me is doing a 64 steps, 200 uS per step PWM for around 50 PWM channels.
This give us a total time of 50*200=12800 uS = 12.8 mS => 78.125 Hz.
Getting less than 10% of processing time.

I ussually do it with Timer0, this creates a 200 uS Timer0 CompA Interrupt.
I think it works for most AVR, but you can choose the part you need depending on wich registers your mcu uses:

```c
// For 16 MHz clock

#define T0Top_Avr 50
#define T0PresAvr 3

   #if defined( OCR0 )
      OCR0  = T0TOP_Avr;
      TCCR0 = 64 + TMR0PresAvr; // CTC mode: TOP = OCR0
   #elif defined( OCR0A )
      OCR0A  = T0TOP_Avr;
      TCCR0A = 2;               // CTC mode: TOP = OCR0A
      TCCR0B = TMR0PresAvr;
   #endif
  
   // enable Timer 0 compare_A interrupt
   #if defined( TIMSK0 )
      TIMSK0 = 0;
      TIMSK0 |= (1 << OCIE0A);
   #elif defined( TIMSK )
      TIMSK = 0;
      TIMSK |= (1 << OCIE0A);
   #endif
  
   sei();      // Enable interrupts



// Now in the interrupt routine:

#define numPWM 32             // Number of PWM Channels
uint8_t pwmChannel[ numPWM ]; // Array containing pwm values
uint8_t pwmCounter=0;

ISR(TIMER0_COMPA_vect)        // Timer 0 compare_A interrupt
 { 
    for( uint8_t i=0; i pwmCounter ) 
        {
            // Set the output line "i" HIGH
            // This depends on the hardware you are using
        }
        else
        {
            // Set the output line "i" LOW
        }
    }
    pwmCounter++;
    if( pwmCounter > 63 ) pwmCounter = 0;
{ 
```

Fast linked list without list

If you need a very fast way to iterate over a list of objects and call the same method on all of them, then here is a posible solution. Der...