Перейти к содержанию
    

22 минуты назад, Arlleex сказал:

Сброс флагов запроса лучше всегда переносить в начало обработчика.

Не всегда. Например, в SPI - вектор один, а флагов много. Сбросите все флаги сразу - потеряете их.

49 минут назад, Xenia сказал:

Но выше частоты 16 КГц начинались потери импульсов:

Ну и чему удивляетесь:

__HAL_GPIO_EXTI_CLEAR_IT( GPIO_PIN_1);

К тому же, в случае равенства настроенного приоритета, приоритет прерывания определяется по его номеру - чем меньше номер, тем выше приоритет. EXTI1 стоит раньше EXTI2 и 3, поэтому приоритет выше.

54 минуты назад, Xenia сказал:

подав на один из трех пинов достаточно высокую частоту, чтобы счетчик "захлебнулся" (100 КГц), обнаружила что, вопреки ожиданиям, остальные два счетчика по-прежнему безупречно вели счет на частоте 16 КГц, хотя "захлебнувшийся"счетчик пропускал импульсы уже тысячами.

Тогда надо искать где-то в другой части - не мешает ли чего в остальной программе? И действительно ли частота МК равна 72 МГц?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

40 минут назад, EdgeAligned сказал:

Не всегда. Например, в SPI - вектор один, а флагов много. Сбросите все флаги сразу - потеряете их.

Читаете в переменную, сбрасываете флаги, анализируете переменную. В чем проблема?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, Arlleex сказал:

Сброс флагов запроса лучше всегда переносить в начало обработчика.

Перенесла, но ничего не изменилось - наблюдаю всё тот же эффект.

 

2 часа назад, EdgeAligned сказал:

К тому же, в случае равенства настроенного приоритета, приоритет прерывания определяется по его номеру - чем меньше номер, тем выше приоритет. EXTI1 стоит раньше EXTI2 и 3, поэтому приоритет выше.

Проверила эту гипотезу - она не подтверждается, поскольку "от перемены мест слагаемых сумма не изменилась". Т.е. безупречный счет на остальных двух счетчиках продолжается вне зависимости от того, который из трех счетчиков я заставляю захлебнуться. 

 

2 часа назад, EdgeAligned сказал:

Тогда надо искать где-то в другой части - не мешает ли чего в остальной программе? И действительно ли частота МК равна 72 МГц?

Проверила логическим анализатором, но не непосредственно тактовую контроллера (поскольку ее выхода нигде на плате нет), а выход таймера при параметрах PSC=0, ARR=0 и получила частоту APB2=72 МГц.

Прошу вас заметить, что я не на задержку жалуюсь, а на ее отсутствие (!), тогда как по идее "захлебывание" одного счетчика должно было бы вызвать захлебывание всех остальных, тем более при недостатке тактовой частоты. А если вы полагаете, что мой STM32F103 разогнан до тактовой частоты во много раз превышающую 72 МГц, то этого просто не может быть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может, работает еще какое-нить высокоприоритетное прерывание, которое выполняется порядка 50 мкс?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 часов назад, adnega сказал:

Может, работает еще какое-нить высокоприоритетное прерывание, которое выполняется порядка 50 мкс?

Есть такое - у меня UART в связке с DMA гоняет текст на терминал (именно так я слежу за показаниями счетчиков), причем у UART'а 1-ый приоритет, а у DMA нулевой. Тогда как у EXII приоритет только 4-ый.

Однако прошу объяснить мне, как наблюдаемый мною эффект можно объяснить через приоритеты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

27 минут назад, Xenia сказал:

Перенесла, но ничего не изменилось - наблюдаю всё тот же эффект.

Ну, я не утверждал, что это поможет)) Просто так несколько правильнее писать обработчик.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пока выполняются обработчики UART и/или DMA все повторные (и более) импульсы будут потеряны. Каждый импульс защелкивается до его обработки обработчиком EXTI, поэтому на низких частотах потерь нет, даже если импульс пришел в момент выполнения обработчиков UART/DMA.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Настройку тактовой микроконтроллера можно проверить функцией SystemCoreClockUpdate(), и в переменной SystemCoreClock увидеть настроенное значение. Конечно, при условии правильно выставленной константе HSE_VALUE (если тактируется от внешнего кварца).

