Свежие обсуждения
Микроконтроллеры

Ликбез по программированию PIC

1 56 99

ИМХО гистерезис желателен. Всё упирается опять же в программную реализацию... в общем, подумаем и над этим.

 

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: А в прерывания мы входим как раз по каждому фронту и спаду на любом из входов... Даже если изменение на входе произошло в процессе обработки прерывания
Вот мы все о входе да о входе в прерывания. А с выходом то как? Мы же в нем занимаемся подсчетом периода. Выход-то мы осуществляем программно (он у нас аппаратно не привязан к фронту), и даже если мы сбросили флаг прерывания в начале прерывания и в процессе прерывания этот флаг снова поднялся и после выхода из прерывания мы войдем в него снова, такое прерывание уже не будет привязано к фронту импульса.