dimka76 61 14 февраля Опубликовано 14 февраля · Жалоба On 2/14/2024 at 10:00 AM, LAS9891 said: Просто картинка сделана когда пропусков прерываний не было. Лучше поймать момент именно когда пропуски есть, а то так не информативно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 14 февраля Опубликовано 14 февраля · Жалоба 12 minutes ago, dimka76 said: Лучше поймать момент именно когда пропуски есть, а то так не информативно. Такой момент хер поймаешь. Это не подтверждает пропуски? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 14 февраля Опубликовано 14 февраля · Жалоба Искать надо там где потерял, а не там где лучше видно. Вроде это очевидно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 61 14 февраля Опубликовано 14 февраля · Жалоба On 2/14/2024 at 10:18 AM, LAS9891 said: Такой момент хер поймаешь. Это не подтверждает пропуски? Подтверждает. Но дело не в этом, а в поиске причины. Либо у вас в какой-то момент обработчик прерывания слишком долго обрабатывает прерывание и поэтому возникают пропуски. Это как раз бы измерение длительности обработки прерывания и показало бы. Либо из-за пологих фронтов прерывание вообще не срабатывает. Либо что-то другое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 14 февраля Опубликовано 14 февраля · Жалоба 2 minutes ago, VladislavS said: Вроде это очевидно. Тут многим очевидно, и многим видно, что код - говнокод. Жду первого, кто расскажет очевидное для всех, кроме меня, решение. 1 minute ago, dimka76 said: Это как раз бы измерение длительности обработки прерывания и показало бы. Типа надо было поймать пропуск прерывания и измерить длительность обработки предыдущего прерывания? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 61 14 февраля Опубликовано 14 февраля · Жалоба On 2/14/2024 at 10:23 AM, LAS9891 said: Типа надо было поймать пропуск прерывания и измерить длительность обработки предыдущего прерывания? Измерение у вас уже есть. Ничего больше добавлять не надо. Просто ловите пропуски (не знаю каким способом вы определяете , что пропуск был) и смотрите импульсы длительности обработки прерывания. Может быть, если есть доступные ножки, добавить еще какой вспомогательный вывод, чтобы однозначно детектировать пропуск. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dOb 10 14 февраля Опубликовано 14 февраля (изменено) · Жалоба 1 час назад, LAS9891 сказал: код - говнок Я бы отказался от колбэков. Что в них происходит и как долго - неясно. Лучше в прерываниях только собрать информацию и когда всё будет готово выставить флаг. В main в бесконечном цикле или средствами ОС ловить этот флаг и обрабатывать принятую информацию. Изменено 14 февраля пользователем dOb Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 14 февраля Опубликовано 14 февраля · Жалоба 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' цифрового входа. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 14 февраля Опубликовано 14 февраля · Жалоба 4 часа назад, dOb сказал: Я бы отказался от колбэков. Что в них происходит и как долго - неясно. Лучше в прерываниях только собрать информацию и когда всё будет готово выставить флаг. В main в бесконечном цикле или средствами ОС ловить этот флаг и обрабатывать принятую информацию. У ТС сигналы довольно низкочастотные. Поэтому - чтобы не находилось в тех функциях, сама по себе длительность их выполнения (в пределах разумного конечно) не должна мешать. При частотах сигналов, заявленных ТС-ом (не более 1кГц), даже если те функции будут выполняться сравнительно долго (несколько десятков мкс) это не должно мешать работе программы. Но только если алгоритм обработки - корректный. А у ТС-а сам алгоритм кривой. В этом проблема. При таких частотах сигналов, вполне возможно всё обрабатывать в ISR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 14 февраля Опубликовано 14 февраля · Жалоба 6 часов назад, dimka76 сказал: Либо у вас в какой-то момент обработчик прерывания слишком долго обрабатывает прерывание и поэтому возникают пропуски. Или наоборот, долгий запрет где-то в фоне... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 14 февраля Опубликовано 14 февраля · Жалоба 29 минут назад, Arlleex сказал: Или наоборот, долгий запрет где-то в фоне... Чтобы потеря событий произошла из-за этакого запрета, его длительность должна быть не менее минимальной длительности импульса сигнала. У ТСа минимальная длительность заявлена как = 366мкс. Неужто где-то такие длительные запреты есть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dimka76 61 14 февраля Опубликовано 14 февраля · Жалоба On 2/14/2024 at 5:47 PM, jcxz said: Неужто где-то такие длительные запреты есть? По его осциллограммам - теряется шесть фронтов Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 178 15 февраля Опубликовано 15 февраля · Жалоба 18 часов назад, jcxz сказал: Чтобы потеря событий произошла из-за этакого запрета, его длительность должна быть не менее минимальной длительности импульса сигнала. У ТСа минимальная длительность заявлена как = 366мкс. Неужто где-то такие длительные запреты есть? Вам ли удивляться качеству многих, выкладываемых тут, исходников🙂 Не могу сказать ничего за ТС, ведь мы видим только то, что показывают. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LAS9891 0 16 февраля Опубликовано 16 февраля · Жалоба On 2/14/2024 at 3:57 PM, jcxz said: В любом случае Благодарю за труд. Даже я понял. Единственный момент тут, я ещё не придумал, как в этом алгоритме обрабатывать значения регистра захвата. Получается если возникло "дребезговое" прерывание, мне всё равно нужно хранить значение захвата, а учесть его только когда случится прям "трушное" прерывание. При этом "дребезговых" может быть куча, и всю кучу значений нужно хранить до прихода "трушного". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 16 февраля Опубликовано 16 февраля · Жалоба 46 минут назад, LAS9891 сказал: Благодарю за труд. Даже я понял. Не совсем полно описал. Не хватает пары пунктов. Уточняю: Т.е. - после получения фронта - переход на п.1; после получения спада - переход на п.6. переключаете режим на регистрацию спада; чистите флаг события по данному каналу (в INTF); считываете реальное текущее значение на пине; проверяете наличие флага в INTF: если флаг есть - переход на п.2; Если с пина прочитан '0' - переход на п.6; если прочитан '1', то - переход на п.11 с результатом: pin=1; переключаете режим на регистрацию фронта; чистите флаг события по данному каналу (в INTF); считываете реальное текущее значение на пине; проверяете наличие флага в INTF: если флаг есть - переход на п.7; Если с пина прочитан '1' - переход на п.1; если прочитан '0', то - переход на п.11 с результатом: pin=0. Сравниваете текущий результат с предыдущим зафиксированным состоянием пина. Если они равны - выход из ISR без каких-либо действий. Если не равны: сохраняем новый результат как реальное зафиксированное значение пина. И выполняете все полезные действия, которые нужно сделать по фронту или спаду. Такая последовательность действий гарантирует, что в п.11 вы будете иметь реальное текущее значение пина с правильно запрограммированным режимом фронт/спад. Т.е. - сперва переключаете режим пина по алгоритму выше, и только затем выполняете полезные действия, которые нужно сделать по фронту или спаду. И никаких &= и |= ! Так можно делать только если все биты регистра имеют тип "r/w". Да и в этом случае лучше так не делать, так как неоптимально. 46 минут назад, LAS9891 сказал: Единственный момент тут, я ещё не придумал, как в этом алгоритме обрабатывать значения регистра захвата. Получается если возникло "дребезговое" прерывание, мне всё равно нужно хранить значение захвата, а учесть его только когда случится прям "трушное" прерывание. При этом "дребезговых" может быть куча, и всю кучу значений нужно хранить до прихода "трушного". А что тут сложного? Если идёт дребезг, то новые захваты либо записываются поверх старых (затирая их) либо не сохраняются (сохраняется только первый захват). Но вам какая разница? Дребезг идёт короткое время, несущественное по сравнению с длительностью вашего сигнала. Получите длительность сигнала на несколько мкс больше или меньше - какая разница при сигнале ~1кГц? Что именно произошло (спад или фронт или же вообще ничего, а была кратковременная иголка, которую нужно игнорировать) определяется в конечных п.11-п.12. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться