Берёшь freemodbus. Портируешь (там делов на один присест). И всё,
работает. Из не предусмотренного в том коде из коробки, я добавил
состояния удержания линии перед передачей и после передачи на пару
символов, чтобы обеспечить сброс ошибок на приёмниках, если на не
привязанной линии до моей посылки был шум. Ну и светодиод вставил -
включается когда увидел свой адрес и выключается когда переходит в
ожидание следующего кадра. Больше времени, чем само портирование, отняло прописывание папок в среде разработки, чтобы оно вообще собираться начало. А так - код прямолинейный и простой, использует минимум памяти. Я брал базовый код, шаблон без привязки к конкретному контроллеру. И глядя на пример с AVR, сделал под свой STM. Там всего поправит нужно: функции инициализации UART и таймера и интерфейсные функции UART и таймера. Вроде, в двух файлах всего. Ну и в файле конфигурации нужно включить что требуется и не включать, что не требуется.
https://embedded-experts.at/wp-content/uploads/2020/04/freemodbus-v1.6.zip