Cuprins:

Cum se interpretează direcția de rotație de la un comutator rotativ digital cu un PIC: 5 pași
Cum se interpretează direcția de rotație de la un comutator rotativ digital cu un PIC: 5 pași

Video: Cum se interpretează direcția de rotație de la un comutator rotativ digital cu un PIC: 5 pași

Video: Cum se interpretează direcția de rotație de la un comutator rotativ digital cu un PIC: 5 pași
Video: DS4 2023 2024, Noiembrie
Anonim
Cum se interpretează direcția de rotație de la un comutator rotativ digital cu un PIC
Cum se interpretează direcția de rotație de la un comutator rotativ digital cu un PIC

Obiectivul acestui instructabil este de a ilustra modul de interfață a unui comutator rotativ digital (codat în cuadratură) cu un microcontroler. Nu vă faceți griji, vă voi explica ce înseamnă pentru noi codratul în cuadratură. Această interfață și software-ul însoțitor îi vor permite microcontrolerului să recunoască direcția de rotație pentru fiecare mișcare de la o detenție la alta. oprește în loc de butoane sus / jos. Ideea a fost de a permite utilizatorului să „formeze” presiunea dorită. Ca urmare, a trebuit să dezvoltăm o rutină software pentru a obține informațiile de poziție de pe comutator și pentru a deduce direcția de rotație pentru a crește sau a micșora punctul de setare a presiunii pentru sistemul principal. În acest manual, voi acoperi interfața fizică la microcontroler, teoria funcționării pentru comutatorul rotativ, teoria funcționării software-ului, precum și rutina de deducere. În cele din urmă, vă voi arăta aplicarea rutinei de deducere. Pe măsură ce progresăm, voi încerca să păstrez lucrurile oarecum generice, astfel încât ideea să poată fi aplicată pe cât mai multe platforme posibil, dar vă voi împărtăși și ceea ce am făcut pentru a putea vedea o aplicație specifică.

Pasul 1: Piese

Părți
Părți

Pentru a implementa acest lucru, veți avea nevoie de: Un comutator rotativ (codat în cuadratură) Rezistențe de tragere Platforma de microcontroler adecvată Pentru proiectul meu, am folosit un codificator optic Grayhill 61C22-01-04-02. Fișa de date pentru comutatorul rotativ solicită rezistențe de tragere de 8,2 k ohm pe cele două linii de date care provin de la comutator. Veți dori să verificați foaia de date pentru codificatorul pe care alegeți să îl utilizați. Comutatorul rotativ pe care l-am folosit poate fi comandat și cu un buton axial. Este o caracteristică utilă pentru comiterea de selecții care au fost formate, etc., dar nu voi discuta aici despre interfața sa. Am o „platformă de microcontroler adecvată” listată pentru că (cred) aceasta poate fi implementată pe mai multe platforme. Am văzut mulți oameni care folosesc alte microcontrolere pentru Instructables, așa că vreau să arăt și abordarea generală. Am scris tot codul în PIC Basic Pro pentru a fi utilizat cu un microcip PIC16F877A. Într-adevăr, elementul cheie de care aveți nevoie la microcontroler este abilitatea de a întrerupe atunci când există o schimbare logică pe oricare dintre cei doi pini. Pe PIC16F877A, aceasta se numește întrerupere de modificare PORTB. Pot exista alte nume pentru aceasta pe alte controlere. Această caracteristică de întrerupere a microcontrolerului face parte din ceea ce face această implementare atât de elegantă.

Pasul 2: interfață hardware

Interfață hardware
Interfață hardware

O soluție „simplă” ar fi să ai un comutator „single pole-16 throw” cu 16 conexiuni la microcontroler. Fiecare ieșire a comutatorului ar fi legată apoi de un pin de pe microcontroler, astfel încât fiecare poziție a cadranului să poată fi verificată de microcontroler. Aceasta este o utilizare excesivă a pinilor I / O. Lucrurile se înrăutățesc chiar dacă vrem mai mult de 16 poziții (detenții) la dispoziția noastră pe comutator. Fiecare poziție suplimentară a comutatorului ar necesita o intrare suplimentară la microcontroler. Acest lucru devine rapid o utilizare foarte ineficientă a intrărilor pe un microcontroler. Introduceți frumusețea comutatorului rotativ. Comutatorul rotativ are doar două ieșiri către microcontrolerul listat ca A și B pe foaia de date. Există doar patru niveluri logice posibile pe care le pot lua aceste linii: AB = 00, 01, 10 și 11. Acest lucru reduce considerabil numărul de linii de intrare pe care trebuie să le utilizați pentru conectarea comutatorului la microcontroler. Deci, am redus numărul de linii de intrare la doar două. Acum ce? Se pare că avem într-adevăr nevoie de 16 stări diferite, dar acest nou comutator are doar patru. Ne-am împușcat în picior? Nu. Citiți mai departe. Vom acoperi un pic din teoria din spatele operației comutatorului rotativ pentru a explica.

