Enkoder i softuerit. AVR

Prej kohësh kam dashur të përshtat në laptopin tim një kontroll të volumit të bërë nga kodues. Ju do të duhet ta lidhni këtë rregullator me USB në mënyrë që gjithçka të "rritur" (dhe nuk ka asnjë mënyrë tjetër për të lidhur një pajisje të jashtme me laptopin). Kthejeni koduesin në të majtë - vëllimi duhet të ulet, në të djathtë - duhet të rritet. Ne shtypim çelësin e koduesit poshtë - hapim një program të dobishëm ose kalojmë në kontrollin e tonit.

Për ata që nuk e dinë se çfarë është një kodues - është një çelës, si një çelës vëllimi i bazuar në një rezistencë të rregullt, vetëm ky çelës nuk ka pozicione kufi - kthejeni sa të doni në çdo drejtim. Enkoderi rrotullohet me klikime të buta të këndshme, por duket si një rezistencë e zakonshme e ndryshueshme.

Pajisjet e tilla nuk janë të rralla në radiot moderne të makinave dhe në çdo pajisje shtëpiake, ndërfaqja e përdoruesit e së cilës përpunohet nga një mikrokontrollues (dhe kjo është pothuajse çdo pajisje shtëpiake) dhe ku nevojitet rregullim ose akordim i qetë. Një kontakt i tretë shpesh ndërtohet në kodues, i cili funksionon si një buton në një dorezë - kur shtypim dorezën e koduesit poshtë (përgjatë boshtit), ky buton aktivizohet. Ai pasuron shumë mundësitë e ndërfaqes së përdoruesit - në një kodues mund të ndërtoni të gjithë sistemin e kontrollit të një pajisjeje elektronike (por i shton dhimbje koke programuesit, por këto janë gjëra të vogla). Unë sapo kisha një kodues të tillë.

Parimi i funksionimit të koduesit është mjaft i thjeshtë - ai ka vetëm dy kontakte (butoni në dorezë nuk llogaritet), të cilat fillojnë të mbyllen sapo përdoruesi fillon të rrotullojë dorezën e koduesit. Kontaktet janë të lidhura me dy këmbët e mikrokontrolluesit (që punojnë si hyrje dixhitale), dhe kur rrotullohet pulla e koduesit, në këto këmbë shfaqen pulse, nga faza dhe sasia e të cilave mikrokontrolluesi përcakton drejtimin e rrotullimit dhe këndin e rrotullimit. të çelësit të koduesit.

Për të funksionuar kontrollin e volumit, duhet të zgjidhni të paktën tre probleme inxhinierike:

Hapi 1. Krijimi i një pajisjeje USB me shpejtësi të ulët në një dërrasë buke.
Hapi 2. Lidhni një kodues me këtë pajisje USB, sigurohuni që mikrokontrolluesi ta përpunojë atë dhe të transmetojë informacion në lidhje me rrotullimin e koduesit në kompjuter.
Hapi 3. Kuptoni se si mund të kontrolloni programatikisht kontrollin e volumit. Me siguri ekziston një lloj API multimediale që ju lejon ta bëni këtë. Programi minimal - duhet të shkruani një program që do të marrë sinjale nga një pajisje USB dhe do të kontrollojë volumin. Do të ishte mirë, sigurisht, të shkruash një shofer, por është pak e frikshme për ta ndërmarrë. Më mirë ta lini për më vonë.

Pra, unë do të përshkruaj procesin e krijimit të një rregullatori hap pas hapi. Do t'i heq detajet, përndryshe do të jetë shumë e mërzitshme. Për të interesuarit, shikoni burimet dhe dokumentacionin në lidhjet.

[Hapi 1: Krijoni një pajisje USB me shpejtësi të ulët në një tabelë]

Ky hap kaloi pa filluar as - disi shumë i thjeshtë dhe banal. Kam shkarkuar marrëzi një projekt shembull nga lidhja. E korrigjova skedarin usbconfig.h - e emërova pajisjen time për t'u dukur DEMO ENKODER, nuk kishte imagjinatë të mjaftueshme për më shumë. Kontrollova llojin e procesorit (ATmega16) dhe frekuencën e kuarcit (16 MHz) në Makefile për t'u përshtatur me tabelën time AVR-USB-MEGA16. E përpilova projektin në AVRStudio, ndeza tabelën e bukës, e lidha me kompjuterin - gjithçka filloi gjysmë rrotullimi, pajisja ime USB funksionoi siç duhet si një port virtual COM - gjithçka është saktësisht siç shkruhet në artikull.

[Hapi 2. Lidhni koduesin me pajisjen USB]

Ky hap më shkaktoi frikën më të madhe se gjithçka do të funksiononte ashtu siç duhej. Që do të lidhja koduesin dhe do të isha në gjendje ta lexoja - nuk kisha asnjë dyshim për këtë. Kishte dyshime se do të isha në gjendje ta lexoja me efikasitet kur përpunimi i protokollit USB po funksiononte gjithashtu në sfond - në fund të fundit, kjo nuk është një detyrë e lehtë për një mikrokontrollues (siç doli më vonë, isha plotësisht e kotë të shqetësohesha ).

