В Вашем коде не хватает самой малости - самого кода. Изворачиваться больше не нужно, вот Вам то, что называют полным кодом Я не поленился накопипастить из двух мест и добавить двойную буферизацию для получения Phase and Frequency Correct PWM.
Вот это - собственно 256-зубый ШИМ. Безвозвратно тратится 26 регистров из 32, R2..R25 - уставка ШИМ, R1 (tmp) - рабочий, R2 (pwm) - пила ШИМа. Таймер в режиме CTC - Clear On Compare (реинициализация и сброс флага автоматические):
;Один шаг пилы ШИМ - ISR таймера
t0isr:
in stsav,SREG ;Сохраняем статус. STSAV - общий для всех невложенных прерываний
inc pwm ;Добавляем очередной зуб к пиле ШИМ
breq reinit_PWM ;Загружаем новые значения уставок в начале каждого нового цикла ШИМ
cp r2,pwm ;Перенос=1 при Rx <= PWM ;Те же 2 такта на канал, что и у ПИКа
rol tmp ;Вдвигаем перенос в рабочий регистр ;
cp r3,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r4,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r5,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r6,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r7,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r8,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r9,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
out PORTA,tmp ;Выставляем ноги PWM 1..8
cp r10,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r11,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r12,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r13,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r14,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r15,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r16,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r17,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
out PORTB,tmp ;Выставляем ноги PWM 9..16
cp r18,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r19,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r20,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r21,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r22,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r23,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r24,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
cp r25,pwm ;Перенос=1 при Rx <= PWM
rol tmp ;Вдвигаем перенос в рабочий регистр
PWM_reti:
out PORTC,tmp ;Выставляем ноги PWM 17..24
out SREG,stsav ;Восстанавливаем статус
reti
;Загрузка новых значений уставок и обнуление ШИМ-выходов в начале каждого нового цикла ШИМ
reinit_PWM:
lds r2,PWM_array+0 ;Копируем 24 уставки из RAM в рабочие регистры ШИМ
lds r3,PWM_array+1
lds r4,PWM_array+2
lds r5,PWM_array+3
lds r6,PWM_array+4
lds r7,PWM_array+5
lds r8,PWM_array+6
lds r9,PWM_array+7
lds r10,PWM_array+8
lds r11,PWM_array+9
lds r12,PWM_array+10
lds r13,PWM_array+11
lds r14,PWM_array+12
lds r15,PWM_array+13
lds r16,PWM_array+14
lds r17,PWM_array+15
lds r18,PWM_array+16
lds r19,PWM_array+17
lds r20,PWM_array+18
lds r21,PWM_array+19
lds r22,PWM_array+20
lds r23,PWM_array+21
lds r24,PWM_array+22
lds r25,PWM_array+23
clr tmp
out PORTA,tmp ;Обнуляем ноги PWM 1-8
out PORTB,tmp ;Обнуляем ноги PWM 9-16
rjmp PWM_reti ;Обнуляем ноги PWM 17-24, используя хвост общей ISR, и выходим из ISR
;Процедура приема-разбора-раздачи уставок - ISR приема UART
;Формат команды - 2 байта (байт номера канала + байт уставки этого канала)
;Байт номера канала опознается по одновременно принятому UARTом 9-му биту (parity) = 1
;Буфер уставок (PWM_array) для удобства располагаем в самом начале RAM (с адреса 0x0100)
;или выравниваем по модулю 256
UARTrxISR:
push tmp ;Сохраняем регистр, не сохраняем статус - он не затронется
lds tmp,UCSRB0 ;Смотрим, что пришло - номер канала ШИМ или данные
sbrs UCSRB,RXB80 ;
rjmp set_data
;set_addr:
lds tmp,UDR0 ;Читаем пришедший номер канала ШИМ из UART, сбрасываем флаг приема
sts PWMchan,tmp ;Сохраняем его в ОЗУ
pop tmp ;Восстанавливаем регистр
reti ;21 такт (1.05 мкс) вместе со входом при приеме номера канала
set_data:
push xl ;Сохраняем регистр
push xh ;Сохраняем регистр
lds tmp,UDR0 ;Читаем пришедшую уставку из UART, сбрасываем флаг приема
lds xl,PWMchan ;Загружаем LSB указателя массива ШИМ
cpi xl,24 ;Проверка границ массива
brsh PWM_err ;Игнорируем команду, если номер канала больше 23
ldi xh,high(PWM_arrray) ;Загружаем MSB указателя массива ШИМ
st x,tmp ;Записываем уставку в буфер нужного канала ШИМ
PWM_err:
pop xh ;Восстанавливаем регистр
pop xl ;Восстанавливаем регистр
pop tmp ;Восстанавливаем регистр
reti ;34 такта (1.7 мкс) вместе со входом при приеме уставки канала
;Итого 21+34=55 тактов, или 2.75 мкс на канал, или 2.75*24=66 мкс на все 24 канала
1. Накладные расходы по регистрам - 26 байт: 24 рабочих ШИМ, tmp и pwm. По RAM - 25 байт (буфер уставок ШИМ PWM_array[24] для двойной буферизации - обеспечения Phase and Frequency Correct PWM, и 1 байт указателя канала - PWMchan)
2. Накладные расходы по времени (вход-выход ISR, инкремент пилы, 4 вывода в порт, сохранение-восстановление статуса) - 18 тактов, или 18/24 = +0.75 такта к каждому каналу, что дает 18+(24*2)= 66 тактов на ISR или 2.75 такта на канал. При 100% загрузке 20-МИПСового АВРа (ATMega164/324/644) ТОЛЬКО этой задачей достижимая частота каждого из 24 каналов 256-ступенчатого ШИМ составит 20 МГЦ/66*256=1183 ГЦ.
3. Если для обновления уставок использовать UART, то для передачи всех 24-х двухбайтовых команд за 1 цикл ШИМ UART должен работать со скоростью не менее 576 КБод (при Fcy=20 MHZ можно с запасом выбрать 625 КБод). Все 24 уставки будут приняты, декодированы и розданы за 24*55=1320 тактов, или 66 мкс. При 100% загрузке 20-МИПСового АВРа (ATMega164/324/644) обеими задачами достижимая частота каждого из 24 каналов 256-ступенчатого ШИМ составит 20 МГЦ/((66*256)+1320)=1098 ГЦ.
И вот теперь будьте добры привести в таком же полном и обсчитанном виде Ваш код. Подразумевается прием и формирование 24-х
совершенно новых произвольных уставок ШИМ за один период, как это сделано у меня. Производительностью ШИМ будет считаться достигнутая частота ШИМ при 100% загрузке 20-МИПСового АВР класса ATMega164/324/664
всеми необходимыми задачами последовательно в едином цикле - прием по UART и дешифрация 24-х двухбайтовых команд, сортировка, формирование 24-х бит-массивов ШИМ, формирование 24-х сигналов ШИМ на 24-х выводах МК. А байки про огромную коммерческую ценность Вашего шедевра оставьте, пожалуйста, для другой аудитории - здесь, как видите, не прокатило, и придется Вам отдуваться бесплатно