Спасибо, отличная ссылка, всё очень понятно написано. Буду пробовать.
nik182 пишет:
У таймера STM32 есть режим ворота - считает импульсы только когда на входе таймера 1. По закрытию ворот можно взять прерывание и считать данные. И тогда прерывание по ноге вообще не понадобится.
Ну впринципе и захват таймера достаточно понятен, главное чтобы работал без фокусов, как случилось с первым вариантом (счётчик при переключение falling-rising на int0 (PD2)), хотя проблем на первый взгляд ничего не предвещало.
Вот такой вопрос, а если спадающий фронт будет до выхода из обработчика, который был вызван по восходящему? Может ли быть такое и как это обыгрывается?
Если прерывание было разрешено (активировано по спадающему фронту) оно в любом случае выполнится. Обработчик прерывания должен выполняться быстрее чем приходят запросы на прерывание, это аксиома!
Либо оптимизируете обработчик прерывания, либо берете камень более быстрый.
Как крайний случай
ISR("название прерывания", ISR_NAKED)
Не будет создаваться пролог и эпилог в прерывании, что иногда, значительно ускоряет обработчик прерывания. Но здесь скрыто зло! Регистры использованные в прерывании, тот же SREG, будут изменены неожиданно для основной программы. Это вызовет троднонаходимые глюки. Если пришлось использовать такую запись, тогда лучше зарезервировать регистр(ы), например
register volatile uint8_t int_flags asm("r16");
И пользоваться в прерывании только ассемблером, не используя операции которые могут изменить SREG.
В любом случае, прерывание не выполнится быстрее чем за 4(такта вход)+4(такта выход).
Раз в 10 секунд в основном цикле вывожу число импульсов impulses и состояние int_state. Прерывания делаю задолго до отправки в uart(поэтому 10 секунд и чтобы вывод не влиял на прерывания), замыканием провода от +3.3V на INT0, INT0 (PD2) подтянут к GRD R=1М (чтобы быстро не спадал).
printf("%d %d\n", impulses, int_state);
И тем не менее, иногда получаю int_state = 1 в выводе printf(), то есть не был вызван обработчик нисходящего фронта. Единственное предположение почему это произошло, это то что нисходящий фронт пришёл настолько быстро после восходящего, что мк не успел его обработать. И это без всяких таймеров.
На мой взгляд решение с переменой фронта подходит для обработки сигналов, переключающихся с достаточно медленной (относительно исполнения обработчика прерывания) скоростью.
Прерывания делаю задолго до отправки в uart(поэтому 10 секунд и чтобы вывод не влиял на прерывания), замыканием провода от +3.3V на INT0, INT0 (PD2) подтянут к GRD R=1М (чтобы быстро не спадал).
Может быть вам стоит сделать из второй ардуины генератор тестовых импульсов, чтобы проверять работу придуманных алгоритмов для разных вариантов входных импульсов.
На мой взгляд решение с переменой фронта подходит для обработки сигналов, переключающихся с достаточно медленной (относительно исполнения обработчика прерывания) скоростью. Сидение на таймере более устойчиво.
Да действительно, захват таймера работает быстро и стабильно. Его функционал меня полностью устроил. В прошлом варианте всё это делал сам, но чаще пропадали нисходящие фронты и работало медленней.
Bruzzer пишет:
Может быть вам стоит сделать из второй ардуины генератор тестовых импульсов, чтобы проверять работу придуманных алгоритмов для разных вариантов входных импульсов.
Можно конечно сделать регулируемый шим-генератор, но пока протестировал просто замыканием, и всё работает, даже при 100% заполнении (долгом замыкании).
по ссылке у человека силовая автоматика, при управлении которой цепи питания ардуины должны быть защищены, у меня же в стабильных тестах питание от компа usb, да и прерывания от пина +3,3V через 10к, так что никаких значимых воздействий на стабильность таймера иметь не могут.
ddr2, вы , по-видимому, не поняли, это и была реплика в поддержку рекомендации отказаться от прерываний int0 и int1 в пользу прерывания по захвату. Ну или я не понял...
DDR2, может поможет:
https://radioparty.ru/prog-avr/program-c/548-ispolzovanie-tajmera-v-rezhime-zakhvata-izmerenie-shiriny-skvazhnosti-i-chastoty-signala
У таймера STM32 есть режим ворота - считает импульсы только когда на входе таймера 1. По закрытию ворот можно взять прерывание и считать данные. И тогда прерывание по ноге вообще не понадобится.
Вот такой вопрос, а если спадающий фронт будет до выхода из обработчика, который был вызван по восходящему? Может ли быть такое и как это обыгрывается?
Если прерывание было разрешено (активировано по спадающему фронту) оно в любом случае выполнится. Обработчик прерывания должен выполняться быстрее чем приходят запросы на прерывание, это аксиома!
Либо оптимизируете обработчик прерывания, либо берете камень более быстрый.
Как крайний случай
Не будет создаваться пролог и эпилог в прерывании, что иногда, значительно ускоряет обработчик прерывания. Но здесь скрыто зло! Регистры использованные в прерывании, тот же SREG, будут изменены неожиданно для основной программы. Это вызовет троднонаходимые глюки. Если пришлось использовать такую запись, тогда лучше зарезервировать регистр(ы), например
И пользоваться в прерывании только ассемблером, не используя операции которые могут изменить SREG.
В любом случае, прерывание не выполнится быстрее чем за 4(такта вход)+4(такта выход).
Раз в 10 секунд в основном цикле вывожу число импульсов impulses и состояние int_state. Прерывания делаю задолго до отправки в uart(поэтому 10 секунд и чтобы вывод не влиял на прерывания), замыканием провода от +3.3V на INT0, INT0 (PD2) подтянут к GRD R=1М (чтобы быстро не спадал).
И тем не менее, иногда получаю int_state = 1 в выводе printf(), то есть не был вызван обработчик нисходящего фронта. Единственное предположение почему это произошло, это то что нисходящий фронт пришёл настолько быстро после восходящего, что мк не успел его обработать. И это без всяких таймеров.
На мой взгляд решение с переменой фронта подходит для обработки сигналов, переключающихся с достаточно медленной (относительно исполнения обработчика прерывания) скоростью.
Сидение на таймере более устойчиво.
Может быть вам стоит сделать из второй ардуины генератор тестовых импульсов, чтобы проверять работу придуманных алгоритмов для разных вариантов входных импульсов.
http://arduino.ru/forum/apparatnye-voprosy/lozhnye-prervaniya-arduino#co...
http://arduino.ru/forum/apparatnye-voprosy/lozhnye-prervaniya-arduino#comment-195726
ddr2, вы , по-видимому, не поняли, это и была реплика в поддержку рекомендации отказаться от прерываний int0 и int1 в пользу прерывания по захвату. Ну или я не понял...