Si zakonisht, fillova të fshij internetin në kërkim të nënprogrameve të gatshme për të lexuar koduesin. Gjeta shumë shpejt atë që më duhej - veçanërisht për AVR, kod shumë i thjeshtë në C, skedarë encoder.c dhe encoder.h. Çfarëdo që të thoni, burimi i hapur është një gjë e lezetshme.

Kam bashkangjitur dy LED tregues - E GJELBËR dhe TË VERDHË - për të treguar drejtimin e rrotullimit të koduesit. Për lehtësi, e lidha koduesin direkt me lidhësin ISP, duke përfituar nga fakti se sinjalet MOSI, MISO dhe SCK janë vetëm kunjat PB5, PB6 dhe PB7 të mikrokontrolluesit ATmega16 (kam lidhur fazat A dhe B atje, si dhe një buton kodues).

Përkufizimet e korrigjuara të këmbëve dhe shtimi i kodit të inicializimit. Unë shtova modulin encoder.c në projekt. Shtoi kontrollin e LED-ve jeshile dhe të verdha në qarkun kryesor kur informacioni vjen nga koduesi. LED LED është i lidhur me butonin e koduesit - kur e shtypim, LED-i i kuq ndizet, kur e lëshojmë, fiket. E përpiloi, e ndezi - funksionon. E kthej dorezën në të majtë dhe LED jeshil pulson me kohë me klikimet e koduesit. E kthej dorezën në të djathtë dhe LED-ja e verdhë pulson. Pavarësisht se koduesi lexohet duke përdorur metodën e sondazhit, falë kodit efikas, NUK ka ankesa për leximin e koduesit, edhe kur punoni njëkohësisht me bibliotekën V-USB (respekt, Pashgan!). Dalja e shtuar e informacionit nga koduesi në portën virtuale COM (kthejeni koduesin në të majtë, shfaq shenjat minus "-" në tastierë, e kthej atë në të djathtë, shfaq shenjat plus "+" në tastierë). Duke përdorur një kohëmatës, çdo 10 ms shfaq gjendjen e butonit të koduesit dhe e tregoj atë me një LED të kuq (butoni shtypet - transmetoj simbolin "1", kur lëshohet - "0"). Gjithçka po funksionon. E mërzitshme.

Më në fund, hodha modulet cmd.c, crc16.c, eepromutil.c, strval.c. Madhësia e kodit ka rënë në 3 kilobajt - shkëlqyeshëm, tani do të futet në memorien ATtiny45 (mund të përdorni tabelën e bukës AVR-USB-TINY45 në të ardhmen, është më e vogël dhe më e lirë).

[Hapi 3. Kuptoni se si të kontrolloni programatikisht kontrollin e volumit]

Si zakonisht, e kërkova në Google pyetjen. Kam shoshitur një tufë mbeturinash dhe më në fund mora një perlë - . Pastaj është çështje teknologjie. Unë nxjerr kompletin tim të preferuar të ndërtimit për fëmijë - Visual Studio. Pa menduar për asgjë, gjenerova një aplikacion të bazuar në dialog duke përdorur magjistarin. E lëshoj rrëshqitësin e kontrollit të volumit në panel, lidh një variabël me të dhe shtoj një mbajtës të pozicionit të rrëshqitësit. Kur fillon aplikacioni, e vendos motorin në një minimum prej 0 dhe një maksimum prej 65535 (për të korresponduar me kufijtë e vlerës së volumit të manipuluar nga bibliotekat e kontrollit të mikserit). E lexova me një funksion mixerGetControlDetails vlera aktuale e volumit dhe vendoseni rrëshqitësin në pozicionin e duhur. Në mbajtësin e pozicionit të rrëshqitësit, gjithçka është e kundërta - lexova pozicionin e rrëshqitësit dhe përdor funksionin mixerSetControlDetails Vendosa volumin e dëshiruar. Unë kontrolloj volumin saktësisht siç është shkruar në artikull. E kontrollova - funksionon.

Tani gjithçka që mbetet për të bërë është të lexoni atë që vjen nga porta virtuale COM (ne kemi një pajisje USB të sapopjekur me një kodues të varur mbi të). Nëse merret një shenjë minus (-), atëherë lëvizni rrëshqitësin në të majtë (ulni volumin), një shenjë plus (+), më pas zhvendoseni rrëshqitësin në të djathtë (rritni volumin). Nëse mbërrijnë karakteret 0 dhe 1, atëherë ne kontrollojmë gjendjen e kutisë së kontrollit në përputhje me rrethanat (vetëm për të treguar nëse butoni i koduesit është i shtypur apo jo). Ju mund të punoni me një port COM si me një skedar të rregullt (shih). Ne inicializojmë lidhjen me portin COM duke hapur një skedar (duke thirrur :: KrijoFile) në modalitetin e bllokimit. Ne hapim një fije të veçantë, shtojmë leximin e skedarit në lakin e pafund (me një thirrje bllokuese ::ReadFile) një personazh në një kohë dhe analizoni këtë personazh. Në bazë të cilit simbol ka mbërritur, ne e kthejmë rrëshqitësin në drejtimin e dëshiruar (vëllimi do të rregullohet nga mbajtësi i rrëshqitësit) ose përditësojmë gjendjen e kutisë së kontrollit. E kontrollova - funksionon.

