Оглавление:

Как определить направление вращения цифрового поворотного переключателя с помощью PIC: 5 шагов
Как определить направление вращения цифрового поворотного переключателя с помощью PIC: 5 шагов

Видео: Как определить направление вращения цифрового поворотного переключателя с помощью PIC: 5 шагов

Видео: Как определить направление вращения цифрового поворотного переключателя с помощью PIC: 5 шагов
Видео: Уроки Arduino. Работа с энкодером 2024, Июль
Anonim
Как интерпретировать направление вращения цифрового поворотного переключателя с помощью PIC
Как интерпретировать направление вращения цифрового поворотного переключателя с помощью PIC

Цель данного руководства - показать, как соединить цифровой (квадратурно-кодированный) поворотный переключатель с микроконтроллером. Не волнуйтесь, я объясню, что для нас означает квадратурная кодировка. Этот интерфейс и сопутствующее программное обеспечение позволят микроконтроллеру распознавать направление вращения для каждого движения от одного фиксатора к другому. Недавно я использовал этот тип переключателя в проекте микроконтроллера, который требовал, чтобы заданное значение давления вводилось с помощью ручки с 16 фиксаторы вместо кнопок вверх / вниз. Идея заключалась в том, чтобы позволить пользователю «набрать» желаемое давление. В результате нам пришлось разработать программную процедуру для получения информации о положении от переключателя и определения направления вращения для увеличения или уменьшения уставки давления для основной системы. В этом руководстве я расскажу о физическом интерфейсе. к микроконтроллеру, теорию работы поворотного переключателя, теорию работы программного обеспечения, а также процедуру вывода. Наконец, я покажу вам свое применение процедуры дедукции. По мере продвижения я постараюсь сделать вещи несколько общими, чтобы идею можно было применить на как можно большем количестве платформ, но я также поделюсь своими действиями, чтобы вы могли увидеть конкретное приложение.

Шаг 1: Детали

Запчасти
Запчасти

Для этого вам понадобятся: Поворотный переключатель (квадратурная кодировка) Подтягивающие резисторы Подходящая платформа микроконтроллера Для своего проекта я использовал оптический энкодер Grayhill 61C22-01-04-02. В техническом описании поворотного переключателя указаны подтягивающие резисторы 8,2 кОм на двух линиях передачи данных, идущих от переключателя. Вы захотите проверить таблицу данных для кодировщика, который вы решите использовать. Поворотный переключатель, который я использовал, также можно заказать с осевым кнопочным переключателем. Это полезная функция для фиксации сделанного выбора и т. Д., Но я не буду здесь обсуждать ее интерфейс. У меня есть «подходящая платформа микроконтроллера», потому что (я думаю) это может быть реализовано на нескольких платформах. Я видел много людей, использующих другие микроконтроллеры для Instructables, поэтому я также хочу показать общий подход. Я написал весь код на PIC Basic Pro для использования с Microchip PIC16F877A. На самом деле, главное, что вам нужно в микроконтроллере, - это возможность прерывания при изменении логики на любом из двух контактов. На PIC16F877A это называется прерыванием изменения PORTB. На других контроллерах для него могут быть другие названия. Эта функция прерывания микроконтроллера является частью того, что делает эту реализацию такой элегантной.

Шаг 2: аппаратный интерфейс

Аппаратный интерфейс
Аппаратный интерфейс

«Простым» решением было бы иметь переключатель «однополюсный 16-позиционный» с 16 подключениями к микроконтроллеру. Затем каждый выход переключателя будет привязан к выводу на микроконтроллере, чтобы микроконтроллер мог проверить каждое положение шкалы. Это чрезмерное использование контактов ввода / вывода. Ситуация становится еще хуже, если мы хотим, чтобы на переключателе было доступно более 16 позиций (фиксаторов). Каждое дополнительное положение переключателя потребует дополнительного входа в микроконтроллер. Это быстро становится очень неэффективным использованием входов на микроконтроллере. Воспользуйтесь преимуществами поворотного переключателя. У поворотного переключателя есть только два выхода на микроконтроллер, указанные как A и B в техническом описании. Эти линии могут принимать только четыре возможных логических уровня: AB = 00, 01, 10 и 11. Это значительно сокращает количество входных линий, которые вы должны использовать для подключения переключателя к микроконтроллеру. Итак, мы сократили количество входных строк до двух. Что теперь? Похоже, нам действительно нужно 16 различных состояний, но у этого нового переключателя их всего четыре. Мы прострелили себе ногу? Неа. Читать дальше. Чтобы объяснить, мы рассмотрим немного теории, лежащей в основе работы поворотного переключателя.