Pasul 3: Teoria hardware a funcționării

Teoria operațiunii hardware
Teoria operațiunii hardware
Teoria operațiunii hardware
Teoria operațiunii hardware
Teoria operațiunii hardware
Teoria operațiunii hardware

Detecția direcției de rotație este posibilă folosind comutatorul „single pole-16 throw” menționat mai sus, dar folosește o mulțime de intrări pe microcontroler. Utilizarea comutatorului rotativ reduce numărul de intrări către microcontroler, dar acum trebuie să interpretăm semnalele care vin de la comutator și să le traducem într-o direcție de rotație. Aceasta este, de asemenea, una dintre eleganțele cheie ale acestei soluții. Aceasta înseamnă că există un cod de 2 biți pe care îl dă comutatorul, care corespunde poziției comutatorului. S-ar putea să vă gândiți: "Dacă există o intrare pe doi biți la microcontroler, cum reprezentăm toate cele 16 poziții?" Asta este o întrebare bună. Nu le reprezentăm pe toate. Trebuie doar să cunoaștem pozițiile relative ale butonului, astfel încât să putem determina direcția de rotație. Poziția absolută a butonului este irelevantă. Pentru rotația în sensul acelor de ceasornic, codul pe care îl dă comutatorul se repetă la fiecare patru detenții și este codat în gri. Codul gri înseamnă că există o singură modificare de biți pentru fiecare schimbare de poziție. În loc să se numere intrarea AB pentru rotația în sensul acelor de ceasornic în binar astfel: 00, 01, 10, 11, se schimbă astfel: 00, 10, 11, 01. Observați că pentru ultimul model, există o singură intrare care se schimbă între seturi. Valorile în sens invers acelor de ceasornic pentru intrarea AB la microcontroler vor arăta astfel: 00, 01, 11, 10. Acesta este pur și simplu inversul modelului în sensul acelor de ceasornic, cu AB = 00 listat mai întâi. Aruncați o privire la diagrame pentru o explicație mai vizuală..

Pasul 4: Teoria funcționării software-ului

Teoria funcționării software-ului
Teoria funcționării software-ului

Rutina care deduce direcția de rotație este întreruptă. Microcontrolerul pe care îl selectați trebuie să fie capabil să întrerupă oricând are loc o modificare pe oricare dintre (cel puțin) doi pini atunci când este activată întreruperea. Aceasta se numește întrerupere de modificare PORTB pe PIC16F877A. Ori de câte ori comutatorul este rotit, microcontrolerul va fi întrerupt și executarea programului va fi trimisă la rutina de întrerupere a serviciului (ISR). ISR va afla rapid în ce direcție a fost rotit comutatorul, va seta un semnalizator în mod corespunzător și va reveni rapid la programul principal. Avem nevoie ca acest lucru să se întâmple rapid în cazul în care utilizatorul roteste comutatorul foarte repede. Știm că modelul AB codat în gri se repetă la fiecare patru poziții, deci dacă facem rutina să funcționeze pentru tranzițiile între aceste patru poziții, acesta va funcționa pentru toate celelalte. Observați că într-un ciclu cu patru poziții, există patru muchii. O margine ascendentă și o margine descendentă pentru intrarea A, precum și intrarea B. Microprocesorul va fi întrerupt de fiecare dată când există o margine, ceea ce înseamnă că microcontrolerul va fi întrerupt de fiecare dată când butonul este rotit. Ca urmare, ISR trebuie să-și dea seama în ce direcție a fost rotit butonul. Pentru a ne ajuta să ne dăm seama cum să facem acest lucru, ne întoarcem la forma de undă pentru rotație în sensul acelor de ceasornic. Observați că, de fiecare dată când A are o margine, noua sa valoare este întotdeauna diferită de cea a lui B. Când butonul trece de la poziția 1 la 2, A trece de la logic-0 la logic-1. B este încă 0 pentru această tranziție și nu se potrivește cu noua valoare a lui A. Când butonul trece de la poziția 3 la 4, A are o margine descendentă în timp ce B rămâne la logica-1. Observați din nou că B și noua valoare a lui A sunt diferite. În acest moment, putem vedea că oricând A provoacă întreruperea în timpul rotației în sensul acelor de ceasornic, noua sa valoare este diferită de cea a lui B. Să verificăm B pentru a vedea ce se întâmplă. B are o margine ascendentă când comutatorul trece de la poziția 2 la 3. Aici, noua valoare a lui B este aceeași cu A. Privind la ultima margine rămasă pentru rotație în sensul acelor de ceasornic, B are o margine descendentă care se deplasează din poziția 4 la 5. (Poziția 5 este aceeași cu poziția 1.) Noua valoare a lui B este aceeași cu A și aici! Acum putem face câteva deduceri! Dacă A provoacă întreruperea și noua valoare a lui A este diferită de cea a lui B, rotația a fost în sensul acelor de ceasornic. În plus, dacă B provoacă întreruperea și noua valoare a lui B este aceeași cu A, atunci rotația a fost în sensul acelor de ceasornic. Să examinăm rapid cazul rotației în sens invers acelor de ceasornic. La fel ca rotația în sensul acelor de ceasornic, rotația în sens invers acelor de ceasornic va provoca patru întreruperi într-un ciclu: două pentru intrarea A și două pentru intrarea B. Intrarea A are o margine ascendentă atunci când butonul se deplasează din poziția 4 la 3 și o margine descendentă se deplasează din poziția 2 la 1 Când butonul se deplasează de la poziția 4 la 3, noua valoare a lui A este aceeași cu valoarea lui B. Observați că atunci când A se deplasează din poziția 2 la 1, noua sa valoare este aceeași cu cea a lui B. Acum, putem vedea că atunci când A provoacă întreruperea și noua sa valoare se potrivește cu cea a lui B, rotația a fost în sens invers acelor de ceasornic. Rapid, vom analiza intrarea B pentru a verifica totul. B va provoca o întrerupere când butonul se deplasează din poziția 5 (care este aceeași cu 1) în 4 și când butonul se deplasează din poziția 3 în 2. În ambele cazuri, noua valoare a lui B nu se potrivește cu valoarea existentă a lui A care este opusul cazurilor când B provoacă întreruperea pentru rotația în sensul acelor de ceasornic. Asta e o veste bună. Pentru a rezuma, dacă A provoacă întreruperea și noua sa valoare nu se potrivește cu valoarea lui B sau dacă B provoacă întreruperea și noua valoare a lui B se potrivește cu valoarea lui A, știm că a fost o rotație în sensul acelor de ceasornic. Putem verifica celelalte cazuri pentru rotație în sens invers acelor de ceasornic în software sau putem presupune că, deoarece nu a fost rotație în sensul acelor de ceasornic, a fost în sens invers acelor de ceasornic. Rutina mea a făcut pur și simplu presupunerea.