Kjo është e gjitha, në fakt. Atëherë mund të përfshiheni në përmirësime të pafundme (dhe ndoshta të padobishme). Bëni një kërkim automatik për portën e kërkuar virtuale COM (tani, për të thjeshtuar gjërat, emri i portës COM kalon përmes vijës së komandës). Konvertoni një pajisje USB me CDC- klasa në HID- kjo mund të thjeshtojë kodin e një pajisjeje USB, si dhe të thjeshtojë kërkimin programatik dhe hapjen e pajisjes në kompjuter me anë të VID dhe HID. Ose shkruani një shërbim në vend të një programi (në mënyrë që të mos keni nevojë të ekzekutoni një program të veçantë). Ose edhe një shofer. Kjo është shumë interesante, por nuk e di se si (ndoshta një nga banorët e Khabra do të më mësojë mençurinë? ..). Bashkangjitni disa veprime në butonin e koduesit. Dhe kështu me radhë ad infinitum.

Shpresoj se dikush do ta gjejë kërkimin tim të dobishëm në zhvillimet e veta. Nëse më ka munguar ndonjë gjë, do të jem i lumtur të dëgjoj komentet tuaja në komente.

[UPD120803]

Një person kompetent montoi një AVR në një mikrokontrollues

Shpesh në pajisjet në mikrokontrolluesit është e nevojshme të organizoni menaxhimin e artikujve të menusë ose të zbatoni një lloj rregullimesh. Ka shumë mënyra: përdorni butona, rezistorë të ndryshueshëm ose kodues. Një kodues në rritje ju lejon të kontrolloni diçka duke e rrotulluar pullën pafundësisht. Në këtë artikull do të shohim se si të funksionojë një kodues inkremental dhe Arduino.

Karakteristikat e një koduesi në rritje

Një kodues në rritje, si çdo lloj tjetër koduesi, është një pajisje me një dorezë rrotulluese. I ngjan në mënyrë të paqartë një potenciometër. Dallimi kryesor nga një potenciometër është se doreza e koduesit rrotullohet 360 gradë. Nuk ka pozicione ekstreme.

Koduesit vijnë në lloje të ndryshme. Ai rritës ndryshon në atë që nuk mund të përdoret për të gjetur pozicionin e dorezës, por vetëm fakti i rrotullimit në një drejtim - majtas ose djathtas. Bazuar në numrin e pulseve të sinjalit, tashmë mund të llogarisni këndin në të cilin është kthyer.

Në këtë mënyrë ju mund të kaloni një komandë, të kontrolloni menynë, nivelin e volumit, për shembull, etj. Në jetën e përditshme, mund t'i shihni në radio makinash dhe pajisje të tjera. Përdoret si një kontroll multifunksional për rregullimin e nivelit, barazuesin dhe navigimin e menusë.

Brenda një koduesi në rritje ka një disk me shenja dhe rrëshqitës që i prekin ato. Struktura e tij është e ngjashme me një potenciometër.

Në foton e mësipërme shihni një disk me shenja, ato nevojiten për të ndërprerë lidhjen elektrike me kontaktin lëvizës, si rezultat ju merrni të dhëna për drejtimin e rrotullimit. Dizajni i produktit nuk është aq i rëndësishëm, le të shohim parimin e funksionimit.

Enkoderi ka tre kunja informacioni, njëra e zakonshme, dy të tjerat zakonisht quhen "A" dhe "B", në figurën e mësipërme shihni pikën e kodimit me një buton - mund të merrni një sinjal kur shtypni boshtin e tij.

Çfarë sinjali do të marrim? Në varësi të drejtimit të rrotullimit, një logjik do të shfaqet fillimisht në pin A ose B, kështu që marrim një sinjal të zhvendosur në fazë dhe ky zhvendosje na lejon të përcaktojmë se në cilin drejtim. Sinjali merret në formën e një forme drejtkëndore, dhe mikrokontrolluesi kontrollohet pas përpunimit të të dhënave për drejtimin e rrotullimit dhe numrin e pulseve.

Figura tregon simbolin e një disku me kontakte, në mes është një grafik i sinjaleve të daljes, dhe në të djathtë është një tabelë e gjendjeve. Kjo pajisje vizatohet shpesh si dy çelësa, gjë që është logjike, sepse në fakt ne marrim një sinjal "përpara" ose "prapa", "lart" ose "poshtë" dhe numrin e ndikimeve.

Këtu është një shembull i një pinout të vërtetë të koduesit:

Interesante:

Një kodues me defekt mund të zëvendësohet me dy butona që nuk fiksohen dhe anasjelltas: një produkt shtëpiak që kontrollohet nga dy butona të tillë mund të modifikohet duke instaluar një kodues.

Në videon më poshtë shihni alternimin e sinjalit në kunjat - me rrotullime të qetë, LED-të ndizen në sekuencën e pasqyruar në grafikun e mëparshëm.

Kjo ilustrohet jo më pak qartë në animacionin e mëposhtëm (kliko mbi imazhin):

Enkoderi mund të jetë optik (sinjali gjenerohet nga emetuesit e fotodetektorit, shihni figurën më poshtë) dhe magnetik (funksionon në efektin Hall). Në këtë rast, ai nuk ka kontakte dhe një jetë më të gjatë shërbimi.

