best solution for 12 analog outputs (5 bits)

dhenry:
I changed the code slightly to make it easier and more consistent.

//generate multiple ppm output

//pin configuration
#define PWM_PORT    PORTB
#define PWM_DDR     DDRB
#define PWM0        (1<<0)
#define PWM1        (1<<1)
#define PWM2        (1<<2)
#define PWM3        (1<<3)
#define PWM4        (1<<4)
#define PWM5        (1<<5)

//set pwm duration for each bit
#define PWM_Bit     (PWM_100us)     //duration of 1 bit
//pin configuration

//defining timing constants
#define PWM_ms      (F_CPU / 64 / 1000)  //milli seconds, 64:1 prescaler
#define PWM_1ms     (PWM_ms)
#define PWM_500us   (PWM_1ms / 2)
#define PWM_250us   (PWM_500us / 2)
#define PWM_100us   (PWM_500us / 5)
#define PWM_2ms     (PWM_1ms * 2)
#define PWM_5ms     (PWM_1ms * 5)
#define PWM_10ms    (PWM_1ms * 10)

//duration examples for 6 channels
unsigned char duration[]={
  1,                                //expected output: 1 / 31 * 5v
  4,                                //expected output: 4 / 31 * 5v
  8,                                //expected output: 8 / 31 * 5v
  16,                                //expected output: 16 / 31 * 5v
  30,                                //expected output: 30 / 31 * 5v
  7};                                //expected output: 7 / 31 * 5v
 
//tmr1 ctc isr
ISR(TIMER1_COMPA_vect) {
  static unsigned char index = 0;    //index
 
  //update the period
  if (index) OCR1A = OCR1A * 2;
  else OCR1A = PWM_Bit;
 
  //change the pins
  if (duration[0] & (1<<index)) PWM_PORT |= PWM0;  //set pwm0
  else PWM_PORT &=~PWM0;                        //clear pwm0
 
  if (duration[1] & (1<<index)) PWM_PORT |= PWM1;  //set pwm1
  else PWM_PORT &=~PWM1;                        //clear pwm1
 
  if (duration[2] & (1<<index)) PWM_PORT |= PWM2;  //set pwm2
  else PWM_PORT &=~PWM2;                        //clear pwm2
 
  if (duration[3] & (1<<index)) PWM_PORT |= PWM3;  //set pwm3
  else PWM_PORT &=~PWM3;                        //clear pwm3
 
  if (duration[4] & (1<<index)) PWM_PORT |= PWM4;  //set pwm4
  else PWM_PORT &=~PWM4;                        //clear pwm4
 
  if (duration[5] & (1<<index)) PWM_PORT |= PWM5;  //set pwm5
  else PWM_PORT &=~PWM5;                        //clear pwm5
 
  //update index
  index += 1;                                   // incrment index
  if (index == 5) index = 0;                    //wrap around index
}

//set up the timer1, 64:1 prescaler
void tmr1_init(unsigned short period) {
  TCCR1B &=~0x07;    //stop tmr1
 
  //set up tccr1a
  TCCR1A =    (0<<COM1A1) | (0<<COM1A0) |    //com1a10 = 0b00, normal operations
              (0<<COM1B1) | (0<<COM1B0) |    //com1b10 = 0b00, normal operations
              (0<<WGM11) | (0<<WGM10);       //wgm2..0 = 0b0100, top at OCR1A
  TCCR1B =    (0<<ICNC1) | (0<<ICES1) |      //disable input capture noise canceller and input capture edge select
              (0<<WGM13) | (1<<WGM12) |      //wgm3..0 = 0b0100, top at OCR1A
              (0<<CS12) | (1<<CS11) | (1<<CS10); //cs2..0 = 0b0011, 64:1 prescaler
  TCCR1C = 0x00;

//reset the timer/counter
  TCNT1 = 0x0000;                            //reset the timer
 
  //load the period
  OCR1A = period;

//reset the flag
  TIFR1 |= (1<<OCF1A);
 
  //enable the interrupt
  TIMSK1 |= (1<<OCIE1A);
}

void setup(void) {
  //initialize the output pins
  PWM_PORT |= PWM0 | PWM1 | PWM2 | PWM3 | PWM4 | PWM5; //set the pins
  PWM_DDR  |= PWM0 | PWM1 | PWM2 | PWM3 | PWM4 | PWM5; //set up the pins for output
 
  //set up the timer
  tmr1_init(PWM_Bit);
 
  //enable interrupt
  sei();
}

void loop(void) {
}

Just for confirmation: is it true that the PWM frequency is 500 Hz with a PWM_Bit duration of 1 ms?