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

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

1 52 99

picmaniac: Зачем нам очередное учебное задание вообще - вот с чего следовало бы начать. Что мы желаем изучить?

Попробую высказаться. Лично для меня выполнение задания не является самоцелью! Мне, честно говоря, "до фонаря", какая там частота, какие допуски, сколько каналов, какие сигналы надо выдавать и в каких полярностях, на какой вывод подавать сигнал и с какого снимать, мигать там будет светодиод или просто гореть, и т. д.
Для меня все это просто необходимые АТРИБУТЫ для ВОЗМОЖНОСТИ обсуждать возможные алгоритмы. Это задание интересует меня в первую очередь с точки зрения одного: как измерять временные интервалы, как осуществлять сравнение измеренного с различными константами, как фиксировать и выводить результаты. Интересует все это не в общем плане, а конкретно, применительно к решению задачи на МК. Какие приемы здесь можно использовать, как лучше организовать опрос входов, запуск таймеров, проверку содержимого, нужно ли уходить в прерывания, какая требуется разрядность для обеспечения необходимой точности, как рациональнее всего составить программу, какие подводные камни, какие ошибки и заблуждения могут здесь подстерегать, ну и многое другое, касательно именно алгоритмов и написания программ.
Вот для чего мне нужно задание. Хочется обсуждения именно по сути вопроса.
А "препираться", сколько нам нужно каналов, какие там проценты, да как там светодиод должен мигать - все это конечно хорошо и необходимо для конкретного практического применения, но не является главным для учебного задания и для учебного процесса.

Если все это является важным для Splav56, ради бога, никаких возражений, давайте делать практически полезную задачу. Но я бы все-таки хотел тогда, чтобы были расписаны роли каждого, как в спектакле. А то получается, что все участники чего-то ждут друг от друга. Splav56 пишет ТЗ, picmaniac вставляет свои замечания, я тоже что-то "вякаю". Вроде бы все по-своему правы, все аргументируют свои возражения и замечания, а организованности нет. Посторонний человек будет читать все это - ведь обхохочется.
Я думаю так, если Splav56 предложил задание - ему и карты в руки. Остальным разрешается только уточнять у него какие-то нюансы. Ну и приступать наконец-то к той работе, ради которой мы тут собрались. Или я все-таки не прав и требуется еще обсуждений и утверждений, листов на несколько? Плохо что текст задания уплывает далеко из виду, его невозможно править, надо постоянно переписывать. Может разместить его где-нибудь в другом месте и там с ним издеваться, в смысле корректировать и обновлять?

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

 

Так, тупик все ближе и ближе. Пора внести ясность.

Есть пара предложений:

1. Создать отдельный топик для этой задачи. Это для того, чтобы не мешать АНТОХЕ и его оппонентам.

2. Я приберег эту задачу для себя и хотел ее решить при помощи С. Но тут возник вакуум в ветке про ASM и я решил подкинуть ее для решения а асме, чтобы потом сравнить полученные коды.

Сейчас у меня 90% времени занимает проект, который мы с приятелем выполняем на MikroBasic. Пока многое не получается (система реального времени), но мы понемногу движемся вперед (сказывается проблема времени: работать приходится урывками, в свободное от основной работы время..) Уже встроили преобразования от ADC. Поэтому прошу строго не судить, 90% мыслей там.
Работы осталось процентов на 30, после чего система будет выставлена на всеобщее обозрение и критику.