Siç u përmend tashmë, drejtimi i rrotullimit mund të përcaktohet nga cili nga sinjalet e daljes ndryshoi së pari, dhe kështu duket në praktikë!

Saktësia e kontrollit varet nga rezolucioni i koduesit - numri i pulseve për rrotullim. Numri i pulseve mund të jetë nga njësi në mijëra. Meqenëse koduesi mund të veprojë si një sensor pozicioni, sa më shumë impulse, aq më i saktë do të jetë përcaktimi. Ky parametër është caktuar si PPR - impuls për rrotullim.

Por ekziston një nuancë e vogël, domethënë përcaktimi i ngjashëm LPR është numri i etiketave në disk.

Dhe numri i impulseve të përpunuara. Çdo shenjë në disk prodhon 1 valë katrore në secilën prej dy daljeve. Pulsi ka dy pjesë të përparme - të pasme dhe të përparme. Meqenëse ka dy dalje, nga secila prej tyre marrim gjithsej 4 impulse, vlerat e të cilave mund t'i përpunoni.

Lidhu me Arduino

Ne kemi mbuluar atë që duhet të dini për një kodues në rritje, tani le të zbulojmë se si ta lidhim atë me Arduino. Le të shohim diagramin e lidhjes:

Moduli i koduesit është një tabelë në të cilën janë vendosur koduesi në rritje dhe rezistorët tërheqës. Ju mund të përdorni çdo kunj.

Nëse nuk keni një modul, por një kodues të veçantë, thjesht duhet të shtoni këto rezistorë, qarku nuk do të jetë thelbësisht i ndryshëm. Për të kontrolluar drejtimin e rrotullimit dhe funksionalitetin e tij, mund të lexojmë informacion nga porta serike.

Le të shohim kodin në mënyrë më të detajuar, një nga një. Në void setup() ne deklaruam se do të përdorim komunikimin serial dhe më pas vendosim kunjat 2 dhe 8 në modalitetin e hyrjes. Ju i zgjidhni vetë numrat e pinit bazuar në diagramin tuaj të lidhjes. Konstanta INPUT_PULLUP vendos modalitetin e hyrjes Arduino ka dy opsione:

    INPUT - hyrje pa rezistorë tërheqës;

    INPUT_PULLUP - lidhja e rezistorëve tërheqës në hyrje. Brenda mikrokontrolluesit tashmë ka rezistorë përmes të cilëve hyrja lidhet me energjinë pozitive (tërheqje).

Nëse përdorni rezistorë për të tërhequr furnizimin me energji siç tregohet në diagramet e mësipërme ose përdorni një modul kodues, përdorni komandën INPUT dhe nëse për ndonjë arsye nuk mundeni ose nuk dëshironi të përdorni rezistorë të jashtëm, përdorni INPUT_PULLUP.

Logjika e programit kryesor është si vijon: nëse kemi një në hyrjen "2", ai nxjerr H në monitorin e portit, nëse jo, L. Kështu, kur rrotullohet në një drejtim në monitorin e portit serik, ju merrni diçka. si kjo: LL HL HH LH LL. Dhe në drejtim të kundërt: LL LH HH HL LL.

Nëse i lexoni me kujdes rreshtat, ndoshta keni vënë re se në një rast karakteri i parë ka marrë një kuptim, dhe në rastin tjetër karakteri i dytë ka ndryshuar i pari.

konkluzioni

Koduesit rritës kanë gjetur aplikim të gjerë praktik në amplifikatorët për sistemet e altoparlantëve - ato u përdorën si një kontroll i volumit, në radiot e makinave - për të rregulluar parametrat e zërit dhe për të lundruar në menutë, në minjtë e kompjuterit, ju e përdorni atë për të lëvizur faqet çdo ditë (një rrotë është i instaluar në boshtin e tij) . Dhe gjithashtu në instrumentet matëse, makinat CNC, robotët dhe sinkronët, jo vetëm si kontrolle, por edhe për matjen e sasive dhe përcaktimin e pozicionit.

Në këtë projekt demo ne do të shikojmë detyrën e ndërlidhjes së një elementi kontrolli të quajtur kodues me një mikrokontrollues PIC.

Për të zbatuar projektin demonstrues do të na duhen:

  • kodues me 24 pozicione;
  • 16 LED (3 mm);
  • drejtues LED;
  • mikrokontrollues

Një kodues është një element kontrolli modern dhe origjinal për pajisjet dixhitale, dhe në pamje është i ngjashëm me një rezistencë të ndryshueshme (shih figurën më poshtë). Një emër tjetër për këtë kontroll është sensori i këndit, sensori i rrotullimit. Rrotullimi i boshtit shoqërohet me klikime, për shembull 24 klikime për rrotullim. Enkoderi ka 3 dalje - A, B, C dhe përdoret për futjen e shpejtë të të dhënave në pajisjet dixhitale. Disa modele kanë një buton të integruar që aktivizohet duke shtypur boshtin e koduesit (shtohet një dalje tjetër).

Parimi i funksionimit të koduesit