Шаг 3: Аппаратная теория работы

Аппаратная теория работы
Аппаратная теория работы
Аппаратная теория работы
Аппаратная теория работы
Аппаратная теория работы
Аппаратная теория работы

Определение направления вращения возможно с использованием вышеупомянутого переключателя «однополюсный-16-ходовой», но он использует много входов на микроконтроллере. Использование поворотного переключателя уменьшает количество входов в микроконтроллер, но теперь нам нужно интерпретировать сигналы, поступающие от переключателя, и переводить их в направление вращения. Ранее я упоминал, что переключатель был закодирован квадратурной кодировкой. Это также одна из ключевых элегантностей данного решения. Это означает, что переключатель дает 2-битный код, который соответствует положению переключателя. Вы можете подумать: «Если на микроконтроллер вводятся два бита, как нам представить все 16 позиций?» Это хороший вопрос. Мы не представляем их всех. Нам просто нужно знать относительное положение ручки, чтобы мы могли определить направление вращения. Абсолютное положение ручки значения не имеет. При вращении по часовой стрелке код, который дает переключатель, повторяется каждые четыре фиксатора и отображается серым цветом. Кодировка серым цветом означает, что при каждом изменении позиции происходит только одно изменение бита. Вместо того, чтобы считать вход AB для вращения по часовой стрелке в двоичном формате, например: 00, 01, 10, 11, он изменяется следующим образом: 00, 10, 11, 01. Обратите внимание, что для последнего шаблона существует только один вход, изменяющийся между наборы. Значения против часовой стрелки для входа AB в микроконтроллер будут выглядеть следующим образом: 00, 01, 11, 10. Это просто обратный паттерну по часовой стрелке с AB = 00, указанным первым. Взгляните на диаграммы для более наглядного объяснения..

Шаг 4: Теория работы программного обеспечения

Теория работы программного обеспечения
Теория работы программного обеспечения

Программа, которая определяет направление вращения, управляется прерыванием. Выбранный вами микроконтроллер должен иметь возможность прерывания в любое время, когда происходит изменение на одном из (как минимум) двух выводов, когда прерывание разрешено. Это называется прерыванием изменения PORTB на PIC16F877A. Каждый раз, когда переключатель вращается, микроконтроллер будет прерван, и выполнение программы будет отправлено в процедуру обработки прерывания (ISR). ISR быстро определит, в какую сторону был повернут переключатель, установит соответствующий флаг и быстро вернется в основную программу. Нам нужно, чтобы это происходило быстро, если пользователь очень быстро поворачивает переключатель. Мы знаем, что шаблон AB с серой кодировкой повторяется каждые четыре положения, поэтому, если мы сделаем рутинную работу для переходов между этими четырьмя положениями, она будет работать для всех остальных. Обратите внимание, что в одном четырехпозиционном цикле есть четыре ребра. Нарастающий и спадающий фронт для входа A и входа B. Микропроцессор будет прерываться каждый раз, когда появляется край, что означает, что микроконтроллер будет прерываться при каждом повороте ручки. В результате ISR должен выяснить, в какую сторону была повернута ручка. Чтобы помочь нам понять, как это сделать, мы обратимся к форме волны для вращения по часовой стрелке. Обратите внимание, что каждый раз, когда A имеет ребро, его новое значение всегда отличается от значения B. Когда ручка переходит из положения 1 в положение 2, A переходит с логического 0 на логическую 1. B по-прежнему равен 0 для этого перехода и не соответствует новому значению A. Когда ручка переходит из положения 3 в 4, A имеет спад, а B остается на уровне логической 1. Еще раз обратите внимание, что B и новое значение A отличаются. Прямо сейчас мы видим, что каждый раз, когда A вызывает прерывание во время вращения по часовой стрелке, его новое значение отличается от значения B. Давайте проверим B, чтобы увидеть, что происходит. B имеет нарастающий фронт, когда переключатель переходит из положения 2 в 3. Здесь новое значение B такое же, как у A. Если посмотреть на последний оставшийся фронт для вращения по часовой стрелке, B имеет спадающий фронт, перемещающийся из положения 4 в 5. (Позиция 5 такая же, как позиция 1.) Новое значение B здесь такое же, как и у A! Теперь мы можем сделать некоторые выводы! Если A вызывает прерывание и новое значение A отличается от значения B, вращение было по часовой стрелке. Вдобавок, если B вызывает прерывание и новое значение B такое же, как A, то вращение было по часовой стрелке. Давайте быстро рассмотрим случай вращения против часовой стрелки. Как и при вращении по часовой стрелке, вращение против часовой стрелки вызовет четыре прерывания за один цикл: два для входа A и два для входа B. Вход A имеет передний фронт, когда ручка перемещается из положения 4 в 3, и задний фронт, перемещающийся из положения 2 в 1. Когда ручка перемещается из положения 4 в 3, новое значение A совпадает со значением B. Обратите внимание, что когда A перемещается из положения 2 в 1, его новое значение также совпадает с значением B. Теперь мы можем видеть, что когда A вызывает прерывание и его новое значение совпадает со значением B, вращение было против часовой стрелки. Мы быстро посмотрим на ввод B, чтобы все проверить. B вызовет прерывание, когда ручка переместится из положения 5 (которое совпадает с 1) в 4, и когда ручка переместится из положения 3 в 2. В обоих этих случаях новое значение B не соответствует существующему значению. A, что противоположно случаю, когда B вызывает прерывание для вращения по часовой стрелке. Это хорошие новости. Подводя итог, если A вызывает прерывание и его новое значение не соответствует значению B, или если B вызывает прерывание, а новое значение B совпадает со значением A, мы знаем, что было вращение по часовой стрелке. Мы можем проверить другие случаи вращения против часовой стрелки в программном обеспечении или предположить, что, поскольку это не вращение по часовой стрелке, оно было против часовой стрелки. Мой распорядок просто сделал предположение.