Прошу отнестись снисходительно к тому, что не могу 100% времени уделить текущему проекту и возложить (временно) функции координатора на другого участника ветки (например Zandy или picmaniac'a). Убедительная просьба от ТЗ сильно не отступать: 4-канала, 25 Гц, +/- 5%, +/-10%, индикация визуальная.

 

Попробуем алгоритм прикинуть...
Очевидно, что для таких частот информативнее измерять период.
Период всего 20ms. А возможная частота заполнения низкая.
Но с нас никто каждые 20ms новые данные не требует!.
И как говорил один известный человек: "Плюс,- это перечеркнутый минус"
Вот мы и перечеркнем. Мы будем измерять период МНОГО РАЗ и усредним результат.
Например, для простоты получения результата (с делением в PIСе напряг) нужно мерять
16 (32) или другое число периодов. Тогда потребное деление заменяется простым сдвигом вправо. И еще фокус в том, что коэффициент деления НЕ ОБЯЗАТЕЛЬНО будет равен количеству усредненных периодов.
Другими словами, мы должны измерять интервал времени равный последовательным (хотя и не обязательно) 8(16,32)текущим периодам. Тогда один из возможных вариантов, - это многобайтный инкримент в основном цикле. А в прерывании подсчет прошедших периодов входной частоты.

 

Splav56: возложить (временно) функции координатора на другого участника ветки (например Zandy или picmaniac'a)
Вот такая вот "википедия".

 

Не присоединился.

62039.doc

 

Из тех обрывочных советов по организации подсчета длительности периода (нескольких периодов) так и не понял, как же лучше все это организовать.
Как опрашивать вывод порта? Делать цикл с опросом и анализом прихода перепада из 0 в 1 или из 1 в 0? При приходе одного перепада запускать счетчик подсчета длительности и счетчик количества перепадов? Проверять счетчик количества перепадов, и при его обнулении считывать число в счетчике длительности? Так или нет? Как уходить в прерывание для обработки получившегося числа? Опять ассинхронно, по таймеру?
Другой вариант. Использовать прерывание по входному сигналу. Здесь непонятно. Сигналов то 4, прерывания будут возникать по любому из них. А нам надо обрабатывать все 4 последовательно. Как это сделать?
Третий вариант. Использование аппаратного таймера для подсчета длительностей. Но нам ведь его разрядности может не хватить. Наращивать? А смысл?
И еще, я все-таки не понял, что будет, если по входу импульс вообще не придет? Вечный цикл?
chav1961 высказазал путь к решению "Проще сделать опрос порта по сигналам таймера. Будет там импульс - не будет импульс, дело десятое". Но я что-то плохо уловил смысл сказанного. Это как? Какая разница, как опрашивать порт, в каком-то цикле или по сигналам таймера? Все равно же мы должны зафиксировать логический перепад? Может контролировать состояние счетчика длительности в цикле и при его переполнении прекращать опрос входа?
А также непонятен "внутренний" критерий выбора количества периодов подсчета. Если мало, показания будут дергаться, если много, инерционность увеличится. По-моему для этой задачи, где точность не требуется, можно и один период анализировать?
Еще. А что будет, если входная частота находится на границе двух диапазонов измерения? Не нужна ли здесь какая-то зона нечувствительности? Иначе светодиод, от цикла к циклу будет себя вести непотребно?
Короче, одни вопросы.
Пока не пойму, как это в принципе делается, даже в самом грубом приближении, граф рисовать не могу.

И все-таки предлагаю разрабатывать программу по кусочкам. Первый маленький кусочек - измерение частоты (длительности) одного входного сигнала с сохранением результата в промежуточном регистре. Кто за? Кто против?

 

Ух, Zandy разошёлся не на шутку!

задание интересует меня в первую очередь с точки зрения одного: как измерять временные интервалы, как осуществлять сравнение измеренного с различными константами, как фиксировать и выводить результаты. Интересует все это не в общем плане, а конкретно, применительно к решению задачи на МК. Какие приемы здесь можно использовать... Вот теперь мне всё ясно. Примерно так рассуждал и я, когда начинал PIC осваивать. Т.е. предлагается поменьше внимания уделять общим вопросам, и побольше - конкретным приёмам программирования. ОК, буду впредь это учитывать.
Теперь по устройству № 4. Прежде чем окончательно составим и утвердим техзадание (я всё-таки буду его именно так называть), предлагаю посмотреть на этот рисунок:
http://www.pic16.nm.ru/likbez1/drawing1.gif

На рисунке я попытался наглядно изобразить некоторые особенности работы нашего девайса.
Что мы тут видим? Прежде всего то, что необходимо измерять длительность как минимум одного периода - целиком. Измерением только длительности импульса или только длительности паузы здесь отделаться нельзя. Видим, что началом измерительного интервала может быть момент, когда произошло изменение уровня на входе, и при этом на нём появилась лог.1. С этого момента начинаем подсчёт импульсов.
Момент, когда произошло изменение уровня на входе, и при этом на нём появился лог.0 - это спад импульса на входе, но это не окончание измерительного интервала.
Момент, когда произошло изменение уровня на входе, и при этом на нём снова появилась лог.1 - это и есть конец одного периода и начало следующего. В этот момент следует считать и сохранить число прошедших импульсов заполнения, и немедленно начать новый отсчёт.
Затем желательно усреднить результат, как уже было сказано до меня. Т.е. подсчитать число импульсов за 8, 16, 32 и т.д. периодов, а затем найти среднее арифметическое.

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

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

Насчёт обработки сигналов с нескольких входов я ещё подумаю.

Кстати, чисто на всякий случай ;) скважность - это отношение длительности периода следования импульсов к длительности импульса.

 

picmaniac, спасибо за подробное объяснение и картинку. Но как раз с этим-то все понятно. Т. е. общий подход ясен, неясна реализация в программном виде.

picmaniac: Момент, когда произошло изменение уровня на входе, и при этом на нём снова появилась лог.1 - это и есть конец одного периода и начало следующего. В этот момент следует считать и сохранить число прошедших импульсов заполнения, и немедленно начать новый отсчёт.
Почему нельзя сразу считать в течении нескольких периодов (8), а потом применить команду сдвига? Вот, как я тут писал.
Zandy: При приходе одного перепада запускать счетчик подсчета длительности и счетчик количества перепадов? Проверять счетчик количества перепадов, и при его обнулении считывать число в счетчике длительности?
Ну, а по поводу дребезга Splav56 писал же, что "трением пренебрегаем". Можно решить эту проблемму и аппаратными средствами, например компаратор с ПОС (триггер Шмитта). Конечно, корошо бы еще и программно подстраховаться. Я так понимаю, можно применить тот же способ, что и с кнопками. Ну или проще, типа двух опросов через задержку. Правда задержка, наверное будет вносить погрешность? Опять же, хорошо, если помеха случайная, можно и пропустить один - два периода, а если она систематическая, и возникает всегда? Все это хорошо, но это отдельная заморочка. Может будем пользоваться приемом президента, "отделяя мух от котлет"?
picmaniac: скважность - это отношение длительности периода следования импульсов к длительности импульса.
Ну конечно, в задании там 1 на 2 надо поправить.

 

Zandy: Почему нельзя сразу считать в течении нескольких периодов Да в принципе можно и так... Просто если каждый период отдельно импульсами заполнять, то при той же разрядности таймера-счётчика их частоту можно сделать побольше, что повысит точность.
неясна реализация в программном виде Мне она тоже пока не вполне ясна. Будем думать... Вот и пытаюсь постепенно разобраться - чего конкретно мы хотим от контроллера в этой задаче? Перевести потом наши требования в код будет не так уж сложно.
приемом президента Я пропустил выборы?

 

picmaniac: Просто если каждый период отдельно импульсами заполнять, то при той же разрядности таймера-счётчика их частоту можно сделать побольше, что повысит точность.
Но ведь тогда потребуется куча регистров, куда все эти отсчеты по периодам складировать. Потом сумма, а для этого все равно будет нужен многобайтовый регистр. Ну и деление (сдвиг) тоже многобайтового числа. Или можно как то по-другому?