Съдържание:

Как да тълкуваме посоката на въртене от цифров ротационен превключвател с PIC: 5 стъпки
Как да тълкуваме посоката на въртене от цифров ротационен превключвател с PIC: 5 стъпки

Видео: Как да тълкуваме посоката на въртене от цифров ротационен превключвател с PIC: 5 стъпки

Видео: Как да тълкуваме посоката на въртене от цифров ротационен превключвател с PIC: 5 стъпки
Видео: LDmicro 19: Rotary Encoder Menu Navigation (Microcontroller PLC Ladder Programming with LDmicro) 2024, Юли
Anonim
Как да тълкуваме посоката на въртене от цифров ротационен превключвател с PIC
Как да тълкуваме посоката на въртене от цифров ротационен превключвател с PIC

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

Стъпка 1: Части

Части
Части

За да приложите това, ще ви трябва: Ротационен превключвател (квадратурно кодиран) Издърпайте нагоре резистори Подходяща платформа за микроконтролер За моя проект използвах оптичен енкодер Grayhill 61C22-01-04-02. Информационният лист за ротационния превключвател изисква 8.2k ohm издърпващи резистори на двете линии за данни, идващи от превключвателя. Ще искате да проверите информационния лист за кодера, който решите да използвате. Ротационният превключвател, който използвах, може да се поръча и с аксиален бутон. Това е полезна функция за извършване на избрани селекции и т.н., но няма да обсъждам интерфейса му тук. Имам "подходяща платформа за микроконтролер" в списъка, защото (мисля) това може да се приложи на повече от една платформа. Виждал съм много хора, използващи други микроконтролери за Instructables, така че искам да покажа и общия подход. Написах целия код в PIC Basic Pro за използване с Microchip PIC16F877A. Наистина, ключовото нещо, от което се нуждаете на микроконтролера, е способността да прекъсвате, когато има логическа промяна на някой от двата пина. На PIC16F877A това се нарича прекъсване на промяната на PORTB. Може да има други имена за него на други контролери. Тази функция за прекъсване на микроконтролера е част от това, което прави това изпълнение толкова елегантно.

Стъпка 2: Хардуерен интерфейс

Хардуерен интерфейс
Хардуерен интерфейс

"Просто" решение би било да има превключвател "един полюс-16 хвърляне" с 16 връзки към микроконтролера. След това всеки изход на превключвателя ще бъде свързан към щифт на микроконтролера, така че всяка позиция на набиране може да бъде проверена от микроконтролера. Това е прекомерна употреба на I/O щифтове. Нещата стават още по -лоши, ако искаме повече от 16 позиции (детенти) на разположение на превключвателя. Всяко допълнително положение на превключвателя ще изисква допълнителен вход към микроконтролера. Това бързо се превръща в много неефективно използване на входове на микроконтролер. Въведете красотата на въртящия се превключвател. Ротационният превключвател има само два изхода към микроконтролера, изброени като A и B в информационния лист. Има само четири възможни логически нива, които тези линии могат да поемат: AB = 00, 01, 10 и 11. Това значително намалява броя на входните линии, които трябва да използвате за свързване на превключвателя към микроконтролера. И така, намалихме броя на входните редове до само два. Сега какво? Изглежда, че наистина се нуждаем от 16 различни състояния, но този нов превключвател има само четири. Застреляли ли сме се в крака? Не. Четете нататък. Ще обясним малко от теорията зад операцията на въртящия се превключвател.

Стъпка 3: Хардуерна теория на работа

Хардуерна теория на работа
Хардуерна теория на работа
Хардуерна теория на работа
Хардуерна теория на работа
Хардуерна теория на работа
Хардуерна теория на работа

Отчитането на посоката на въртене е възможно с помощта на гореспоменатия превключвател "single pole-16 throw", но той използва много входове на микроконтролера. Използването на въртящ се превключвател намалява броя на входовете към микроконтролера, но сега трябва да интерпретираме сигналите, идващи от превключвателя, и да ги преведем в посока на въртене. Споменах по -рано, че превключвателят е квадратурно кодиран. Това също е един от ключовите елементи в това решение. Това означава, че има 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 са различни. Точно сега можем да видим, че всеки път, когато А причинява прекъсването по време на въртене по часовниковата стрелка, новата му стойност е различна от тази на 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. Сега можем да видим, че когато А причинява прекъсването и новата му стойност съвпада с тази на В, въртенето е обратно на часовниковата стрелка. Бързо ще разгледаме вход Б, за да проверим всичко. B ще предизвика прекъсване, когато копчето се премести от позиция 5 (което е същото като 1) на 4 и когато копчето се премести от позиция 3 в 2. И в двата случая новата стойност на B не съответства на съществуващата стойност на A, което е обратното на случаите, когато B причинява прекъсване за въртене по часовниковата стрелка. Това е добра новина. Всичко се проверява както трябва. За да обобщим, ако А причинява прекъсването и новата му стойност не съответства на стойността на В или ако В причинява прекъсването и новата стойност на В съвпада със стойността на А, ние знаем, че е имало въртене по часовниковата стрелка. Можем да проверим другите случаи за въртене обратно на часовниковата стрелка в софтуера или можем да приемем, че тъй като не е въртене по часовниковата стрелка, то е обратно на часовниковата стрелка. Моята рутина просто направи предположението.