Pasul 5: Software

Software
Software
Software
Software

Nu am folosit întreruperile încorporate în PIC Basic Pro. Am folosit câteva fișiere pe care le-am inclus în codul meu de la Darrel Taylor pentru a conduce rutina. Aici aparține un credit imens pentru Darrel! Fișierele sunt gratuite. Doar vizitați site-ul său web pentru mai multe informații, alte aplicații și pentru a descărca fișierele. Puteți sări peste această parte dacă nu utilizați un PIC cu întreruperile Darrel Taylor. Configurați întreruperile după cum este necesar pe platforma pe care o utilizați. Pentru a configura întreruperile Darrel Taylor (DT), trebuie să faceți două lucruri de făcut: 1.) Includeți fișierele DT_INTS-14.bas și ReEnterPBP.bas în cod.2.) Copiați și lipiți acest lucru în codul dvs. Macro ASMINT_LIST; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _ISR, PBP, da endm INT_CREATEENDASM Introduceți file și spații precum graficul de la sfârșitul instructabilului, astfel încât să puteți vedea lucrurile puțin mai ușor în cod. Va trebui să-l modificați ușor pentru a se potrivi nevoilor dvs. Sub Etichetă, înlocuiți ISR cu numele subrutinei care este ISR-ul dvs. Nu uitați de subliniere! Ai nevoie de el! Pentru ca întreruperile să funcționeze, mai sunt două lucruri de făcut: 1.) Scrieți ISR. Veți scrie acest lucru exact așa cum urmați să scrieți un subrutin PBP, cu excepția faptului că va trebui să introduceți @ INT_RETURN la sfârșitul subrutinei în loc de RETURN. Acest lucru va confirma întreruperea și va întoarce execuția programului în locul în care a rămas în bucla principală. În interiorul ISR, trebuie să ștergeți semnalizatorul de întrerupere, astfel încât programul dvs. să nu fie prins într-o întrerupere recursivă. Simpla citire PORTB este tot ce trebuie făcut pentru a șterge semnalizatorul de întrerupere de pe PIC16F877A. Fiecare microcontroler diferit are un mod diferit de a șterge semnalizatoarele de întrerupere. Verificați foaia de date pentru microcontrolerul dvs. 2.) Când ajungeți la punctul din codul în care doriți să activați întreruperea, utilizați această linie de cod: @ INT_ENABLE RBC_INT Când doriți să dezactivați întreruperea pur și simplu utilizați: @ INT_DISABLE RBC_INT Există multe de lucruri împachetate în ceea ce tocmai am acoperit, așa că voi rezuma rapid. Până în prezent, programul dvs. ar trebui să arate cam așa:; Orice set sau cod necesar INCLUDE "DT_INTS-14.bas" INCLUDE "ReEnterPBP.bas" ASMINT_LIST macro; IntSource, Label, Type, ResetFlag? INT_Handler RBC_INT, _myISR, PBP, yes endm INT_CREATEENDASM; Orice alt set sau cod necesar @ INT_ENABLE RBC_INT; Cod care trebuie să știe în ce direcție se rotește butonul @ INT_DISABLE RBC_INT; Alt codEND; Sfârșitul programului ISR:; cod ISR aici @ INT_RETURN (Tabel de configurare a manipulării întreruperii) Cred că acesta este locul în care oricine nu utilizează întreruperi PIC sau DT se poate alătura din nou. Acum, trebuie să scriem ISR-ul, astfel încât microcontrolerul să știe în ce direcție se rotește butonul. Amintiți-vă din secțiunea teoriei software-ului că putem deduce direcția de rotație dacă cunoaștem intrarea care a provocat întreruperea, noua sa valoare și valoarea celeilalte intrări. Iată pseudocodul: Citiți PORTB într-o variabilă zero pentru a șterge semnalizatorul de întrerupere Verificați dacă A a provocat întreruperea. Dacă este adevărat, comparați A și B. Verificați dacă este diferit, dacă este diferit, A fost o rotație în sensul acelor de ceasornic Altfel, A fost în sens invers acelor de ceasornic EndifCheck dacă B a provocat întreruperea. Dacă este adevărat, comparați A și B Verificați dacă este diferit, dacă este același, A fost o rotație în sensul acelor de ceasornic Altfel, A fost în sens invers acelor de ceasornic EndifReturnare de la întrerupere Descoperirea noii valori a intrării modificate și a celeilalte intrări (neschimbate) este ușoară, deoarece le putem citi în interiorul ISR. Trebuie să știm care era starea fiecăruia înainte ca executarea să fie trimisă la ISR. Acest lucru se întâmplă în rutina principală. Rutina principală stă și așteaptă ca o variabilă de octeți pe care am numit-o CWflag să fie setată la 1 sau eliminată la 0 de către ISR. După fiecare schimbare confirmată a butonului sau dacă nu există activitate a butonului, variabila este setată la 5 pentru a indica o stare inactivă. Dacă semnalizatorul este setat sau este șters, rutina principală crește sau micșorează imediat presiunea punctului de setare în mod corespunzător în funcție de rotație și apoi setează variabila CWflag la 5 deoarece butonul este acum din nou inactiv. Deoarece rutina principală este verificarea CWflag, documentează și starea valorilor comutatorului rotativ A și B. Acest lucru este foarte simplu și arată astfel: vechi A = AoldB = B Doar includeți aceste două linii la începutul buclei care verifică rotirea CWflag. Tocmai actualizăm valorile logice ale intrărilor din butonul rotativ din bucla de creștere / descreștere din rutina principală, astfel încât să putem vedea ce intrare a cauzat întreruperea când ISR este executat. Iată codul ISR: ABchange: scratch = PORTB 'Citiți PORTB pentru a șterge semnalul de întrerupere' Dacă A determină întreruperea, verificați B pentru direcția de rotație IF oldA! = A THEN 'Dacă A și B sunt diferite, a fost o rotație în sensul acelor de ceasornic IF A! = B THEN GOTO CW 'În caz contrar, a fost o rotație în sens invers acelor de ceasornic ELSE GOTO CCW ENDIF ENDIF' Dacă B provoacă întreruperea, verificați A pentru direcția de rotație IF oldB! = B THEN 'Dacă A și B sunt aceleași, a fost o rotație în sensul acelor de ceasornic IF A == B THEN GOTO CW 'În caz contrar, a fost o rotație în sens invers acelor de ceasornic ELSE GOTO CCW ENDIF ENDIFCW: CWflag = 1 @ INT_RETURNCCW: CWflag = 0 @ INT_RETURN Am inclus codul ISR într-un fișier AB_ISR.bas deoarece filele din cod nu apar așa cum ar trebui. Acum, deoarece ISR are valorile vechi pentru intrările A și B, poate determina ce intrare a provocat întreruperea, o poate compara cu cealaltă intrare (neschimbată) și poate determina direcția de rotație. Tot ceea ce trebuie făcut este să verificați CWflag-ul pentru a vedea ce direcție a rotit butonul (dacă are) și să măriți sau să micsorați un contor, set point sau orice doriți sau aveți nevoie. Sper că acest lucru vă ajută și nu a fost prea confuz. Acest tip de interfață este util mai ales dacă sistemul dvs. folosește deja întreruperi, deoarece aceasta este doar o altă întrerupere de adăugat. Bucurați-vă!

Recomandat: