#define ADC1Cnt (uint16_t)lroundf(CorrFreq(TIM234567freq)/ADCtimerPresc*ADCsmpPerpTime) //First ADC data request at about 195us from Sync request
Или даже:
#define ADC1Cnt (uint16_t)ceilf(CorrFreq(TIM234567freq)/ADCtimerPresc*ADCsmpPerpTime) //First ADC data request at about 195us from Sync request
Если нужно получить гарантированно не меньшее значение. floorf() если нужно гарантированно не большее.
В примере выше - всё в плавучке, чтобы можно было свободно подстраивать режимы и всегда выбирались оптимальные значения.
И подставляю где нужно в код инициализации таймеров, счётчиков. В вычисления всяких делителей и множителей.
У меня так почти всё сделано.
Как-то, понадобилось добавить данных и в протокол обмена (а он реального времени, нужно пакеты на кадры бить, времена обмена кадрами планировать, вочдоги выставлять на отказы связи). Коллега, обречённо: "Хрен мы сейчас успеем это сделать!". Я ему: "Смотри!"
И беру добавляю нужные поля в структуру и копирую во все проекты устройств системы. А так как всё задефайнено подобным образом, оно волшебно "само" всё рассчиталось, на кадры побилось, интервалы обмена обновились. Включаем - работает!
Но, конечно, это даётся не бесплатно - я в разы менее продуктивен, чем тот коллега, код которого не поправить подобным образом. Коллега за короткое время давал рабочий результат, который почти невозможно довести потом до ума не переделав полностью. Зато инвестиции уже пошли. Я же делаю очень долго. И рабочий результат сильно позже. Зато любые изменения - довольно быстро. И ошибки искать вполне можно - удобно и понятно, так как не прибито гвоздями к волшебным числам, а по выражениям понятно, что почему откуда и как изменить.
P.S. В современных GCC (сейчас у меня в ходу 12..15 версии, проблески 16й от Клёна) такой дефайн, если собран из статических значений (которые, по цепочке, ясны при проходе препроцессора), компилируется в присвоение константы в нужном месте.