|
|
|
|
ИМХО гистерезис желателен. Всё упирается опять же в программную реализацию... в общем, подумаем и над этим. |
|
|
picmaniac: Из этих 62 мс примерно 45 мс ждём изменения уровня на входе. Да, здесь я "маху дал". 62 мс - мало. Ну, увеличим его до 125 мс, например. С обработкой в прерываниях меня почему-то все-таки несколько смущает случайный порядок входа в прерывание. А если входной сигнал, например по двум каналам синхронен? А потом, длительность обработки каждого прерывания будет разная для разных частот. Как же нам точно выдерживать временные соотношения "мигалок". В моем варианте, при последовательной обработке каналов все времена будут жестко нормированы, поэтому и легко "встроить" в общий цикл "мигалки". А по поводу некоторого бесполезно затраченного времени (ожидание фронта сигнала), ну и что страшного? Не на пожар торопимся. Все равно, человеческая реакция на изменение свечения светодиода будет гораздо более долгой. В конце концов, можно усреднять не по 8, а по 4 отсчетам, тогда и реакция системы будет быстрее. А "фиксация" фронта и сам опрос можно очень быстро производить. Ошибка будет небольшая и систематическая, поэтому это не страшно. |
|
|
Так, для лучшего понимания попробую изобразить эту идею графически: http://www.pic16.nm.ru/likbez1/drawing3.gif Предупреждение - рисунок широкий, 1560 пикс. Zandy, правильно нарисовано? |
|
|
АНТОХА: Пришло прерывание от изменения уровня - выяснили от какого сигнала - записали длительность (разность между текущим TMR и предыдущим по этому каналу) Сразу надо предусмотреть,например, случаи: а) все фронты от 4-х датчиков пришли ОДНОВРЕМЕННО б) Для определенности: Занесение(отметка) данных в программе по очередности номеров датчиков. Тогда сработал сначала 4-й а затем (сразу, после принятия в этой пробе, что 1-3 не сработали), немедленно сработал, например, первый. Zandy: .. гистерезис... Естественно нужен. Полагаю, можно изначально задаться "максимальной шириной спектр. линии" с нашего датчика и принять, например, удвоенное значение. Хорошая задачка..
|
|
|
А теперь попробую изобразить возможный вариант решения через прерывания по изменению уровня на входах: http://www.pic16.nm.ru/likbez1/drawing4.gif 
Примечание: физически происходит непрерывное инкрементирование одного регистра таймера (условно назову его TMR). Но для наглядности я нарисовал импульсы заполнения 4 раза, чтоб удобнее было проследить процесс для каждого входа. В моменты, обозначенные точками, происходит вычисление периода для каждого входа (из текущего значения таймера вычитается значение, которое было при предыдущем фронте на этом входе, подробнее см. выше). Разная высота импульсов - также для наглядности. |
|
|
picmaniac: Zandy, правильно нарисовано? Ну да, нарисовано правильно. Только в варианте с прерываниями у вас нарисовано так, как будто все 4 канала одновременно обрабатываются. На самом-то деле в данный момент времени может обрабатываться только один канал. Ну и в прерывания тоже ведь не по каждому фронту входим. Конец периода будет находиться внутри прерывания, т. к. по нему происходит фиксация длительности. |
|
|
RB4 и RB5 выдали одновременно запрос на прерывание. Мы же можем обработать их только последовательно. Кому отдадим приоритет? |
|
|
Почему только последовательно? Входим в обработчик, считываем порт в промежуточный регистр - вот нам и одномоментный опрос входов. Считываем таймер в промежуточный регистр - вот и "поймали" момент для всех входов сразу. А далее уже анализируем каждый вход отдельно. Если определили, что прошёл фронт на RB4 - берем число из промежуточного регистра, куда сохранили значение таймера, вычитаем из него заранее сохранённое значение в момент предыдущего фронта (TMRTEMP4) - вот и период на RB4. Сохраним его в RESULT4. Аналогично для других входов. При возникновении прерывания от любого входа мы анализируем сразу все входы. Если был фронт на входе - считаем период для этого входа, не было фронта - переходим к проверке следующего входа тут же. А в прерывания мы входим как раз по каждому фронту и спаду на любом из входов, а также по переполнению таймера тайм-аута. Даже если изменение на входе произошло в процессе обработки прерывания - после выхода по retfie немедленно произойдет повторный переход на обработку прерывания. Флаг-то RBIF сразу установится, как только изменение произошло, и не важно в какой момент оно произошло! Прерывания выявляются АППАРАТНО! в этом их преимущество. |
|
|
picmaniac: Входим в обработчик, считываем порт в промежуточный регистр - вот нам и одномоментный опрос входов. Сколько времени займет обработка прерывания? Где гарантия, что по другому входу в это время не придет запрос, который будет проигнорирован, т.к. у нас на время обработки этого прерывания все другие прерывания запрещены. А если частота стабильна, то все запросы, приходящие во время обработки с этого пина мы проигнорируем из-за их маскирования, т.е. получим ошибку. И будем при считывании порта В всегда иметь 0 с этого пина. PS: лучше файлы прикреплять или давать ссылку, иначе очень неудобно читать страницу. 
|
|
|
И все-таки здесь для меня есть много "темных пятен". Допустим мы наш счет длительности начинаем с положительного фронта. Смотрим на последний рисунок (picmaniacа). Допустим мы вошли в прерывание по положительному фронту RB6. Находясь в прерывании мы не знаем, по какому сигналу оно произошло. При опросе портов выясняется, что в данный момент и RB4 и RB5 и RB6 находятся в состоянии 1. Так от какого же сигнала произошло прерывание? Утверждение, что все три сигнала синфазны, будет неверно - RB6 опережает RB4 и RB5. picmaniac: А в прерывания мы входим как раз по каждому фронту и спаду на любом из входов... Даже если изменение на входе произошло в процессе обработки прерывания Вот мы все о входе да о входе в прерывания. А с выходом то как? Мы же в нем занимаемся подсчетом периода. Выход-то мы осуществляем программно (он у нас аппаратно не привязан к фронту), и даже если мы сбросили флаг прерывания в начале прерывания и в процессе прерывания этот флаг снова поднялся и после выхода из прерывания мы войдем в него снова, такое прерывание уже не будет привязано к фронту импульса.
|
|
|
|
|