Ниже прилагаю полность програмную реализацию ШИМ, это перевод из книги Make AVR Programming Элиота Вильямса и моя интерпритация. Код разделен на две независимые части. Функция pwmAllPins(), реализует програмный шим. Остальной код в главном цикле, увеличивает и уменьшает переменную отвечающую за яркость. Вызов функции pwmAllPins() и увеличение и уминьшение яркости приводит к пульсированию светодиодов. В pwmAllPins(), мы итеритуемся по i, что дает ровно 256 шагов каждый раз. В нутри цикла мы сравниваем переменную яркости с i и включаем светодиоды если i меньше. Это дает эффект включенных светодиодов в начале каждого прохода до 256 и затем отключает их, так скоро как i достигает значени переменной яркости, так что для более высокого значение яркости светодиоды отсаются включены на больший процент из 256 шагов. ШИМ! Но следует отметить, это загружает процессор под завязку утилизируя его только на включение и отключение светодиодов. Часть кода main() устанавливает переменную направления dir