Kur ktheni një klikim, për shembull, djathtas, kontakti A+C mbyllet fillimisht, pastaj B+C. Kur boshti kthehet në këtë klikim, kontaktet hapen në të njëjtën sekuencë. Kur boshti kthehet në drejtimin tjetër, sekuenca e mbylljes me kontaktin C ndryshon, d.m.th. kur ktheheni majtas, fillimisht B+C, pastaj A+C mbyllen.

Duke përdorur një kodues në projektet e mikrokontrolluesve, është e mundur të zbatohen disa lloje të ndryshme të futjes së të dhënave duke përdorur të njëjtin kodues, megjithatë, kjo kërkon disa reagime dhe vizualizim në mënyrë që përdoruesi të dijë se çfarë informacioni po fut dhe në çfarë pozicioni është koduesi.


Diagrami skematik: lidhja e koduesit me mikrokontrolluesin PIC (kliko për ta zmadhuar)

Kunjat e koduesit A ​​dhe B janë të lidhura me portat e mikrokontrolluesit RB4 dhe RB5, kunja e koduesit C është e lidhur me tokën. Vlen të përmendet se rezistorët tërheqës duhet të lidhen me linjat e sinjalit të kunjave A dhe B. Nuk është rastësi që koduesi është i lidhur me linjat e specifikuara I/O të mikrokontrolluesit: së pari, porta B ka rezistorë tërheqës të integruar dhe nuk duhet të lidhim ato të jashtme, dhe së dyti, porta B e mikrokontrolluesit. ka një funksion shumë të dobishëm - "interrupt-on-change" - ndërprerje duke ndryshuar nivelin, i cili do të na lejojë të monitorojmë gjendjen e koduesit.

16 LED të zakonshëm 3 mm përdoren për të vizualizuar të dhënat hyrëse dhe ato do të vendosen në tabelën e qarkut të printuar rreth koduesit të instaluar. LED-et janë të lidhura me çipin A6276.

Çipi është një drejtues LED me hyrje informacioni serik 16-bit. Drejtuesi përmban një regjistër zhvendosjeje 16-bitësh CMOS, kapëse dhe drejtues të lidhur për të kontrolluar LED-të dhe mund të drejtojë më shumë LED sesa lejon mikrokontrolluesi. Përveç kësaj, drejtuesi mund të kontrollohet nëpërmjet një ndërfaqeje SPI, e cila redukton më tej numrin e linjave I/O të përdorura dhe e bën projektin të shkallëzueshëm.

Softueri i mikrokontrolluesit për zgjidhjen e problemit tonë është relativisht i thjeshtë. Ka 3 mënyra funksionimi (hyrje informacioni) dhe reagime:

  • Modaliteti i pozicionimit 360° - në këtë modalitet, LED-të tregojnë "pozicionin" aktual të koduesit, përdoruesi mund të rrotullojë boshtin e koduesit majtas dhe djathtas në çdo kënd;
  • Modaliteti "Vëllimi/Niveli" - në këtë modalitet, LED-të tregojnë vlerën aktuale midis niveleve minimale dhe maksimale të diapazonit të hyrjes (si niveli i volumit në pajisjet audio);
  • Modaliteti i ndërprerësit rrotullues me 3 pozicione - Në këtë modalitet, ekzistojnë vetëm tre pozicione të zgjedhura që përdoruesi zgjedh duke e kthyer boshtin e koduesit majtas/djathtas.

Demonstrimi i projektit

Parimi i funksionimit, diagrami i lidhjes dhe kodi burimor i bibliotekës për të punuar me një kodues rritës janë diskutuar tashmë nga unë në një nga artikujt. Sot do të flasim për aplikimin praktik të koduesit. Si shembull, unë zgjodha një program gjenerues të valëve katrore me një gamë frekuence funksionimi prej 1 - 100 Hz. Plani origjinal supozoi një gamë prej 1 - 1000 Hz, por në praktikë doli se kalimi i njëmijë vlerave është i lodhshëm edhe me një kodues.

Përgatitja

Krijo një projekt të ri në një hapësirë ​​pune bosh

Projekti > Krijo projekt të ri…

Lloji i shabllonit C > kryesor

Kopjoni skedarët burimor të bibliotekës për të punuar me koduesin në dosjen e projektit
kodues.h dhe kodues.c

Ne lidhim skedarin encoder.c me projektin tonë
Butoni i djathtë i miut në dritaren e hapësirës së punës dhe në menynë që hapet Shto > Shto skedarë...

Kopjoni skedarin bits_macros.h në dosjen e projektit.


Përfshirë skedarët e kokës

Në fillim të skedarit main.c shkruajmë rreshtat e mëposhtëm
#përfshi
#përfshi
#include "encoder.h"
#include "bits_macros.h"

Vendosja e cilësimeve të projektit

Projekti > Opsionet

Lloji i mikrokontrolluesit
Opsionet e përgjithshme > Synimi > Konfigurimi i procesorit > ATMega8535

Lejimi i përdorimit të emrave të biteve të përcaktuar në skedarët e kokës
Opsionet e përgjithshme > Sistemi > Aktivizo përkufizimet e biteve...

Optimizimi i kodit për madhësinë
Përpiluesi C/C++ > Optimizimet > Madhësia e lartë

Lloji i skedarit dalës
Kontrolli i lidhjes > Skedari i daljes Anuloni parazgjedhjen dhe ndryshoni shtrirjen në hex
Lidhësi > Formati > Tjetër zgjidhni Intel Standard

