Длительность периода в реальном времени

Обсуждаем контроллеры компании Atmel.
Ответить
Собутыльник Кота
Аватара пользователя
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Сообщение B@R5uk »

В одной из задач возникла необходимость измерять длительность временного промежутка между повторяющимися событиями в реальном времени. Для этого планирую использоваться таймер с функцией захвата. Однако возникла следующая проблема: длительность измеряемого временного промежутка может быть больше, чем полный счёт таймера от 0 до 65535. Разумное решение — сделать программное расширение таймеру, но тогда возникает другая проблема: момент фиксации времени события (осуществляемый таймером автоматически) и момент чтения этого времени (аппаратной части и программной) отличаются. Между этими двумя моментами времени может произойти переполнение таймера, в результате программная и аппаратная части временного штампа события окажутся рассинхронизированы.

Наверняка, я не первый кто с этой проблемой сталкивался, подскажите, пожалуйста, какие есть варианты решения. Заранее очень благодарен.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск

Сообщение pyzhman »

Использовать прерывание при переполнении. Количество_прерываний * 65536 + TCNTx.
Docendo discimus
Контактная информация:
Реклама
Грызет канифоль
Сообщения: 289
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Сообщение viiv »

B@R5uk,
Мои рассуждения: Приоритет CAPTURE выше чем OVERFLOW (все AVRы не просматривал, на mege8 так), т.е
1) если влетели в ОVEFLOW, инкрементируем программный счетчик и выходим из обработчика.
2) если влетели в CAPTURE, читаем ICR, читаем Overflow Flag (флаг переполнения). Если флаг переполнения не стоит, то проблем нет. Если флаг переполнения стоит, то возникает неопределенность о которой Вы говорите (если я правильно понял), но она легко решается: если считанный ICR "болшой", то CAPTURE возникло до переполнения, если "маленький", то после переполнения, которое еще не обработано.
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

viiv, что означает "большой" или "маленький" ? Это "сколько в граммах" ? :)
Единственное решение при неатомарных ситуациях - запрет другим потокам модифицировать данные. В данном случае - это останов таймера на время его чтения. Потеряются некоторые такты, но зато вероятность нарваться на неприятности сводится к нулю.
Есть ещё вариант. Поле чтения таймера, прочитать флаг его переполнения. Если он взведён (переполнение было) - сбрасываем его (чтобы не влететь в overflow) и прибавляем к считанному значению 65536.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2406
Зарегистрирован: Ср фев 23, 2011 12:12:31

Сообщение AndTer »

Насколько нужна точность измерения? А если просто уменьшить частоту таймера? Т.е. те же 65535 будут набираться гораздо дольше, ровно во столько, во сколько будет ниже частота.
Глупый не задает вопросы. Глупый и так все знает.
Реклама
Грызет канифоль
Сообщения: 289
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Сообщение viiv »

Аlex писал(а):viiv, что означает "большой" или "маленький" ? Это "сколько в граммах" ? :)
В предельном случае сравнить c 0x8000.
Аlex писал(а): В данном случае - это останов таймера на время его чтения.
останавливать таймер незачем.
Аlex писал(а): Есть ещё вариант. Поле чтения таймера, прочитать флаг его переполнения. Если он взведён (переполнение было) - сбрасываем его (чтобы не влететь в overflow) и прибавляем к считанному значению 65536.
Я про это и писал, только просто добавть 65536 нельзя, так как при установленном флаге переполнения, это самое переполнение могло возникнуть как до CAPTURE так и после.
Реклама
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Немного не допонял проблему в вопросе и поторопился с ответом. Оказывается, используют аппаратный захват.
B@R5uk, у Вас проблема надуманная, которой, на самом деле, не существует. Вы говорите о двух взаимоисключающих вещах.
Если вызвалось прерывание от события по захвату, а до этого не было прерывания по переполнению - значит переполнения вовсе не было, и можно смело читать захваченные данные и счётчик переполнений (он всё равно не обновится, пока мы не дойдём до обработчика переполнения). Если бы до захвата было переполнение таймера, Вы бы сначала влетели в обработку по переполнению, а потом уже по захвату.
Контактная информация:
Грызет канифоль
Сообщения: 289
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Сообщение viiv »

