Вернее, можно на ассемблере писать, но некомфортно — кругом одни деревья, леса не видно. Язык C для микроконтроллеров — самое оно.
Неделя ушла на выяснение причин, почему сервомашинка, будучи подключена к одному из двух каналов управления, слегка дергается когда ширина импульсов в обоих каналах становятся равными (даже если меняется другой канал).
Если по порядку, то задача выглядит довольно просто: есть два порта. Нужно управлять шириной импульсов в каждом канале в интервале от 0.5 ms до 2 ms. Между импульсами делать задержку примерно в 10 ms. К каналам подключены две сервомашинки (на самом деле сервомашинка и регулятор хода, но это не важно), чем шире импульсы, тем на больший угол поворачивается серва (или быстрее вращается двигатель).
Самое главное — чтобы в генерируемых сигналах не дрожали интервалы импульсов, так как сервомашинки реагируют на это дерганиями.
Решение, которое получилось с самого начала было довольно простым, и экономичным, как с точки зрения прерываний, так и с точки зрения занятости микроконтроллера: включаем оба канала, заряжаем таймер на минимальный импульс. Когда срабатывает прерывание таймера, выключаем нужный канал, снова заряжаем таймер на оставшееся время. При повторном срабатывании прерывания, выключаем второй канал, и снова заряжаем таймер на время между импульсами.
Все работало очень хорошо, за исключением одной мелочи — когда значения в каждом канале были близки (+/- десяток отсчетов таймера), сервомашинки слегка подергивались. Причина — разница во времени работы ISR в случаях когда импульсы не равны и когда равны.
Всю неделю я убил на то, чтобы заставить эти чертовы импульсы перестать дрожать, и не смог. За это время программа переписывалась пятью различными способами, а результат один — подрагивания остаются.
К своему стыду, то решение, которое в конце концов заработало именно так как нужно, мне не нравится — приходится использовать по отдельному прерыванию таймера на каждую сервомашинку, что с моей точки зрения, перебор. Другое решение, которое скорее всего тоже заработает — использовать режим compare ECCP, что тоже не лучше — каналов ECCP всего два, и они точно могут понадобится в будущем оба.
Вот так выглядит подрагивающая серва (дрожит на 12-й секунде видео):
Зачем все это делалось, расскажу в другой раз, после испытаний :).