Klikoni OK. Ruani projektin dhe hapësirën e punës.
Tani kemi një projekt bosh me një bibliotekë të lidhur dhe cilësime të specifikuara.

Detyrë

Bëni që mikrokontrolluesi të gjenerojë një valë katrore me një frekuencë nga 1 në 100 Hz. Vlera e frekuencës duhet të vendoset duke përdorur një kodues. Kthimi i koduesit me një pozicion duhet të korrespondojë me një ndryshim në frekuencën e gjeneratorit me 1 Hz.

Diagrami për shembullin tonë

Një LED është i lidhur me pinin në të cilin do të gjenerohet gjarpërimi në mënyrë që të paktën të shihet disi rezultati i programit. Nuk ka gjasa që shumë njerëz të kenë një oshiloskop në dorë.

Algoritmi i programit

Sinjali i valës katrore gjenerohet duke përdorur një kohëmatës 16-bit T1, i cili funksionon në modalitetin CTC - rivendoset kur koincidon. Memoria flash e mikrokontrolluesit ruan një grup që përmban një konstante për çdo vlerë të frekuencës së kërkuar. Ndryshorja pTimerValue përdoret për të aksesuar elementët e grupit. Në ndërprerjet e kohëmatësit T1, vlera e konstantës lexohet dhe shkruhet në regjistrin e krahasimit.

Pini PD5 (OC1A) përdoret për të gjeneruar sinjalin. Ai ka funksione alternative - mund të ndryshojë gjendjen e tij në të kundërtën nëse regjistri i numërimit dhe regjistri i krahasimit janë të barabartë.

Në programin kryesor, në një lak të pafund ndërsa, mikrokontrolluesi anketon buferin e koduesit dhe, në varësi të vlerës së tij, zvogëlon ose rrit variablin pTimerValue.

Në fillim të main ka kod për inicializimin e pajisjeve periferike dhe variablave të nevojshëm.

Struktura e programit

Për qartësi, unë kam përshkruar strukturën e programit në formën e një diagrami.

Kjo është një strukturë tipike për ndërtimin e programeve të thjeshta. Ndërprerjet ndodhin natyrshëm në pika të rastësishme në lak.

  • Inicializimi.
  • Një lak i pafund (i ashtuquajturi superloop) në të cilin pritet një ngjarje, zakonisht në formën e flamujve të votimit ose një lloj tampon.
  • Funksionimi paralel i pajisjeve periferike që shkaktojnë ndërprerje. Ata ekzekutojnë disa kode (mundësisht të shkurtër) dhe vendosin flamuj.

Për detyra të thjeshta kjo qasje është e mjaftueshme. Për ato komplekse, ka mënyra të tjera për të organizuar programe. Jini të durueshëm, gjërat do t'u vijnë së shpejti.

Llogaritja e konstantave për kohëmatësin T1

Le të llogarisim vlerën e konstantës për një frekuencë prej 1 Hz. Unë kam dhënë tashmë një llogaritje të ngjashme, por do të ishte e dobishme ta mbani mend atë

Frekuenca e orës së mikrokontrolluesit është 16 MHz (shih diagramin). Faktori i parashkallëzuesit të kohëmatësit është 256. Ai ju lejon të merrni ndërprerje me çdo frekuencë nga diapazoni ynë.

Periudha e një tik-takimi të kohëmatësit do të jetë e barabartë me 1/(16 MHz/ 256) = 16 µs

Në pinin PD5 duhet të marrim një sinjal me frekuencë 1 Hz. Pini ndryshon gjendjen e tij për çdo ndërprerje të kohëmatësit, që do të thotë se frekuenca e ndërprerjes duhet të jetë 2 herë më e lartë. Për rastin tonë - 2 Hz.

Sa rriqra kohëmatës do të përshtaten në 2 Hertz? (1/2 Hz)/16 µs = 31250
Kjo është konstanta e dëshiruar.

Vlerat e mbetura llogariten në të njëjtën mënyrë. Unë zakonisht përdor Excel për këtë.


Ne vendosim vlerat që rezultojnë në një grup