Аlex писал(а): Если бы до захвата было переполнение таймера, Вы бы сначала влетели в обработку по переполнению, а потом уже по захвату.
ИМХО это не верно. 1) прерывания могут быть запрещены, например, работает дгугой обработчик. Если при запрещенных прерываниях произошло два события (И CAPTURE и ОVRFLOW), то при разрешении прерываний вызовется обработчик с бОльшим приоритетом(CAPTURE), не зависимо от того, какое событие было раньше.
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Если бы у бабки был ... А если упадёт метеорит на МК, то он вообще не сможет ничего обрабатывать :)
Если знаем о такой проблеме, то нужно как то не допускать её возникновения, т.б. - стараться не запрещать в программе прерывания.

ЗЫ: Сравнение с 0x8000 - неудачное решение. Вы предлагаете все значения до 0x8000 считать переполнением таймера ?
Контактная информация:
Грызет канифоль
Сообщения: 289
Зарегистрирован: Чт ноя 06, 2014 13:09:06

Сообщение viiv »

Аlex писал(а): Если знаем о такой проблеме, то нужно как то не допускать её возникновения, т.б. - стараться не запрещать в программе прерывания.
Мы же не знаем, что у ТС за задача. Может у него еще что-то работает. Что без прерываний с UART-ом и с другой переферией работать?
Да и в AVR не все команды выполняются за 1 такт, есть и 2-х тактовые и трехтактовый, и четырехтактовые. выполнение команды - атомарное, т.е. не может "разорваться" вызовом прерывания.
Так что в пределе эти два события (CAPTURE и OVF) могут возникнуть и во премя выполнения одной ассемблерной команды.
Аlex писал(а):ЗЫ: Сравнение с 0x8000 - неудачное решение. Вы предлагаете все значения до 0x8000 считать переполнением таймера ?
Да, при установленном бите переполнения таймера и считанном ICR<0x8000 считать, что событие CAPTURE произошло после переполнения таймера, которое еще не обработано.
О порогах можно подумать, может я чего не учел. Но разделить диапазон пополам пока сажется не таким уж плохим решением.

==============
ЗЫ. Уважаемый, Аlex, похоже топик-стартеру данный вопрос не очень-то интересен, так как никакой реакции от него нету. Идея озвучена, информации для размышления ТС есть. Бабушку с метеоритами обсуждать нет никакого желания.
Собутыльник Кота
Аватара пользователя
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Сообщение B@R5uk »

pyzhman писал(а):Использовать прерывание при переполнении. Количество_прерываний * 65536 + TCNTx.
Ну, это и называется программное расширение таймера. Со всеми вытекающими проблемами.
AndTer писал(а):Насколько нужна точность измерения? А если просто уменьшить частоту таймера?
Думал про это. К сожалению, точность фиксирована, а период при любой частоте гарантированно может оказаться длиннее цикла таймера.
Аlex писал(а):Единственное решение при неатомарных ситуациях - запрет другим потокам модифицировать данные. В данном случае - это останов таймера на время его чтения.
Весьма громкое утверждение. Хотя я тоже думал про остановку. Во-первых, по событию захвата таймер не останавливается, а именно в этот момент происходит чтение аппаратной части временного штампа (младших двух байт). К моменту обработки прерывания (или просто в цикле после проверки соответствующего флага), когда будет осуществляться чтение программной части временного штампа и появится возможность остановки таймера, уже может появиться рассинхрон. Во-вторых, ARV так устроена, что выключение таймера не выключает предделитель, который продолжает считать. В-третьих, отключение таймера приведёт к нарушению самого главного требования задачи — регистрации временных штампов событий в реальном времени.

Остальное почитал, требует осмысления. Я так понял единственная возможность решения проблемы — это положиться на приоритет прерываний?
viiv писал(а):Может у него еще что-то работает. Что без прерываний с UART-ом и с другой периферией работать?
Работа с USART есть. Вывод в цикле, а ввод придётся делать через прерывания. Цикл слишком длинный, чтобы закончить его обсчёт за время приёма двух байт подряд.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Два прерывания - захват и переполнение.

В обработчике переполнении счетчик переполнений инкрементируется .

В захвате:
1. Сброс счетчика.
2. Если захваченный счет небольшой (например если не установлен старший бит захваченных данных), то проверяется флаг переполнения. Если флаг переполнения установлен, инкрементируется счетчик переполнений.
3. Вычиляете фактическое значение периода (если почему то затрытный расчет, то считается в основной программе).
4. Сброс флаг переполнения и счетчика переполнений.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Собутыльник Кота
Аватара пользователя
Сообщения: 2896
Зарегистрирован: Сб ноя 13, 2010 12:53:25
Откуда: приходит весна?

