# START/STOP СИФУ в 166: обработка без ожидания основного цикла ## Что изменено До исправления main опрашивал последнее состояние команды. Короткий ноль между двумя единицами мог не попасть в опрос; запись EEPROM задерживала как выдачу, так и снятие дискрета. Теперь каждое принятое по CAN слово 127 передаётся в UMP_commands_write прямо в CAN ISR. Полный подтверждённый CRC RS-пакет вызывает ту же функцию из ReceiveCommandModbus6. История фронтов общая для CAN и RS. Повторная передача единицы не является новым событием. Новое 0→1 обрабатывается сразу, без очереди и ожидания main. Это не гарантирует приём каждого физического CAN-кадра при перегрузке шины; обрабатываются кадры, которые действительно дошли до Handlai. | Событие | Результат | |---|---| | START 0→1, STOP=0 | START_DPTB включается, RES_OUT_2 активируется | | START остаётся 1 | Импульс не продлевается | | Новый START 0→1 во время START | Оставшееся время снова 1000 тиков | | STOP 0→1 во время START | START снимается, включается STOP, RES_OUT_2 снимается | | START и STOP пришли одновременно | Только STOP, без кратковременного START | | START изменяется при STOP=1 | Пуск подавляется и не ставится в очередь | | STOP снят, START остался 1 | Самопуска нет; нужен новый 0→1 START | | STOP снят и пришёл свежий фронт START | Переключение STOP→START без перекрытия | | Истекли 1000 тиков | Активный дискрет снимается; RES_OUT_2 сохраняет состояние | Таймер 1 кГц вызывает UMP_pulse_tick перед Load_runner. main больше не пишет START/STOP и не отсчитывает IMPowse. Номинальная длительность импульса около секунды (фаза первого тика даёт до 1 мс разброса). Задержки/запреты IRQ могут удлинять реальное время: это не аппаратный одновибратор. Функции автомата используют короткий запрет IRQ с восстановлением старой маски. В них нет EEPROM, передачи UART, ожидания ACK или обхода массива. volatile описывает общие данные; целостность изменения состояния обеспечивает критическая секция, а не само ключевое слово. ## Включение платы и параметры До UMP_pulse_init команды записываются в карту, но не выдают дискрет. Инициализация после Load_params/Setup_DAC_time снимает выходы и запоминает текущую команду. Уже активная единица не запускает СИФУ задним числом. При начальном нуле первая свежая единица принимается без предварительного прохода основного цикла. Потерю/перезапуск питания контроллер должен учитывать своим протоколом: перед новым запуском передать ноль. Default_params и Load_params для dsk_LOAD не копируют и не обнуляют слово 127 как обычный параметр. Служебные биты сбрасываются отдельно, START/STOP сохраняются. Поэтому чтение EEPROM не подменяет живую команду старым значением даже на один тик прерывания. Остальные типы платы сохраняют прежний сброс. ## Что ещё может задерживаться - RS: байты принимает ISR, но CRC и исполнение FC06 происходят в main. Если main ждёт EEPROM, RS-команда ещё не считается принятой обработчиком. - EEPROM: синхронное ожидание без тайм-аута сохранено. Оно не задерживает уже принятые CAN-пуски и снятие импульса, пока обслуживаются прерывания. - ЦАП: начальная пауза примерно 3 с и профиль 6..16 мА сохранены. LOAD_TIME=30 с ускорением второй половины даёт около 22.5 с разгона. START/STOP дискреты и расчёт ЦАП — разные механизмы; приоритет STOP относится к дискретам, не переписывает алгоритм аналогового задания. - Повторный фронт во время активного START продлевает высокий уровень, не создаёт отдельный электрический импульс с паузой между ними. - Произвольная запись памяти сервисным загрузчиком не считается обычной CAN/RS-командой и не проходит автомат фронтов. ## Код и комментарии - Include/ump_pulse.h — проверяемый автомат без GPIO. - Include/ump_control_impl.h — аппаратная обёртка, подключённая только в DAC.c. - ecan.c/message.c — точки приёма полного командного слова. - measure.c — владелец временной базы дискретов. - package.h/DAC.h — volatile-доступ к команде и диагностическому IMPowse. Во всех 17 собственных C-модулях и основных заголовках добавлены русские комментарии: назначения, контексты main/ISR, единицы и ограничения. Кодировки исходников сохранены (CP1251). Код TI и внешние библиотеки не менялись. 29 файлов с изменением только комментариев проверены сравнением токенов с HEAD после удаления комментариев: исполняемый текст в них совпадает. ## Проверка - Host-тест tests/ump_pulse/control_test.c включает настоящий автомат и аппаратную обёртку с подменёнными GPIO/IRQ. Проверяет стартовую защиту, короткий ноль, удержание, повторный фронт, STOP, отсутствие перекрытия на каждой записи GPIO, завершение без main, параметры и вложенный запрет IRQ. - Тест регистратора tests/ump_logger прошёл; существующие 7 тестов модели ограничения DAC проекта 167 также прошли (это отдельный исторический анализ). - Все 27 C/ASM-файлов собраны и слинкованы TI C2000 22.6.1.LTS, Debug/O1, COFF/FPU32. Остались шесть прежних предупреждений measure.c/peripher.c. - MAP: RAML0 занято 0x3979 из 0x4000 слов, RAML5 — 0xFAB из 0x3000; .logg — 0xFA00 слов во внешней памяти. Стек выделен 0x3F0 слов; максимальное реальное использование стека на устройстве не измерялось. - Из проверенной сборки обновлены штатные OUT/HEX/BIN и карта преобразования. Запуск тестов на Windows: `py -3 tests/ump_pulse/run_test.py` и `py -3 tests/ump_logger/run_test.py`; нужен Clang/lld либо MSVC в PATH, или параметр `--compiler "полный путь к cl.exe"`. Проверка на плате не выполнялась. На стенде проверить GPIO62/GPIO58 и RES_OUT_2 осциллографом: CAN-пуск во время Save_params, короткий сброс, одновременный START/STOP, останов во время пуска, длительность импульса при нагрузке CAN и работа с включённым логгером. Привязать результат к принятым CAN-командам и выходам в архиве SetGUI.