Попробуй нечто в таком духе:
Код
typedef struct {
int count;
unsigned mask;
} pwmchan_t;
pwmchan_t pwm_array[2][17];
int current_array;
int count;
unsigned mask;
// прерывание
// Вывести (приготовленную на прошлом заходе) маску в порт
// Это минимизация джиттера
PORT = mask;
if( ++count == PERIOD) {
count = 0;
mask = 0;
pwmptr = pwm_array[current_array];
} else {
while( count == pwmptr->count ) { // тут было правильно, но ГЛУПО
mask |= pwmptr->mask; // видать, послобеденная полудрёма не дала
++pwmptr; // нормально добавить обработку нескольких одинаковых
}
}
В массиве содержатся отсортированные по возрастанию count записи, при изменении
скважности какого-от канала массив пересортировывается во второй копии и делается
замена индекса current_array с 0 на 1 и назад
При желании можно замену current_array привязывать к окончанию периода - менять
current_array_next, а в обработчике прерывания по достижению PERIOD делать
current_array = current_array_next
Главное, чтобы обработчик успевал при самом худшем раскладе -
когда все каналы станут на одну скважность - уложиться в период (а не в половину).
Ну а загрузка процессора будет низкая, гораздо ниже половины (основная масса прерываний
будет отрабатывать быстро).
Да, совсем забыл. записей в массиве 17 для того, чтобы в последней записи держать такое значение .count, что оно не будет достигнуто счётчиком. Это чтобы if( count == pwmptr->count ) и аналогичное в while работало и как ограничитель инкремента указателя