Сообщение B@R5uk »

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

Суммируя то, что обсуждали Аlex и viiv. Возможны следующие варианты развития событий.
Вариант А
1) Событие захвата;
2) Обработка события захвата;
3) Событие переполнения;
4) Обработка события переполнения.
В этом случае результат получается правильный.

Вариант Б
1) Событие переполнения;
2) Обработка события переполнения;
3) Событие захвата;
4) Обработка события захвата.
В этом случае результат получается тоже правильный.

Вариант В
1) Событие захвата;
2) Событие переполнения;
3) Обработка события захвата;
4) Обработка события переполнения.
Произошло некоторое наложение, но результат получается правильный.

Вариант Г
1) Событие захвата;
2) Событие переполнения;
3) Обработка события переполнения;
4) Обработка события захвата.
Из-за накладки результат получается неправильный. Программная часть временного штампа на единицу больше, чем надо.

Вариант Д
1) Событие переполнения;
2) Событие захвата;
3) Обработка события захвата;
4) Обработка события переполнения.
Как и в прошлом варианте результат получается неправильный. Но программная часть временного штампа на единицу меньше, чем надо.

Вариант Е
1) Событие переполнения;
2) Событие захвата;
3) Обработка события переполнения;
4) Обработка события захвата
Несмотря на накладку результат получается правильный.

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

Жаль, конечно, что проблема не имеет готового решения. Но надеюсь, что правильное решение планомерным подходом получится таки найти. Заранее спасибо всем участвующим за помощь.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

B@R5uk писал(а):сбрасывать счётчик не годится,
Значит не сбрасывайте, но флаг переполнения в обработчике захвата все равно надо также проверять. Предложенный мной алгоритм должен работать.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

B@R5uk писал(а):Вариант Г
1) Событие захвата;
2) Событие переполнения;
3) Обработка события переполнения;
4) Обработка события захвата.
Из-за накладки результат получается неправильный. Программная часть временного штампа на единицу больше, чем надо.
Этот вариант исключён.
Если событие захвата произойдёт раньше события переполнения, то программа по-любому сначала обработает захват, а потом уже переполнение.

А вот вариант Д:
B@R5uk писал(а): 1) Событие переполнения;
2) Событие захвата;3) Обработка события захвата;
4) Обработка события переполнения.
Как и в прошлом варианте результат получается неправильный. Но программная часть временного штампа на единицу меньше, чем надо.
вполне возможен. И ничего с этим не поделаешь.

Берите другой проц, у которого есть, как минимум, 2 приоритета. Тогда, повесив переполнение на старший приоритет, Вы исключите ошибку.

Добавлено after 6 minutes 3 seconds:
Z_h_e писал(а):но флаг переполнения в обработчике захвата все равно надо также проверять
Нельзя этого делать.
Если событие захвата произойдёт до переполнения, то, проверкой на переполнение в событии захвата, вы прибавите лишние 65536 попугаев.
Это тоже самое, что предложил viiv - проверять на 0x8000. Но то предложение, конечно же, ещё глупее...
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Аlex писал(а):Нельзя этого делать.
Если событие захвата произойдёт до переполнения, то...
Можно и нужно. Обратите внимание на важную составляющую алгоритма - проверка флага, если захваченные данные меньше половины максимума счетчика.

Но скорректировать алгоритм надо, сброс флага переполнения нужно делать не всегда, а только если захваченные данные также меньше половины. Это из-за того что счетчик не надо сбрасывать.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

А, дак речь идёт о проверке уже захваченного значения. А я всё думаю, причём тут значение счётчика :)
Тогда да, какая то доля правды в этом есть... :roll:
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Аlex писал(а):Тогда да, какая то дол правды в этом есть... :roll:
А по мне - алгоритм полностью рабочий и решает задачу ТС. По крайней мере я не вижу адекватной ситуации, при которой он работать не будет.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

Да, похоже, действительно, рабочий.

ЗЫ: Всем плюсики в карму, за хорошее решение :)))
Контактная информация:
akl
Друг Кота
Сообщения: 4450
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

B@R5uk писал(а):...Наверняка, я не первый кто с этой проблемой сталкивался, подскажите, пожалуйста, какие есть варианты решения.
Как вариант - вырезка из старого проекта решавшего аналогичную задачу. Если ешё актуально.
TEST_CAPT_OVER.asm
Ответить

Вернуться в «AVR»