Шаг 5: Программное обеспечение

Программное обеспечение
Программное обеспечение
Программное обеспечение
Программное обеспечение

Я не использовал встроенные прерывания в PIC Basic Pro. Я использовал пару файлов, которые я включил в свой код от Даррела Тейлора, чтобы управлять рутиной. Именно здесь Даррелу принадлежит огромная заслуга! Файлы бесплатны. Просто посетите его веб-сайт для получения дополнительной информации, других приложений и загрузки файлов. Вы можете пропустить эту часть, если не используете PIC с прерываниями Даррела Тейлора. Просто настройте прерывания по мере необходимости на используемой вами платформе. Чтобы настроить прерывания Даррела Тейлора (DT), нужно сделать две вещи: 1.) Включите файлы DT_INTS-14.bas и ReEnterPBP.bas в ваш code.2.) Скопируйте и вставьте это в свой код. макрос ASMINT_LIST; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _ISR, PBP, yes endm INT_CREATEENDASMВставьте табуляции и пробелы, такие как рисунок в конце Instructable, чтобы вам было легче увидеть вещи в своем коде. Вам нужно будет немного изменить его, чтобы он соответствовал вашим потребностям. В разделе «Метка» замените ISR на имя подпрограммы, которая является вашей ISR. Не забывайте подчеркивание! Вам это нужно! Чтобы прерывания работали, нужно сделать еще две вещи: 1) Записать ISR. Вы напишете это так же, как вы собирались написать подпрограмму PBP, за исключением того, что вам нужно будет вставить @ INT_RETURN в конце подпрограммы вместо RETURN. Это подтвердит прерывание и вернет выполнение программы туда, где оно было остановлено в основном цикле. Внутри ISR вам необходимо сбросить флаг прерывания, чтобы ваша программа не попала в рекурсивное прерывание. Простое чтение PORTB - это все, что нужно сделать, чтобы сбросить флаг прерывания на PIC16F877A. Каждый микроконтроллер имеет свой способ сброса флагов прерывания. Проверьте лист данных для вашего микроконтроллера. 2.) Когда вы дойдете до точки в коде, где вы хотите включить прерывание, используйте эту строку кода: @ INT_ENABLE RBC_INT Если вы хотите отключить прерывание, просто используйте: @ INT_DISABLE RBC_INT Там много материала, упакованного в то, что я только что рассмотрел, поэтому я быстро резюмирую. Пока ваша программа должна выглядеть примерно так:; Любая необходимая настройка или код. ВКЛЮЧАЙ "DT_INTS-14.bas" ВКЛЮЧАЙ макрос "ReEnterPBP.bas" ASMINT_LIST; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _myISR, PBP, да endm INT_CREATEENDASM; Любая другая необходимая настройка или код @ INT_ENABLE RBC_INT; Код, который должен знать, в какую сторону вращается ручка @ INT_DISABLE RBC_INT; Другой кодEND; Конец программы. Теперь нам нужно написать ISR, чтобы микроконтроллер знал, в какую сторону вращается ручка. Вспомните из раздела теории программного обеспечения, что мы можем определить направление вращения, если мы знаем вход, вызвавший прерывание, его новое значение и значение другого входа. Вот псевдокод: Считайте PORTB в рабочую переменную, чтобы очистить флаг прерывания. Проверьте, не вызвал ли A прерывание. Если истина, сравните A и B. Проверьте, различаются ли, если различаются. Было ли вращение по часовой стрелке. Иначе, было против часовой стрелки. Endif. Проверьте, не вызвал ли B прерывание. Если истина, сравнить A и B Проверить, отличаются ли они, если одинаковы, Это было вращение по часовой стрелке Иначе, Это было против часовой стрелки EndifReturn from interrupt Как узнать, вызвало ли прерывание изменение в A или B? Обнаружить новое значение измененного ввода и другого (неизменного) ввода легко, потому что мы можем прочитать их внутри ISR. Нам нужно знать, в каком состоянии был каждый из них до того, как исполнение будет отправлено в ISR. Это происходит в основном распорядке. Основная процедура сидит и ждет, пока байтовая переменная, которую мы назвали CWflag, будет установлена в 1 или сброшена в 0 с помощью ISR. После каждого подтвержденного изменения ручки или при отсутствии активности ручки переменная устанавливается на 5, чтобы указать состояние ожидания. Если флаг установлен или сброшен, основная процедура немедленно увеличивает или уменьшает заданное давление в соответствии с вращением, а затем устанавливает переменную CWflag обратно на 5, потому что ручка теперь снова находится в режиме ожидания. Поскольку основная процедура проверяет CWflag, она также документирует состояние значений поворотного переключателя A и B. Это действительно просто и выглядит так: oldA = AoldB = B Здесь действительно нет ничего сверхъестественного. Просто включите эти две строки в начало цикла, который проверяет CWflag на вращение. Мы просто обновляем логические значения входов от поворотной ручки внутри цикла увеличения / уменьшения в основной программе, чтобы мы могли видеть, какой вход вызвал прерывание при выполнении ISR. Вот код ISR: ABchange: scratch = PORTB 'Прочтите PORTB, чтобы очистить флаг прерывания' Если A вызывает прерывание, проверьте направление вращения B IF oldA! = A THEN 'Если A и B разные, это было вращение по часовой стрелке IF A! = B THEN GOTO CW 'В противном случае это было вращение против часовой стрелки ELSE GOTO CCW ENDIF ENDIF' Если B вызывает прерывание, проверьте направление вращения A IF oldB! = B THEN 'Если A и B одинаковы, это было вращение по часовой стрелке IF A == B THEN GOTO CW 'В противном случае это было вращение против часовой стрелки ELSE GOTO CCW ENDIF ENDIFCW: CWflag = 1 @ INT_RETURNCCW: CWflag = 0 @ INT_RETURN Я включил код ISR в файл AB_ISR.bas, потому что вкладки в коде отображаются не так, как должны. Теперь, поскольку ISR имеет старые значения для входов A и B, он может определить, какой вход вызвал прерывание, сравнить его с другим (неизменным) входом и определить направление вращения. Все, что нужно сделать, это проверить CWflag, чтобы увидеть, в каком направлении повернулась ручка (если есть), и увеличить или уменьшить счетчик, заданное значение или что-то еще, что вам нравится или нужно. Я надеюсь, что это помогает, и не было слишком сбивает с толку. Этот тип интерфейса особенно полезен, если ваша система уже использует прерывания, поскольку это всего лишь еще одно прерывание, которое нужно добавить. Наслаждаться!

Рекомендуемые: