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

GD32F103RBT6. Пропуск прерываний в режиме захвата

On 2/14/2024 at 10:00 AM, LAS9891 said:

Просто картинка сделана когда пропусков прерываний не было.

Лучше поймать момент именно когда пропуски есть, а то так не информативно.

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


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

12 minutes ago, dimka76 said:

Лучше поймать момент именно когда пропуски есть, а то так не информативно.

Такой момент хер поймаешь. Это не подтверждает пропуски?

 

 

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


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

Искать надо там где потерял, а не там где лучше видно. Вроде это очевидно.

 

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


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

On 2/14/2024 at 10:18 AM, LAS9891 said:

Такой момент хер поймаешь. Это не подтверждает пропуски?

Подтверждает.

Но дело не в этом, а в поиске причины.

Либо у вас в какой-то момент обработчик прерывания слишком долго обрабатывает прерывание и поэтому возникают пропуски.

Это как раз бы измерение длительности обработки прерывания и показало бы.

 

Либо из-за пологих фронтов прерывание вообще не срабатывает.
Либо что-то другое.

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


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

2 minutes ago, VladislavS said:

Вроде это очевидно.

Тут многим очевидно, и многим видно, что код - говнокод. Жду первого, кто расскажет очевидное для всех, кроме меня, решение.

1 minute ago, dimka76 said:

Это как раз бы измерение длительности обработки прерывания и показало бы.

Типа надо было поймать пропуск прерывания и измерить длительность обработки предыдущего прерывания?

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


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

On 2/14/2024 at 10:23 AM, LAS9891 said:

Типа надо было поймать пропуск прерывания и измерить длительность обработки предыдущего прерывания?

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

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

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


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

1 час назад, LAS9891 сказал:

код - говнок

Я бы отказался от колбэков. Что в них происходит и как долго - неясно.

Лучше в прерываниях только собрать информацию и когда всё будет готово выставить флаг.

В main в бесконечном цикле или средствами ОС ловить этот флаг и обрабатывать принятую информацию.

Изменено пользователем dOb

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


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

8 часов назад, LAS9891 сказал:

Я учёл, но что с этим делать не знаю. Как это сделать правильно? Подозреваю предложите ловить фронты каналом 0, а срезы ловить каналом 1. Такое решение сократит функционал платы вдвое.

Ну а как борются с дребезгом? Неужто не знаете? Так и сделать.

Например: После получения события фронта/спада по каналуX, отключать регистрацию событий по данному каналу на время какого-то таймаута. Если вы уверены, что максимальная частота сигнала на входе ~1кГц, то время таймаута можно выбрать например = 0.25мсек. По истечении этого времени прочитать с ноги текущее актуальное состояние на входе (0 или 1) и заново включить регистрацию фронта или спада (исходя из текущего значения на входе). Всё.

У себя в проектах, где требуется регистрация длительностей сигналов, я именно так и делаю. Работает стабильно, даже при наличии значительного дребезга или при пологих фронтах/спадах.

8 часов назад, LAS9891 сказал:

Есть ещё идея в обработчике прерывания проверять значение захвата и если оно меньше минимального (ширина минимально допустимого импульса известна), то не учитывать его, и полярность не менять.

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

Хорошие контроллеры (типа XMC4xxx) имеют FIFO и могут в нём сохранять сразу несколько событий пересечения. Чтобы потом скопом обработать их программно. У вас вашего МК такого нет. Значит потери обязательно будут.

8 часов назад, LAS9891 сказал:

Уточнение: ранее проект жил на STM32F072. Там для таймера в режиме захвата можно выбрать режим: noninverted/both edges. Circuit is sensitive to both TIxFP1 rising and falling edges. И там проблемы смены полярности не было.

Ну и как поможет этот режим по обоим фронтам при дребезге? Точно также будут теряться события. Может просто это реже и вы не замечали.

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

 

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

Т.е. - после получения фронта - переход на п.1; после получения спада - переход на п.5.

1. переключаете режим на регистрацию спада;

2. затем - чистите флаг события по данному каналу (в INTF);

3. затем - считываете реальное текущее значение на пине;

4. Если с пина прочитан '1', то - выход из ISR; если прочитан '0' - переход на п.5;

5. переключаете режим на регистрацию фронта;

6. затем - чистите флаг события по данному каналу (в INTF);

7. затем - считываете реальное текущее значение на пине;

8. Если с пина прочитан '0', то - выход из ISR; если прочитан '1' - переход на п.1.

Если дребезг происходит редко и длится недолго, то такой алгоритм должен нормально работать. Тогда можно обойтись без алгоритма с таймаутами. Хотя алгоритм с таймаутами - надёжнее. Так как устойчив даже к длительным дребезгам и не грузит при этом излишне CPU.

 

