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

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

1 53 99

Пишешь-пишешь ТЗ, пишешь-пишешь, а его оказывается даже не читают! В ТЗ же черным по белому написано, цитирую:

6. Входной сигнал: импульсная последовательность положительной полярности уровня ТТЛ и скважностью 0,1.

В дальнейшем была устранена опИска про скважность: скважность равна не 0,1, а 10.

А тут опять вдруг вылезает синусоида.

А насчет помех: например сигнал идет с индуктивного датчика, выдающего импульсы положительной полярности амплитудой ок. 50 вольт, по витой экранированной паре прямо на плату устройства, где они формируются при помощи диодного формирователя и ограничителя до уровня ТТЛ. Формирователь-ограничитель установлен непосредственно на входе м/к. Частота повторения импульсов - 25Гц. В таких условиях никаких внешних помех на входе м/к не будет. Вполне реальный случай. Поэтому и предложено помехами пренебречь.

 

Splav56: черным по белому написано Я, конечно, дико извиняюсь. Нарисовал так для наглядности. Скважность 10 на рисунке смотрелась бы некрасиво. Техзадание читал многократно. Мы же его ещё не утвердили окончательно. Обещаю в дальнейшем исправиться!
А вот и дополненнный рисунок (упс, пока что с синусоидой): http://www.pic16.nm.ru/likbez1/drawing2.gif

Продолжаю анализировать работу девайса. Пока рассматриваю один вход для упрощения. Помеху пока тоже не рассматриваю.
Регистр таймера условно обозначу просто TMR, пока без номера. Таймер непрерывно инкрементируется от тактового генератора с требуемой достаточно высокой частотой (пока мы её точно не определили).

В момент А уровень на входе изменился с 0 на 1. Происходит прерывание по этому изменению. В обработчике мы выясняем, что прерывание произошло именно по этому входу (забегаю вперёд). Это делается путём сравнения сохраненных предыдущих значений уровней на входах с текущими.
Далее выясняем, что на входе лог.1. Значит, это фронт. Для того, чтоб подсчитать число импульсов заполнения от предыдущего фронта до текущего, вычисляем:
RESULT := TMR (считать текущее значение таймера)
W := TMRTEMP (это предыдущее значение таймера, сохраненное ранее)
RESULT := RESULT - W [ = TMR - TMRTEMP (получили искомое число импульсов) ]
W := RESULT + W [ = TMR - W + W = TMR (восстановили то значение, которое мы считали из таймера) ]
TMRTEMP := W (и сохранили это новое значение)

В результате этих преобразований получаем в регистре RESULT число импульсов за временной интервал от фронта до фронта, а в регистре TMRTEMP - новое значение таймера, которое было считано из регистра TMR. Считывать из самого регистра TMR следует лишь единожды!
Замечание: частота импульсов заполнения должна быть такой, чтоб их не прошло более 255 за самый длинный из допустимых измерительных интервалов от фронта до фронта (в случае 8-разрядного таймера). Не выше.
После выхода из обработчика в регистре RESULT содержится вожделенное число импульсов за один период. В основной программе с этим числом уже можно работать дальше - усреднять за несколько периодов и т.п.

В момент В уровень на входе изменился с 1 на 0. Происходит прерывание по этому изменению. Опять же выясняем, что именно по этому входу. На входе лог.0, значит - спад. Тут вроде как делать ничего не нужно.

В момент С действуем точно так, как в момент А.
В момент D действуем точно так, как в момент B.
И так далее.

Прошу анализировать мои предложения и критиковать. А я пока ещё подумаю...

 