Стъпка 5: Софтуер

Софтуер
Софтуер
Софтуер
Софтуер

Не използвах вградените прекъсвания в PIC Basic Pro. Използвах няколко файла, които включих в кода си от Даръл Тейлър, за да управлявам рутината. Тук е огромна заслуга на Даръл! Файловете са безплатни. Просто посетете уебсайта му за повече информация, други приложения и за изтегляне на файловете. Можете да пропуснете тази част, ако не използвате PIC с прекъсвания на Darrel Taylor. Просто настройте прекъсванията според нуждите на платформата, която използвате. За да настроите прекъсванията на Darrel Taylor (DT), трябва да направите две неща: 1.) Включете файловете DT_INTS-14.bas и ReEnterPBP.bas във вашия code.2.) Копирайте и поставете това във вашия код. ASMINT_LIST макрос; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _ISR, PBP, да endm INT_CREATEENDASI Вмъкване на раздели и интервали като графиката в края на Instructable, така че да виждате нещата малко по -лесно във вашия код. Ще трябва да го промените леко, за да отговаря на вашите нужди. Под Label заменете ISR с името на подпрограмата, която е вашият ISR. Не забравяйте долната черта! Имате нужда! За да накарате прекъсванията да работят, трябва да направите още две неща: 1.) Напишете ISR. Ще напишете това точно както щяхте да напишете подпрограма PBP, с изключение на това, че ще трябва да вмъкнете @ INT_RETURN в края на подпрограмата вместо RETURN. Това ще потвърди прекъсването и ще върне изпълнението на програмата там, където е спряло в основния цикъл. В ISR трябва да изчистите флага за прекъсване, така че програмата ви да не бъде уловена в рекурсивно прекъсване. Простото четене на PORTB е всичко, което трябва да се направи, за да се изчисти флагът за прекъсване на PIC16F877A. Всеки различен микроконтролер има различен начин за изчистване на флаговете на прекъсванията. Проверете информационния лист за вашия микроконтролер. 2.) Когато стигнете до точката във вашия код, която искате да разрешите прекъсването, използвайте този ред код:@ INT_ENABLE RBC_INT Когато искате да деактивирате прекъсването, просто използвайте:@ INT_DISABLE RBC_INT Има много неща, опаковани в това, което току -що покрих, така че ще обобщя бързо. Досега програмата ви трябва да изглежда така:; Всяка необходима настройка или код INCLUDE "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; Край на programmyISR:; ISR код тук@ INT_RETURN (Таблица за настройка на манипулатор на прекъсвания) Мисля, че тук всеки, който не използва PIC или DT прекъсвания, може да се присъедини отново. Сега трябва действително да напишем ISR, така че микроконтролерът да знае по какъв начин се върти копчето. Припомнете си от раздела теория на софтуера, че можем да изведем посоката на въртене, ако знаем входа, който е причинил прекъсването, новата му стойност и стойността на другия вход. Ето псевдокода: Прочетете PORTB в променлива за нула, за да изчистите флаг за прекъсване Проверете дали A е причинило прекъсването. Ако е вярно, сравнете A и B. Проверете дали е различно, ако е различно, Това е въртене по посока на часовниковата стрелка Друго, Това е EndifCheck обратно на часовниковата стрелка, ако B е причинило прекъсването. Ако е вярно, сравнете A и B Проверете дали е различно, ако е същото, Това е въртене по посока на часовниковата стрелка Друго, Това е обратно на часовниковата стрелка Endif Връщане от прекъсване Как да разберем дали промяна на 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 'В противен случай това е въртене обратно на часовниковата стрелка ОЩЕ GOTO CCW ENDIF ENDIF' Ако B причинява прекъсване, проверете A за посоката на въртене, ако е стараB! = B THEN 'Ако A и B са еднакви, то беше въртене по часовниковата стрелка, ако A == B ТОГАВА ОТЛИЧЕ CW 'В противен случай това беше въртене обратно на часовниковата стрелка ОЩЕ GOTO CCW ENDIF ENDIFCW: CWflag = 1@ INT_RETURNCCW: CWflag = 0@ INT_RETURNI включихме ISR кода във файл AB_ISR.bas, защото разделите в кода не се показват по начина, по който трябва. Сега, тъй като ISR има старите стойности за входове A и B, той може да определи кой вход е причинил прекъсването, да го сравни с другия (непроменен) вход и да определи посоката на въртене. Всичко, което трябва да направите, е да проверите CWflag, за да видите в коя посока се е завъртяло копчето (ако има) и да увеличите или намалите брояч, зададена точка или каквото искате или имате нужда. Надявам се, че това помага и не е било твърде объркващо. Този тип интерфейс е особено полезен, ако вашата система вече използва прекъсвания, тъй като това е само още едно прекъсване за добавяне. Наслади се!

Препоръчано: