Модернизированный "FX3U"

Sep 27, 2024 16:30

Как уже писал, код закончил утром, а только что закончил Readme.md дописывать. Вот и сделал пуш во все свои кодохранилища.
Издевался над парочкой из более свежей партии:



Самый первый почему-то перестал "общаться" по RS-232 (однако, по модбасу и кэну работает - видимо, преобразователь уровней помер).
Получилось очень даже приличное устройство (в отличие от оригинала, который вообще хрен запрограммируешь нормально). Если нужно кастомизировать, а базовых возможностей не хватает, любой может открыть исходники и добавить нужный ему код. Быстро, удобно и не требует изучать всякие левые недоЯПы (а то и вообще мышей надрачивать дичь какую-нибудь).
Более-менее подробно документация изложена по ссылке, поэтому здесь лишь немного прокомментирую.

У прошивки есть уйма настроек, которые можно менять как по 232, так и по CAN. В модбасе количество доступных действий сильно ограничено и он скорей для того, чтобы устройство как господина использовать, посылая команды рабам.
Раньше уже писал, что устройства при помощи простой настройки по 232 можно связать по CAN или modbus (во втором случае мультимастер нельзя, поэтому лишь одно устройство сможет посылать команды - адов недостаток этого ублюдского протокола, пережитка прошлого). В настройках есть параметры "canidout" - адрес раба в CAN-шине - и "modbusidout" - адрес раба в модбасе. И если установить флаг "f_send_relay_can", при изменении входов на устройстве оно будет посылать по CAN команду рабу, чтобы тот включил/выключил соответствующие релюшки. Аналогично "f_send_relay_modbus" позволяет делать это по модбасу. Если адрес раба равен нулю, посылается широковещательная посылка. В CAN-шине, понятное дело, все сразу ринутся отвечать на нее, а вот в модбасе, естественно, рабы будут молчать.

По 232 протокол текстовый, как я и люблю. С хэшами (заменив strcmp на switch) я только один раз заморачивался - ну его нафиг, этот кодогенератор. Куда удобней просто структуру объявлять: команда, ее код (отрицательный для "чисто текстовых"), стока справки (которая формируется по запросу help).
У команды может быть параметр, например так: relay5=1 (включить реле с номером 5), а может и не быть: relay=0b1010 включит первое и третье, выключив все остальные. Для общих с CAN команд парсер формирует CAN-пакет, а потом вызывает соответствующий обработчик и, если код возврата не "OK", пишет текст ошибки. Для "чисто текстовых" команд обработчик имеет немного другой вид: туда идет строка - все после имени команды - и код команды (для случая, когда один парсер вызывается для разных команд - как для работы с битовыми флагами).

Кстати, о битовых флагах: если CAN может работать с ними либо как с единым целым (uint32_t), либо побитно (обращаясь к номеру бита), то текстовый формат позволяет еще по мнемоническому имени флага работать, что удобней, чем вспоминать, а что такое flag4…

Протокол CAN - мой "стандартный". Данные в остроконечном формате. Посылка: 2 байта - номер команды; 1 байт - номер параметра (либо 0x7f как метка отсутствия параметра), для геттеров это поле OR'ится с 0x80 - меткой геттера; 1 байт кода ошибки (только для ответа) и 4 байта данных. Запрос может в принципе иметь любую длину не меньше минимальной - три байта (код команды и номер параметра). Ответ всегда имеет 8 байт. В случае ошибки содержимое пакета не меняется (поэтому если он короче 8 байт, в хвосте может быть мусор), лишь в байт ошибки заносится ее код.

По модбасу я не полностью следую стандарту: во-первых, не обслуживаю прямо вообще все возможные функциональные коды, а во-вторых, не использую идиотское правило "трех с половиной байт IDLE". Вот не хватало еще таймер заводить и в прерывании по приему каждого байта взводить заново! Все намного проще: и прием, и передача данных производится при помощи DMA. Сигналом окончания пакета является прерывание IDLE. А в прерывании Transfer Complete MAX485 переводится в состояние приема данных (помним, что DMA Tx дает прерывание, когда откинет последний байт в регистр DR, если из него дернуть ногу DE, то последний байт потеряем). Ну и длина пакета у меня намного меньше стандарта: зачем выделять аж 4 буфера по 256 байт (причем, на прием нужно 257 минимум - иначе будет сигнал переполнения буфера и вообще всю посылку потеряем)? Понятно, что китайцы на этот клон напаяли жирнючий МК, где этой памяти - хоть лопатой жри! Но если грамотно к разработке подходить, туда хватит "восьмерки": сейчас прошивка в 16кБ укладывается + нужно хоть немного места во флеше для хранения настроек.
В режиме господина шины МК шлет в модбас введенные пользователем из терминала 232 данные (два формата: либо со строгой проверкой - "modbus", либо вообще без проверки - "modbusraw"). Два байта CRC добавляются автоматом. Как только что-то пришло, проверяется CRC и формат посылки, а затем сообщение парсится и выводится на терминал. Заодно, если там все ОК и требуется что-то сделать, это делается (например, щелкаются релюшки, перезагружается МК и т.п.).

Да, я не использую "набортную" флешку: вообще не вижу в этом смысла, учитывая то, какой огромный объем флеша у самого МК. Да даже если только 1кБ выделить под настройки, вряд ли кто-нибудь осилит менять их настолько часто, чтобы убить МК. Тем паче, сохраняются настройки во флеш исключительно при подаче команды "saveconf" (или ее CAN'овского аналога 9), а до этого изменения лишь в оперативке происходят (поэтому можно как угодно баловаться: если "поломаешь", но не успеешь сохранить, просто перезагрузишь МК, и все вернется).

Может быть, когда-нибудь я таки возьмусь, да нарисую оригинальную схему в кикаде, а потом на основе нее нарисую свой вариант: со вменяемым МК и вменяемой трассировкой (уж SWCLK на DE сажать точно не буду - как отлаживать, если хочется не отключать на время отладки модбас?).

Набортную кнопку я использую как IN8, возможно, это не очень хорошо. Если мне кто-нибудь пришлет вариант с максимальным количеством входов и выходов (из клонов я нашел лишь 56MR, хотя в оригинале бывают и 64MR), будет понятно: везде отсутствуют каналы 8 и 9, или только в этом варианте.
Ну и RTC не использую: непонятно, на кой черт вообще оно там нужно, если у F103 нет полноценного RTC, да и точность ни к черту. Ну и ЦАП не использую, если понадобится - несложно добавить.

В общем, я доволен. И еще больше буду доволен, если таки нарисую полную схему в кикаде.
Единственным недостатком при переделке этих недорогих модулей является то, что для прошивки нужно подпаять проводок к резистору на BOOT0 и при подаче питания подцепить его на +3.3В. Затем при помощи stm32flash отключается защита, стирается флеш, и можно записывать свою прошивку. Под CAN я просто два проводка припаял, но хорошо бы туда впаять такой же разъем, как соседний - где 485 и аналоговые входы/выходы.
Разъем SWD в своей версии я бы сделал, как и в прочих железяках - нераспаянная гребенка с шагом 1.27мм, куда очень удобно вставляются контакты "прищепки".
Ну и, понятное дело, в своей версии сделал бы независимыми оба полюса каждого входа и каждого выхода. Иначе получается уж больно узкий круг задач, которые можно решить этой фиговиной. Ну или если оставлять входы с общим, то хотя бы биполярные опторазвязки воткнуть…

железяки, stm32, c

Previous post Next post
Up