Splav56, вы не против того, как я "испохабил" ваше ТЗ? Сами ж разрешили.
Я просто подумал, что к непрерывному свечению ближе частое мигание светодиода. Ну, в смысле интерпретаций градаций измерения: горит - часто мигает - мигает редко.
Синусоиду, picmaniac нарисовал, я так понимаю, для того чтобы представить задачку, так сказать, в общем виде. Думаю, что и решать ее лучше тоже для широкого круга применений, т. е. использовать наиболее типовое решение. Мало ли, где еще такая штука может пригодиться. Хотя, в принципе для данного ТЗ хватило бы измерения одной единственной паузы между стробами.
А вопрос дребезга - интересный вопрос, хоть в ТЗ он и не затронут. Я предлагаю заняться им, но позже, после выполнения основного задания. Лично для меня здесь и так головоломок хватает.

 

Извините, что встреваю.
Вроде в PIC16F6xx есть модуль захвата/сравнения? Он же специально заточен на измерение временнЫх интервалов, и притом 16-разрядный....
Правда, 4 канала не получится... Зато точность будет - недостижимая другими средствами.

 

А если в каждом прерывании не проделывать математических операций TMR - TMRTEMP, а предусмотреть регистр - счетчик количества обнулений таймера и счетчик количества прерываний настроенный, например на 8. После 8-и прерываний проделываем "математику", а в регистре - счетчике количества обнулений таймера окажется старший байт искомого числа имппульсов за 8 периодов. Останется сделать циклический сдвиг и "готов" усредненный результат?

А если в первом прерывании обнулять TMR, то совсем просто получается. После 8 периодов (прерываний) в TMR будет "в чистом виде" младший байт искомого числа импульсов.

 

Zandy: Splav56, вы не против того, как я "испохабил" ваше ТЗ? Сами ж разрешили.

Не против, т.к. я эти изменения даже не видел. У меня Ваш аттач, если изменения там, не скачивается.

picmaniac: Прошу анализировать мои предложения и критиковать.

Особых замечаний нет. Единственный вопрос может возникнуть при многоканальной работе в случае синфазности сигналов. Тогда понадобятся приоритеты.

AHTOXA: Извините, что встреваю.
Вроде в PIC16F6xx есть модуль захвата/сравнения? Он же специально заточен на измерение временнЫх интервалов, и притом 16-разрядный....
Правда, 4 канала не получится... Зато точность будет - недостижимая другими средствами.

Да встревайте на здоровье!
Хочется сделать именно многоканальную систему, причем суперточность не слишком важна, поэтому ССР в этом варианте не задействовать.

 

Zandy: А если в каждом прерывании не проделывать математических операций TMR - TMRTEMP, а предусмотреть регистр - счетчик количества обнулений таймера и счетчик количества прерываний настроенный, например на 8. После 8-и прерываний проделываем "математику", а в регистре - счетчике количества обнулений таймера окажется старший байт искомого числа имппульсов за 8 периодов. Останется сделать циклический сдвиг и "готов" усредненный результат?

Это будет правильным только в том случае, если таймер считает от 0 до FF, без перезагрузки. Если это устраивает, то можно и так.

 

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

Что-то не въехал, поподробнее пож-ста. Почему 8 прерываний (прерывания по изменению уровня на входе происходят как по фронту, так и по спаду), это будет соответствовать трем с половиной периодам. А как учесть то, что в момент восьмого прерывания в таймере будет остаток, зависящий от частоты входного сигнала. А это снизит точность измерения. Или я чего-то не понял.

 

Splav56: (прерывания по изменению уровня на входе происходят как по фронту, так и по спаду)
Холостые не в счет.
Splav56: в момент восьмого прерывания в таймере будет остаток, зависящий от частоты входного сигнала.
Так это и будет младший байт, если в первом прерывании TMR был обнулен. Старший в том счетчике количества переполнений таймера
AHTOXA: только в том случае, если таймер считает от 0 до FF, без перезагрузки.
Что значит "без перезагрузки"?
Splav56: У меня Ваш аттач, если изменения там, не скачивается.
Вот он еще в текстовом виде.

62121.txt

 

Zandy: Что значит "без перезагрузки"

Если Вы, для изменения периода таймерных прерываний, не заносите в начале прерывания в TMR какое-нибудь значение, отличное от 0.