Если вы еще не видели очередного ардуиносрача на хабре — читать тут:
Собственно, автора можно показывать студентам-медикам в курсе общей психопатологии как наглядный пример «бреда изобретательства» — но странное впечатление производят поддерживающие его комментаторы. Кажется, что они заперлись в своем маленьком ардуино-мирке и активно не хотят признавать, что их «проблемы» (те же таймеры, например, или многозадачность) решены много лет назад.
Вот, скажем, в комментариях автор с гордостью заявляет — мол,
типовое время задержки в системе составляет 10 мс (но пиковые задержки могут быть значительно больше и не нормируются)
— и более того,
на реальных задачах это особой роли не играет потому, что 99,(9) процентов времени в системе остаются типовые задержки
Вы примерно представляете себе, что такое 10 мс? Это примерно до хрена, если речь идет о несложной, в общем-то (но абсолютно реальной) задаче типа управления инжекторным двигателем — целый оборот коленвала при 6000 оборотах в минуту. За это время надо:
— открыть форсунки;
— закрыть форсунки (выдержав требуемое время впрыска);
— в нужный (с точностью до десятков микросекунд) момент жахнуть искрой в нужную пару цилиндров;
— прикрыть или приоткрыть регулятор холостого хода;
— сделать еще кучку полезных дел — например, считать показания десятка аналоговых датчиков (ну ладно, в конкретном цикле — можно обойтись и двумя, ДМРВ и ДПДЗ) и пересчитать параметры работы двигателя (время впрыска, опережение зажигания и так далее);
И это не какие-то там нереальные космические нанотехнологии, это в каждом сраном Жигуле стоит и надежно работает (на убогом SAF C509). Не знаю, конечно, как оно сделано в том же Январе или Микасе, а вот исходники MegaSquirtAVR вполне доступны для изучения (после минимальной гуглежки) и там ничего ужасного нет — в общих чертах, кстати говоря, это повторяет материал обсуждаемой лекции (где-то с 1:16:46). В системе поддерживается очередь событий (типа «открыть группу форсунок такую-то», «закрыть группу форсунок такую-то» и так далее), в нужный момент (скажем, в верхней мертвой точке — она определяется по датчику положения коленвала, или при определенном угле поворота того же коленвала) очередная пачка событий со временами их срабатывания добавляется в очередь. Один из таймеров, «тикающий» с периодом в 4 микросекунды, начинает отсчет до ближайшего события, а при срабатывании прерывания, во-первых, выполняется связанный с событием код (довольно элементарный — «дернуть» одной из ножек микроконтролера), и во-вторых — начинается отсчет времени до следующего события из очереди. Все это работает на AtMega128 — и по отзывам, работает вполне неплохо.
Скажете, не всем надо управлять инжекторными двигателями? Хорошо, расскажу тогда про мой первый проект на микроконтролере — идейно, кстати говоря, очень похожий. Сделан он был, правда, не на AVR, а вовсе на PIC, и представлял собой PPM-кодер для аппаратуры радиоуправления. PPM — или Pulse Position Modulation — это распространенный стандарт, позволяющий «упаковать» сигналы для нескольких (до 8) сервомашинок в одну «посылку» длительностью около 20 мс. Принцип формирования (точнее, декодирования) PPM-сигнала показан на рисунке:
Декодер, кстати говоря, делается на одной микросхеме CD4017 — схема есть тут (оттуда же я уволок и картинку выше):
http://rconline.ru/modules/smartsection/item.php?itemid=49
Длительность «посылки» составляет 20 мс, пауза между импульсами каждого из каналов — 0,3 мс, а длина каждого из «канальных» импульсов — от 1 до 2 мс (считая вместе с паузой). Для восьмиканальной (максимально доступное количество каналов в PPM-аппаратуре) длина синхроимпульса составит 4 мс. Кстати, теперь понятно, почему сервомашинки управляются таким, на первый взгляд, странным образом?
Так вот, имея «в активе» PIC16F72 с АЦП и прочитанные пару глав из самоучителя Корабельникова (не смейтесь — но 11 лет назад в жанре «введение в микроконтролеры для чайников» выбор был между слегка упоротым Корабельниковым и полностью шизофреническим 123avr) я соорудил вполне приличный кодер для PPM-сигнала, поддерживающий до 8 каналов с 8-битным разрешением (для аппаратуры радиоуправления 8 бит — уже неплохая разрядность, в самой дорогой аппаратуре можно встретить 10-битные АЦП). Опять же, все очень просто — запускаем таймер с частотой 10 МГц (для удобства счета), и радостно пользуемся тем фактом, что один отсчет этого таймера — это в точности 0,1 микросекунды. При срабатывании прерывания таймера — просто загружаем в него либо значение, соответствующее длительности паузы, либо заранее вычисленную длительность «сигнального» импульса. Немного сложнее, чем генерация обычного ШИМ на том же таймере — но принцип примерно тот же.
Про многозадачную операционную систему на PIC рассказывать, наверное, не буду — собственно, под видом «операционной системы» предлагался просто способ организации кода в виде относительно независимых «задач». Этого в «самоучителе» не было — но найти ее и использовать не представляло особого труда.
При чем здесь ардуино? Наверное, ни при чем — если, конечно, не обращать внимания на огромное количество совершенно поверхностных материалов «для начинающих». Честное слово, даже упоротый Корабельников, невероятно многословно рассказывающий в своем «самоучителе», как организовывать задержки с использованием аппаратного таймера и прерываний, намного лучше любого материала «про ардуино», где то же самое предлагается делать с помощью разнообразных задержек типа delay() (библиотека же Timer1 считается в среде ардуинщиков каким-то «высшим пилотажем», а заодно и не работает на некоторых платформах).