Перенос сброса флага прерывания в начало влияет наоборот, на сброс флага - известная проблема с EXTI.

 

Можно понизить приоритеты всех иных прерываний или даже запретить их, а приоритет EXTI1, 2, 3 вообще не изменять, по умолчанию он будет максимальным.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте EXTI дать высший приоритет, а UART/DMA понизить приоритет. UART/DMA не должны пострадать, т.к. за время выполнения EXTI не прилетят два символа по UART (при разумной скорости обмена).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не вижу в прерываниях сброса счетчика. Значит, он сбрасывается где-то в основном цикле. Пока вы его сбрасываете - прерывание могло добавить к нему еще несколько импульсов, которые потеряются. Я бы в основном цикле раз в секунду выставлял флаг, по которому в прерывании EXTI переносил значение счетчика в переменную для чтения, а сам счетчик обнулял.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 часов назад, Arlleex сказал:
7 часов назад, Xenia сказал:

Перенесла, но ничего не изменилось - наблюдаю всё тот же эффект.

Ну, я не утверждал, что это поможет)) Просто так несколько правильнее писать обработчик.

А я наоборот опасалась, что если сниму флаг прерывания раньше, чем закончу выполнять обработчик, то прерывание сможет возникнуть еще раз, после чего станет неясно, какой из обработчиков выполнится первым.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, Xenia said:

А я наоборот опасалась, что если сниму флаг прерывания раньше, чем закончу выполнять обработчик, то прерывание сможет возникнуть еще раз, после чего станет неясно, какой из обработчиков выполнится первым.

Период следования прерывания должен быть больше суммарного времени его обработки, входа и выхода из прерывания. Иначе неизбежен их пропуск.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не пользуйтесь HALами.

HAL не атомарен!

Для снятия битов лучше пользоваться макросом:

#define BITBAND_PERI_REF 0x40000000
#define BITBAND_PERI_BASE 0x42000000
#define BIT_PER(a,b) *((volatile uint32_t *)(BITBAND_PERI_BASE+((uint32_t)&(a)-BITBAND_PERI_REF)*32+((b)*4)))

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 часов назад, Xenia сказал:

Но выше частоты 16 КГц начинались потери импульсов: при частоте 18 КГц терялось около 5-ти импульсов, при 20 КГц - около сотни, и т.д. по нарастающей.

Для честных экспериментов (а вообще подход к задаче должен быть иным, считать импульсы должен таймер, но, я так понял, у Вас уже академический интерес именно к EXTI) в коде не должно быть уже ничего лишнего, поэтому всякие DMA и UART-ы придется выкинуть. Либо разделить по времени работу EXTI и выдачу результатов по UART. Вообще говоря, при 16 кГц прерываний, 24 тактах CPU на вход/выход из прерываний (полезный код внутри ISR не берем в расчет), загрузка CPU составит ~ 0.53%. Это копейки. Значит, что-то другое перебивает работу этих прерываний, либо вносит задержку. Например, существенно заниженная частота тактирования APB/AHB, где висит GPIO/EXTI.
 

9 часов назад, Xenia сказал:

А я наоборот опасалась, что если сниму флаг прерывания раньше, чем закончу выполнять обработчик, то прерывание сможет возникнуть еще раз, после чего станет неясно, какой из обработчиков выполнится первым.

Не совсем понял. Почему прерывание может возникнуть еще раз? Если по причине внешнего воздействия, то это как раз отлично - для этого сброс флага и переносится ближе к началу - чтобы не пропустить потенциально возможное повторное событие. И про неясность, какой из обработчиков выполнится первым, тоже не понял - разумеется, равноприоритетные прерывания вытеснить друг друга не смогут, поэтому обработаются друг за другом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 28.08.2023 в 08:50, Arlleex сказал:

Не совсем понял. Почему прерывание может возникнуть еще раз?

Типа, мы уже в обработчике прерывания, но приходит еще один запрос для того же прерывания - и получаем вложенное прерывание (само в себя). Насколько мне известно на Cortex-M такое невозможно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...