PS: В любом случае - корректный порядок разрешение событий фронта или спада: Сперва включить нужный режим; затем почистить флаг INTF для данного события; затем проверить что реальное состояние сигнала соответствует ожидаемому. Вы ничего этого не делаете, поэтому у вас и работает криво. Даже в таймаутном алгоритме, включать регистрацию фронта или спада нужно именно таким способом. Это предохранит от неадекватного поведения программы, если в момент такого программирования, напряжение сигнала на ножке находится где-то возле порога переключения '0'/'1' цифрового входа.

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


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

4 часа назад, dOb сказал:

Я бы отказался от колбэков. Что в них происходит и как долго - неясно.

Лучше в прерываниях только собрать информацию и когда всё будет готово выставить флаг.

В main в бесконечном цикле или средствами ОС ловить этот флаг и обрабатывать принятую информацию.

У ТС сигналы довольно низкочастотные. Поэтому - чтобы не находилось в тех функциях, сама по себе длительность их выполнения (в пределах разумного конечно) не должна мешать. При частотах сигналов, заявленных ТС-ом (не более 1кГц), даже если те функции будут выполняться сравнительно долго (несколько десятков мкс) это не должно мешать работе программы. Но только если алгоритм обработки - корректный. А у ТС-а сам алгоритм кривой. В этом проблема.

При таких частотах сигналов, вполне возможно всё обрабатывать в ISR.

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


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

6 часов назад, dimka76 сказал:

Либо у вас в какой-то момент обработчик прерывания слишком долго обрабатывает прерывание и поэтому возникают пропуски.

Или наоборот, долгий запрет где-то в фоне...

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


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

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

Или наоборот, долгий запрет где-то в фоне...

Чтобы потеря событий произошла из-за этакого запрета, его длительность должна быть не менее минимальной длительности импульса сигнала. У ТСа минимальная длительность заявлена как = 366мкс. Неужто где-то такие длительные запреты есть?  :scratch_one-s_head:

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


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

On 2/14/2024 at 5:47 PM, jcxz said:

Неужто где-то такие длительные запреты есть?  :scratch_one-s_head:

По его осциллограммам - теряется шесть фронтов

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


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

18 часов назад, jcxz сказал:

Чтобы потеря событий произошла из-за этакого запрета, его длительность должна быть не менее минимальной длительности импульса сигнала. У ТСа минимальная длительность заявлена как = 366мкс. Неужто где-то такие длительные запреты есть?  :scratch_one-s_head:

Вам ли удивляться качеству многих, выкладываемых тут, исходников🙂 Не могу сказать ничего за ТС, ведь мы видим только то, что показывают.

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


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

On 2/14/2024 at 3:57 PM, jcxz said:

В любом случае

Благодарю за труд. Даже я понял. Единственный момент тут, я ещё не придумал, как в этом алгоритме обрабатывать значения регистра захвата. Получается если возникло "дребезговое" прерывание, мне всё равно нужно хранить значение захвата, а учесть его только когда случится прям "трушное" прерывание. При этом "дребезговых" может быть куча, и всю кучу значений нужно хранить до прихода "трушного".

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


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

46 минут назад, LAS9891 сказал:

Благодарю за труд. Даже я понял.

Не совсем полно описал. Не хватает пары пунктов. Уточняю:

Т.е. - после получения фронта - переход на п.1; после получения спада - переход на п.6.

  1. переключаете режим на регистрацию спада;
  2. чистите флаг события по данному каналу (в INTF);
  3. считываете реальное текущее значение на пине;
  4. проверяете наличие флага в INTF: если флаг есть - переход на п.2;
  5. Если с пина прочитан '0' - переход на п.6; если прочитан '1', то - переход на п.11 с результатом: pin=1;
  6. переключаете режим на регистрацию фронта;
  7. чистите флаг события по данному каналу (в INTF);
  8. считываете реальное текущее значение на пине;
  9. проверяете наличие флага в INTF: если флаг есть - переход на п.7;
  10. Если с пина прочитан '1' - переход на п.1; если прочитан '0', то - переход на п.11 с результатом: pin=0.
  11. Сравниваете текущий результат с предыдущим зафиксированным состоянием пина. Если они равны - выход из ISR без каких-либо действий.
  12. Если не равны: сохраняем новый результат как реальное зафиксированное значение пина. И выполняете все полезные действия, которые нужно сделать по фронту или спаду.

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

И никаких &= и |= ! Так можно делать только если все биты регистра имеют тип "r/w". Да и в этом случае лучше так не делать, так как неоптимально.

46 минут назад, LAS9891 сказал:

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

А что тут сложного? Если идёт дребезг, то новые захваты либо записываются поверх старых (затирая их) либо не сохраняются (сохраняется только первый захват). Но вам какая разница? Дребезг идёт короткое время, несущественное по сравнению с длительностью вашего сигнала. Получите длительность сигнала на несколько мкс больше или меньше - какая разница при сигнале ~1кГц?

Что именно произошло (спад или фронт или же вообще ничего, а была кратковременная иголка, которую нужно игнорировать) определяется в конечных п.11-п.12.

 

 

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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