__flic i panënshkruar int timerVlera =
{

ruajeni në një skedar të veçantë – timer_value.h dhe lidheni me skedarin main.c

#include "timer_value.h"

Po, ju ende duhet të shtoni disa konstante në këtë skedar

#define MAX_TIM_VALUE 99
#define MIN_TIM_VALUE 0

Le të sigurohemi që i kemi llogaritur saktë konstantet për kohëmatësin. Le ta nisim atë. Kodi i programit do të jetë i tillë.

//Programimi AVR në C

//faqe 10.17.09
#përfshi
#përfshi
#include "encoder.h"
#include "bits_macros.h"
#include "timer_value.h"

//indeks për qasje në elementet e grupit
i paqëndrueshëm unsigned char pTimerValue = 0;

ndër kryesore( i pavlefshëm )
{
//inicializimi i kohëmatësit T1
TCNT1 = 0;
TCCR1A = (0<TCCR1B = (0<

//vendosni pinin PD5 në dalje
SetBit (PORTD, PD5);
SetBit (DDRD, PD5);

// mos bëj asgjë në një lak të pafund
derisa(1);
kthimi 0;
}

Unë mendoj se vetëm pjesa e inicializimit të kohëmatësit kërkon shpjegim.

Rivendosja e regjistrit të numëruesit
TCNT1 = 0;

Inicializimi i regjistrave të konfigurimit të kohëmatësit T1.
TCCR1A = (0<TCCR1B = (0<

Ku bitet WGM13, WGM12, WGM11, WGM10 vendosin mënyrën e funksionimit të kohëmatësit - CTC,
CS12, CS11, CS10 – përcaktoni koeficientin e parashkallëzuesit të kohëmatësit –256,

COM1A1, COM1A0 - përcaktoni sjelljen e pinit PD5(OC1F) - në këtë rast, bazuar në një sinjal kohëmatësi, ai do të ndryshojë gjendjen e tij në atë të kundërt


Inicializoni regjistrin e përputhjes në vlerën fillestare.
OCR1A = Vlera e kohëmatësit;

Ne e përpilojmë programin dhe e ngarkojmë atë në mikrokontrollues. LED duhet të pulsojë në një frekuencë prej 1 Hz.
Nuk ka ndërprerje në program. Nuk ka asnjë manipulim të pinit PD5. Megjithatë, LED pulson!

Programi

Tani duhet të "vidhosni" koduesin në këtë program. Le të vendosim cilësimet në skedarin e kokës encoder.h - porta dhe kunjat me të cilat është lidhur koduesi, vlerat e konstanteve.


#define PORT_Enc PORTA
#define PIN_Enc PINA
#define DDR_Enc DDRA
#define Pin1_Enc 2
#define Pin2_Enc 1

#define RIGHT_SPIN 0x01
#define LEFT_SPIN 0xff

Kreu përmban prototipe të tre funksioneve. Le të kujtojmë qëllimin e tyre.

i pavlefshëm ENC_InitEncoder (i pavlefshëm) konfiguron kunjat e mikrokontrolluesit me të cilët është i lidhur koduesi me hyrjen. Ky funksion duhet të thirret në fillim të kryesore.


i pavlefshëm ENC_PollEncoder(i pavlefshëm)– anketon koduesin një herë, analizon gjendjen aktuale dhe të mëparshme dhe shkruan konstantet përkatëse (RIGHT_SPIN dhe LEFT_SPIN) në buffer. Ky funksion do të vendoset në ndërprerjen e kohëmatësit T0.


karakter i panënshkruar ENC_GetStateEncoder(void)– kthen përmbajtjen e buferit të koduesit. Nëse rrotullimi me një pozicion nuk ishte i fiksuar, funksioni do të kthejë 0 nëse rrotullimi ishte i fiksuar, funksioni do të kthejë vlerën e konstantës përkatëse. Kjo do të pastrojë vlerën e buferit. Ky funksion do të thirret në programin kryesor - në ciklin while.


Ne po zgjerojmë programin tonë. Ju mund të përpiqeni ta bëni këtë vetë.

//Programimi AVR në C
//një shembull i përdorimit të një koduesi
//faqe 10.17.09

#përfshi
#përfshi
#include "encoder.h"
#include "bits_macros.h"
#include "timer_value.h"

#define TCNT0_const 253
#define TCCR0_const 5

i paqëndrueshëm unsigned char pTimerValue = 0;

ndër kryesore( i pavlefshëm )
{
ENC_InitEncoder();

//inicializimi i kohëmatësit t0
TCNT0 = TCNT0_konst;
TCCR0 = TCCR0_konst;

//inicializimi i kohëmatësit t1
TCNT1 = 0;
TCCR1A = (0<TCCR1B = (0<OCR1A = Vlera e kohëmatësit;

//aktivizo ndërprerjet e kohëmatësit
//t0 - nga tejmbushja, t1 - nga rastësia

TIMSK = (1<

//vendosni PD5 në dalje
SetBit (PORTD, PD5);
SetBit (DDRD, PD5);

__aktivizoj_ndërprerjen ();
derisa (1){
//lexoni përmbajtjen e buferit të koduesit
//pas leximit pastrohet

karakter i panënshkruar stateEnc = ENC_GetStateEncoder();

//nëse jo bosh
nëse(stateEnc != 0)(
//përcaktoni drejtimin e rrotullimit dhe ndryshoni variablin timerValue
nëse(stateEnc == RIGHT_SPIN)(
nëse(pTimerValue == MAX_TIM_VALUE) pTimerValue = MIN_TIM_VALUE;
tjetër pTimerValue++;
}
nëse(stateEnc == LEFT_SPIN) (
nëse(pTimerValue == MIN_TIM_VALUE) pTimerValue = MAX_TIM_VALUE;
tjetër pTimerValue--;
}
}
}
kthimi 0;
}

//sondazhi me kodues
#pragma vector=TIMER0_OVF_vect
__ndërpreji pavlefshëm timer0_ovf_my( i pavlefshëm)
{
TCNT0 = TCNT0_konst;
ENC_PollEncoder();
}

#pragma vector=TIMER1_COMPA_vect
__ndërprej i pavlefshëm timer1_compa_my( i pavlefshëm)
{
//përditëso vlerën e regjistrit të krahasimit
OCR1A = Vlera e kohëmatësit;
}

Duket se gjithçka duhet të jetë e qartë.
Pjesa e kodit që ndryshon vlerën e pTimerValue mund të shkruhet gjithashtu si kjo:

nëse(stateEnc != 0) (
pTimerValue = pTimerValue + StateEnc;
nëse(pTimerValue == (MAX_TIM_VALUE + 1)) pTimerValue = MIN_TIM_VALUE;
tjeter nese(pTimerValue == (MIN_TIM_VALUE - 1)) pTimerValue = MAX_TIM_VALUE;
}

Kur koduesi rrotullohet djathtas, pTimerValue shtohet në 1, domethënë rritet.

Kur rrotullohet koduesi në të majtë, pTimerValue shtohet në 0хff, që është e barabartë me zbritjen e 1. Është i njëjti veprim, por rezultati është saktësisht i kundërt.

Për të zbatuar projektin demonstrues do të na duhen:

  • kodues me 24 pozicione;
  • 16 LED (3 mm);
  • Shofer LED A6276;
  • mikrokontrollues PIC18F2550.

Një kodues është një element kontrolli modern dhe origjinal për pajisjet dixhitale, dhe në pamje është i ngjashëm me një rezistencë të ndryshueshme (shih figurën më poshtë). Një emër tjetër për këtë kontroll është sensori i këndit, sensori i rrotullimit. Rrotullimi i boshtit shoqërohet me klikime, për shembull 24 klikime për rrotullim. Enkoderi ka 3 dalje - A, B, C dhe përdoret për futjen e shpejtë të të dhënave në pajisjet dixhitale. Disa modele kanë një buton të integruar që aktivizohet duke shtypur boshtin e koduesit (shtohet një dalje tjetër).

Parimi i funksionimit të koduesit

Kur ktheni një klikim, për shembull, djathtas, kontakti A+C mbyllet fillimisht, pastaj B+C. Kur boshti kthehet në këtë klikim, kontaktet hapen në të njëjtën sekuencë. Kur boshti kthehet në drejtimin tjetër, sekuenca e mbylljes me kontaktin C ndryshon, d.m.th. kur ktheheni majtas, fillimisht B+C, pastaj A+C mbyllen.

Duke përdorur një kodues në projektet e mikrokontrolluesve, është e mundur të zbatohen disa lloje të ndryshme të futjes së të dhënave duke përdorur të njëjtin kodues, megjithatë, kjo kërkon disa reagime dhe vizualizim në mënyrë që përdoruesi të dijë se çfarë informacioni po fut dhe në çfarë pozicioni është koduesi.

Diagram skematik

Kunjat e koduesit A ​​dhe B janë të lidhura me portat e mikrokontrolluesit RB4 dhe RB5, kunja e koduesit C është e lidhur me tokën. Vlen të përmendet se rezistorët tërheqës duhet të lidhen me linjat e sinjalit të kunjave A dhe B. Nuk është rastësi që koduesi është i lidhur me linjat e specifikuara I/O të mikrokontrolluesit: së pari, porta B ka rezistorë tërheqës të integruar dhe nuk duhet të lidhim ato të jashtme, dhe së dyti, porta B e mikrokontrolluesit. ka një funksion shumë të dobishëm - "interrupt-on-change" - ndërprerje duke ndryshuar nivelin, i cili do të na lejojë të monitorojmë gjendjen e koduesit.

16 LED të zakonshëm 3 mm përdoren për të vizualizuar të dhënat hyrëse dhe ato do të vendosen në tabelën e qarkut të printuar rreth koduesit të instaluar. LED-et janë të lidhura me çipin A6276.

Çipi A6276 është një drejtues LED me hyrje serike 16-bit. Drejtuesi përmban një regjistër zhvendosjeje 16-bitësh CMOS, kapëse dhe drejtues të lidhur për të kontrolluar LED-të dhe mund të drejtojë më shumë LED sesa lejon mikrokontrolluesi. Përveç kësaj, drejtuesi mund të kontrollohet nëpërmjet një ndërfaqeje SPI, e cila redukton më tej numrin e linjave I/O të përdorura dhe e bën projektin të shkallëzueshëm.

Softueri i mikrokontrolluesit për zgjidhjen e problemit tonë është relativisht i thjeshtë. Ka 3 mënyra funksionimi (hyrje informacioni) dhe reagime:

  • Modaliteti i pozicionimit 360° - në këtë modalitet, LED-të tregojnë "pozicionin" aktual të koduesit, përdoruesi mund të rrotullojë boshtin e koduesit majtas dhe djathtas në çdo kënd;
  • Modaliteti "Vëllimi/Niveli" - në këtë modalitet, LED-të tregojnë vlerën aktuale midis niveleve minimale dhe maksimale të diapazonit të hyrjes (si niveli i volumit në pajisjet audio);
  • Modaliteti i ndërprerësit rrotullues me 3 pozicione - Në këtë modalitet, ekzistojnë vetëm tre pozicione të zgjedhura që përdoruesi zgjedh duke e kthyer boshtin e koduesit majtas/djathtas.

Demonstrimi i projektit

Shkarkimet

Gjendet një arkiv ZIP me një projekt në mjedisin MPLAB dhe kodin burim në Hitech C, si dhe një diagram qarku dhe topologji të bordit të qarkut të printuar.