Sergzloy писал(а): ↑17.04.2021{, 19:25}
... у меня тактирование импульсов накачки идет из внутреннего источника...
При использовании дисплея, т.е.организации интерфейса (I2C в данном случае) или выполнения любых других дополнительных цикличных задач, Ваш генератор накачки(10 мкс/20мкс) может не соблюдать установленные интервалы времени полупериодов (однопоточная система занята другими текущими задачами и время основного цикла превышает время программного генератора), а скоростной счётчик (на прерываниях) продолжает считать импульсы. Даже применив прерывания по переполнению аппаратного таймера для генератора импульсов накачки, понижение частоты возможно из-за ардуиновского digitalWrite()
(см.ссылку) + вызов функции безконечного цикла loop() + сравнительно медленного переключения выхода МК LOW--->dead Time--->HIGH + вызов совпавшего по времени обработчика прерываний скоростного счётчика в любом возможном сочетании этих факторов и это будет уже не измерительный прибор, так как о поддержания стабильности частоты программного генератора не может идти речи вообще. Потому для быстрой смены состояния выхода МК (например в скоростных интерфейсах) применяют способ переключения ножки LOW--->Z-State+PULLUP (т.е. переключить выход на землю--->отключить выход, а резистор внешней подтяжки притянет линию к питанию - переключив в HIGH и применения прямого доступа к регистрам ввода /вывода. В таком случае переключение состояния линии выполняется за один такт МК (условно). Также замечу, что Arduino IDE прекрасно работает с функциями main() и while(), вместо setup() и loop() соответственно,- т.е. с организацией скетча в стиле Си т.о. можно добиться более быстрым вызов циклов программы. Если низкоуровневое программирование Вам не по силам- применяйте внешний генератор, о чём резонно подсказал Вам ув.
edyapd,. Но в любом случае необходимо организовать разделение задач и чёткую последовательность их выполнения. Как пример, для Вашего случая задачи: 1) Первичное измерение при включении питания или по внешней команде (кнопке) без инициализации/запретом других задач; 2) Запрещение 1-й задачи, как ненужной на данном этапе, програмный расчёт данных и вывод на дисплей; 3) запрещение 2-й задачи, как выполненой; 4) Цикличное измерение (подсчёт и опционально програмная генерация импульсов) с сохранением результата; 5) Последующее сравнение сохранённого отдельно предыдущего значения скоростного счётчика с текущим в пределах определённого гистерезиса(опционально); 6) повторный вызов 2-й задачи при обнаружении значимого изменения данных скоростного счётчика. Изолировав задачи, Вы сможете исключить их взаимное влияние и соответственно стабилизировать время выполнения цикла (получить константу задержки выполнения), скорректировать продолжительности полупериодов программного генератора с учетом полученой константы. Реализация в ФЛПрог возможна с помощью размещения задач на отдельных платах в проекте и выполнения их кода по условию или в цикле по условию, но выбраный Вами пользовательский блок OLED дисплея (автор не указан) совершенно не подходит для таких задач, так как выполняется по внутреннему таймеру, а нужно постоянно/по внешней команде En. IMHO
Удачи!