Например TDA7294

РадиоКот > Статьи

ЭНКОДЕР +PIC16F628A

Автор: dock4, minichus@mail.ru
Опубликовано 14.11.2017.
Создано при помощи КотоРед.

ЭНКОДЕР +PIC16F628A

Намедни как то столкнулся с задачей управления энкодером исполнительного устройства. Самый доступный в продаже оказался энкодер с кнопкой ЕС11.
В интернете стал смотреть статьи с описанием этого прибора и примеры программ для его работы. Поскольку отдаю предпочтение микроконтроллерам Microchip , то интересовался именно программами для PIC ов. Хотя, нормальным программистам, без разницы на каком контроллере собирать устройство и писать программу. Но мне было «лениво» разбираться с АВРами, поэтому искал информацию для PIC ов и исходники написанные на языке Си. Есть несколько статей по решению данной задачи. Разбираясь в предоставленных исходниках я понял, что предложено, в основном, два варианта. В обоих вариантах используются прерывания с предварительным запоминанием начального состояния. В первом варианте автор «долбил» прерывание для постоянного опроса состояния ножек энкодера. Если произошло изменение состояния ножек, то в очередном прерывании определял направление и, в зависимости от этого направления, увеличивал или уменьшал значение своего регистра. После этого перезаписывал начальное состояние. Это действие нужно для того, чтобы при «долбёжном» прерывании смотреть, есть изменения или нет. Если нет изменения начального состояния, то просто выход из прерывания, ничего не делая. Во втором варианте автор тоже запоминает стартовое состояние. Но в прерывание входит по событию. Когда меняется логический уровень ножки с подключенным энкодером. В этом прерывании стартовая позиция сдвигается влево на несколько позиций и на места первых разрядов прописывается считываемое состояние энкодера. А после сравнивается со значением b11100001 или b11010010; если равно первому значению, то фиксируется сдвиг влево, во втором варианте-сдвиг вправо. Оба варианта рабочие. Но меня не устраивало обработка прерывания.. Поэтому решил обрабатывать ножки в основном цикле программы. Что такое энкодер? Если разобраться по факту, то это шестеренка с дырочками на валу. Между зубчиками стоит фиксатор. Мы слышим его работу в виде щелчков при повороте оси. Напротив дырок расположены два контакта. Если контакты попадают в дырки, то они проваливаясь замыкаются на массу. Условно эти контакты обозначим №1 и № 2. При повороте колесика в одну сторону вначале замыкается контакт №1, потом №2. В обратную сторону наоборот: №2 и потом №1. При повороте до щелчка контакты размыкаются. Для процессора ножки энкодера подтягиваем сопротивлениями к плюсу. Получается, что при разомкнутых контактах, через подтягивающие резисторы, на процессор поступает сигнал логической единицы. Это и будет наше стартовое условие. В программе мы будем проверять состояние только одного контакта. Не важно какого. Как только сработал один контакт( замкнул на массу) мы делаем маленькую задержку. Называется она задержка антидребезга. Потом снова смотрим  сигнал на этой ножке. Четкая фиксация состояния. И если событие произошло , то смотрим сигнал на второй ножке. Я уже выше писал, что при вращении ножки поочередно замыкаются на массу. Вот в этот момент сигнал на второй ножке нам дает информацию об направлении вращения. При фиксировании сигнала, например, увеличиваем какое то значение регистра. Если сигнала нет, то уменьшаем. Как это выглядит на примере:
                   if(Bt_1==0&&lk_1==0){ // если сработал контакт Bt_1 и бит защелки lk_1 равен 0
                   __delay_ms(2);              // задержка антидребезга и еще раз идем проверяеть контакт Bt_1
                  if(Bt_1==0&&Bt_2==0){ // есть срабатывание контакта Bt_1, смотрим сигнал контакта Bt_2
                                         lk_1 = 1; // это bit защелки, чтобы сработало условие проверки контакта Bt_1только один раз.

                                         ******   //если второй контакт сработал, то выполняем что-то на вычитание                   

                                                   } //


                  if(Bt_1==0&&Bt_2==1){ // есть срабатывание контакта Bt_1, смотрим контакт Bt_2, он не сработал.
                                       lk_1=1;
                                       ******    //если второй контакт не сработал, то выполняем что-то на увеличение.
                                                  } //
                                                  } // окончание обработки кнопок.
Из-за того, что мы выставили бит защелки, нет условия обработки сигналов кнопок и программа будет проскакивать этот фрагмент. Для возврата в исходное состояние нам нужно энкодер повернуть до щелчка, что означает размыкание двух контактов. Мы отслеживаем это событие и при его наступлении бит защелки lk_1устанавливаем в ноль. Достаточно проверять один контакт:
                  if(Bt_1==1&&lk_1==1)lk_1=0;

Хочу обратить внимание, что этот фрагмент кода нормально работает в основном цикле, в котором не злоупотребляют штатными задержками. 
Для проверки вышеизложенного материала мною собрана демо плата: Эта плата скорее игрушка, но она позволяет наглядно посмотреть работу энкодера. Я взял довольно распространенный процессор PIC16F628A .Тактовый внутренний генератор на 4 мГц .На весь порт «В» я подключил восемь светодиодов. При инициализации процессора я зажигаю самый старший светодиод. Это ножка RB7. По изложенной методике я обрабатываю ножки процессора к которым подключен энкодер. При вращении по часовой я сдвигаю зажигание светодиода от RB7 к RB0. И обратно. Такой «бегущий огонек». )) В программе я поставил условия, чтобы при дальнейшем прокручивании энкодера в ту или иную сторону светодиод оставался гореть в одном из крайних положений.
Для написания программы я пользовался MPLAB IDE v8.92 и HI-TECH 9.83
В приложении я выкладываю исходник на Си и сам исполняемый файл. Всем удачи!


Файлы:
исполняемый файл.
исходник на Си


Все вопросы в Форум.


ID: 2600