Domov - Nastavenie internetu
Dynamický sedemsegmentový displej na avr. Stručné teoretické informácie

V prípade zariadení napájaných z batérie sa použitie LCD indikátorov vo všeobecnosti považuje za vhodnejšie ako indikátory LED (light-emitting diode) z dôvodu ich vysokej spotreby prúdu. Tento postulát sa mi nezdá vôbec zrejmý z nasledujúcich dôvodov: 1) v moderných LCD indikátoroch je podsvietenie, ktoré spotrebuje až 100 mA; 2) sú pomerne krehké a obávajú sa priamych slnečných lúčov; 3) moderné LED indikátory (najmä superRED a ultraRED) majú dostatočný jas aj pri prúde 1 mA cez ne a pri rýchlom nastavení jasu v závislosti od svetelných podmienok je priemerná spotreba prúdu 4-miestneho indikátora maximálne 30 mA dokonca aj vonku, čo je menej ako spotreba podsvietenia LCD.

Napriek množstvu dynamických zobrazovacích obvodov online som na PIC16 nevidel obvod so softvérovým ovládaním jasu. Tento článok ukazuje môj skromný pohľad na realizáciu takejto úlohy. Je určený hlavne pre rádioamatérov, ktorí robia prvé kroky od opakujúcich sa návrhov k samoprogramovateľným mikrokontrolérom.

Článok pojednáva o tom, ako ovládať maticu LED pomocou mikrokontroléra PIC strednej triedy pomocou prerušení z časovačov TMR0 a TMR2. Časovač TMR2 sa používa na PWM riadenie priemerného prúdu cez povolené segmenty. Algoritmus organizácie práce je nasledujúci:

1. Inicializácia. Porty mikrokontroléra konfigurujeme v súlade so schémou zapojenia indikátora. Pre časovače 1 a 2 je aktivovaný režim interného taktovania s preddeličkou rovnajúcou sa 16. Periférne prerušenia sú povolené.

2. Vytvoríme tabuľku generátora znakov na zobrazenie čísel a niektorých (väčšinou latinských) písmen a symbolov na indikátore.

3. Vyhradzujeme dve štvorbitové premenné. V jednom zadáme sekvenčný digitálny kód (pre čísla - iba číslo) znaku potrebného na výstup v súlade s tabuľkou z bodu 2. Prevedené hodnoty z tabuľky sa prenesú do inej premennej na trvalé zobrazenie na indikátore.

4. V prerušení od TMR0 sa znakové bity postupne zobrazujú podľa tabuľky. Pred zmenou číslic indikátor zhasne. Každé prerušenie zobrazuje jednu číslicu. Potom sa vynuluje časovač TMR2, vynuluje sa príznak prerušenia z TMR2 a povolia sa prerušenia z neho.

5. V prerušení TMR2 indikátor zhasne a prerušenie TMR2 je deaktivované.

6. V hlavnom programe sa perióda prerušenia od TMR2, a teda čas zapnutia indikátora, upraví zadaním čísel od 7 do 255 v desiatkovom prepočte do registra PR2 pomocou vzorca X(n+1)=2* X(n)+1. Výsledkom je šesť stupňov jasu s 2-násobným rozdielom medzi nimi. Pri PR2=255 je trvanie maximálne (4 ms zo 4 ms), pri PR2=7 je trvanie približne 0,25 ms.

Na demonštráciu tohto princípu ovládania je nižšie uvedený obvod na lacnom PIC16F628A a testovací program v jazyku Assembly, ktorý na indikátore zobrazuje slovo „test“. Po stlačení tlačidla sa na indikátore zobrazí jas (bežne čísla od 0 do 5). Pri následných stlačeniach sa jas zmení v kruhu a to je okamžite viditeľné na indikátore. Chcel by som hneď varovať začiatočníkov: modelovanie obvodu na simulátore ako Proteus vám neumožní vidieť zmenu jasu kvôli vlastnostiam tohto programu (Proteus). Prototyp obvodu na testovanie a experimenty bude musieť byť zostavený v hardvéri. Na sledovanie skutočnej organizácie dynamického zobrazenia (okrem zmien jasu) je však pripojený model Proteus.

Spotreba obvodu pri minimálnom jase je menšia ako 4 mA, pri maximálnom - asi 80 mA.

Archív obsahuje testovací program v assembleri MPASM.

Na zjednodušenie obvodu a uvoľnenie „nohičiek“ pre rôzne akcie sa používa konfigurácia s vnútorným generátorom a vnútorným resetom. Zároveň tí, ktorí používajú podomácky vyrobený programátor bez možnosti odoslať signál MCLR pred Upp, môžu mať problémy s následným overovaním, čítaním a vymazávaním. Pre tých, ktorí si nie sú istí svojim programátorom, a tiež ak je potrebná vysoká stabilita oscilátora, môžete nainštalovať 4 MHz kremeň podľa štandardnej schémy s výberom v konfigurácii „OSC_XT“. Ak koncový obvod vyžaduje prerušenia z pinu INT0 (RB0), je možné čiarku ovládať cez pin RA4, u indikátora s OA je indikátor pripojený priamo na tento pin, aj keď je otvorený. Uvoľnený kolík RB0 možno použiť na určený účel. V programe, v prerušení od TMR0, sa v tomto prípade kód pridá za „movwf PORTB“:

Andlw b"00000001" bsf PORTA,4 potlačiť čiarku btfsc STATUS,Z vziať do úvahy, že vo W je inverzná hodnota. bcf PORTA,4 ak 0. bit = 0, ľahká čiarka

Malé vysvetlenia k programu:

Číslo výstupu sa umiestni do premenných OUT_ - OUT+3 podľa číslice az nej sa v podprograme out__ po konverzii umiestni do OUT_LED. Samozrejme, môžete sa zaobísť bez premennej OUT_ a písať všade pre výstup:

Movlw X volá Table_s movwf OUT_LED

V pôvodnej podobe je však všetko oveľa jednoduchšie a prehľadnejšie (umiestnil som to do OUT_ a zabudol som) a tiež pri viacerých výstupoch z rôznych miest v programe sa dosiahne úspora kódu (4 slová na 1 výstup) - myslím, že dobrá kompenzácia za ďalšie 4 bajty RAM.

To isté platí pre výstup čiarky cez premennú comma_.

V podprograme tabuľky Table_s boli prijaté opatrenia, aby správne fungovali pri umiestnení na ľubovoľné miesto v pamäti programu bez obmedzenia priesečníka 256 bajtových blokov.

Premenná pause_ v prerušení TMR0 slúži na nastavenie časových intervalov na 4 ms.

Ostatné je podľa mňa jasné z algoritmu a komentárov.

P.S. Pre 2 alebo 3 číslice v programe musíte vykonať minimálne zmeny, ktoré sú podľa mňa možné aj pre začiatočníkov. Na ovládanie indikátora s počtom číslic od 5 do 8 je potrebné buď použiť ovládač s veľkým počtom pinov alebo na ovládanie číslic použiť dekodér 3 x 8.

V prvom prípade sú zmeny v programe tiež minimálne (použitie iného portu namiesto portu A atď.). Ak sa použije dekodér, program týkajúci sa prerušenia TMR0 sa dosť vážne zmení.

Zoznam rádioelementov

Označenie Typ Denominácia Množstvo PoznámkaObchodMôj poznámkový blok
U1 MK PIC 8-bit

PIC16F628A

1 Do poznámkového bloku
H1 Indikátor4x7 FIQ-3641A1 Do poznámkového bloku
Q1-Q4 Bipolárny tranzistor

KT361E

4 Do poznámkového bloku
C3 Kondenzátor22 nF1 Do poznámkového bloku
R1-R7, R14 Rezistor

150 ohmov

8 Do poznámkového bloku
R8 Rezistor

Pokračujeme v lekcii a pozrime sa na dynamické zobrazenie. Ak ste si pozorne preštudovali statickú indikáciu, viete, že segmentový indikátor je sada LED. Na pripojenie indikátora potrebujete 7 pinov mikrokontroléra. Zrazu sme však potrebovali použiť niekoľko ukazovateľov, napríklad 2, 3, 4...

Potom budeme potrebovať 14, 21, 28 nôh a nôh je málo... Tu nám prichádza na pomoc dynamické zobrazenie. Hlavným cieľom dynamického zobrazenia je znížiť počet použitých pinov mikrokontroléra. Upozorňujeme, že v diagrame je zahrnutých 9, nie 14 nôh. Všetky ovládacie nohy sú zapojené paralelne.

Vo všeobecnom zmysle tento dizajn funguje nasledovne: najprv sa konfigurácia prvého čísla odošle na spoločnú zbernicu a zapneme PB1. Rozsvieti sa prvý indikátor s požadovaným číslom. Potom ho vypneme, vydáme konfiguráciu druhého čísla na dátovú zbernicu, rozsvietime druhý indikátor a vypneme.

Podrobnejšie. V prvom momente je všetko vypnuté PORTB=0x00; PORTD=0xFF; pretože obvod je so spoločnou „+“ anódou. Ďalej sa do PORTD odošle konfigurácia prvého čísla, napríklad „0“. Zo statického zobrazenia si pamätáme:

case 0 : ( PORTD= 0xC0 ; break ; )

prípad 0: ( PORTD=0xC0; prestávka; )

Ale všimnite si, že „+“ je pripojené k PORTB.1, t.j. na zapálenie segmentu je potrebné zapnúť PORTB.1=1 noha;

V druhom momente opäť všetko vypneme, odošleme konfiguráciu druhého čísla a zapneme, tentoraz, druhý indikátor. Ďalej opakujeme.

Pri vysokých frekvenciách ľudské oko nedokáže rozpoznať tieto prepínače a zdá sa, že indikátor stále svieti. Odporúča sa nepoužívať frekvencie, ktoré sú násobkami 50 Hz. V mojom testovacom projekte som použil 120 Hz. Časovač je nastavený na frekvenciu 1 MHz. Kód je spracovaný v prerušení timer1. Prerušenie sa volá 240-krát za sekundu, pretože existujú dva indikátory, takže do porovnávacieho registra vtlačíme 1000 000/240=4166 alebo 0x1046. Proteus nebolo možné spárovať s dynamickým indikátorom, no hardvérovo fungoval okamžite.

Poznámka!!! Pri pripájaní indikátora sa odporúča pripojiť ku každému segmentu odpor obmedzujúci prúd, a nie jeden spoločný. Tiež odporúčam pripojiť spoločný indikačný vodič cez tranzistor, inak si môžete spáliť nohu.

Pre obvod so spoločnou anódou

Pre obvod so spoločnou katódou

Ako testovací firmvér som použil časovač z predchádzajúceho projektu.

Video z prevádzky firmvéru

Indikátory sú zvyčajne umiestnené na miestach vhodných na prezeranie informácií, ktoré sú na nich zobrazené. Zvyšok digitálnych obvodov môže byť umiestnený na iných doskách plošných spojov. So zvyšujúcim sa počtom indikátorov sa zvyšuje počet vodičov medzi doskou indikátorov a digitálnou doskou. To vedie k určitým nepríjemnostiam pri vývoji konštrukcie a prevádzky zariadenia. Rovnaký dôvod vedie k zvýšeniu jeho nákladov.

Počet pripojovacích vodičov možno znížiť tak, že indikátory budú pracovať v impulznom režime. Ľudské oko má zotrvačnosť a ak prinútite indikátory zobrazovať informácie jeden po druhom dostatočne vysokou rýchlosťou, potom sa osobe bude zdať, že všetky indikátory zobrazujú svoje informácie nepretržite. V dôsledku toho je možné striedavo prenášať zobrazené informácie cez rovnaké vodiče. Zvyčajne postačuje obnovovacia frekvencia 50 Hz, ale je lepšie túto frekvenciu zvýšiť na 100 Hz.

Pozrime sa na blokovú schému sedemsegmentových LED indikátorov zobrazených na obrázku 1. Tento obvod môže poskytovať dynamickú indikáciu výstupných digitálnych informácií.


Obrázok 1. Bloková schéma dynamickej indikácie

V diagrame na obrázku 1 sú zobrazené štyri digitálne číslice. Každý bit je krátko pripojený k vlastnému vstupu prepínača. Generátor slúži na nastavenie rýchlosti aktualizácie informácií o indikátoroch. Binárne počítadlo sekvenčne generuje štyri stavy obvodu a prostredníctvom tlačidiel poskytuje alternatívne napájanie sedemsegmentových indikátorov.

Výsledkom je, že keď spínač dodáva binárny desiatkový kód zo vstupu A na vstupy sedemsegmentového dekodéra, tento kód sa zobrazí na indikátore HL1. Keď spínač dodáva binárno-desiatkový kód zo vstupu B na vstupy sedemsegmentového dekodéra, tento kód sa v cykle zobrazí na indikátore HL2 atď.

Rýchlosť aktualizácie informácií v uvažovanej schéme bude štyrikrát nižšia ako frekvencia generátora. To znamená, že na získanie frekvencie blikania indikátora 100 Hz je potrebná frekvencia generátora 400 Hz.

Koľkokrát sme tým znížili počet pripojovacích vodičov? Záleží na tom, kde nakreslíme prierez obvodu. Ak na indikačnej doske ponecháme len indikátory, tak ich činnosť si vyžiada 7 informačných signálov pre segmenty a štyri spínacie signály. Spolu je to 11 vodičov. V statickom zobrazovacom obvode by sme potrebovali 7×4=28 vodičov. Ako vidíte, výhry sú zrejmé. Pri implementácii 8-bitovej zobrazovacej jednotky bude zisk ešte väčší.

Ešte väčší zisk bude, ak sa prierez obvodu nakreslí pozdĺž vstupov indikátorov. V tomto prípade bude štvormiestna zobrazovacia jednotka vyžadovať iba šesť signálnych vodičov a dva vodiče napájania obvodu. Takýto bod prierezu dynamického zobrazovacieho obvodu sa však používa veľmi zriedka.

Teraz vypočítajme prúd, ktorý preteká každým segmentom LED, keď sa rozsvieti. Na to použijeme ekvivalentný obvod toku prúdu cez jeden zo segmentov indikátora. Tento diagram je znázornený na obrázku 2.


Ako už bolo spomenuté, LED vyžaduje na normálnu prevádzku prúd 3 až 10 mA. Nastavíme minimálny prúd LED na 3 mA. V pulznom režime prevádzky však jas indikátora N-krát klesne, pričom koeficient N sa rovná pracovnému cyklu prúdových impulzov dodávaných do tohto indikátora.

Ak chceme zachovať rovnaký jas žiary, tak musíme N-krát zvýšiť veľkosť impulzného prúdu pretekajúceho segmentom. Pre osemmiestny ukazovateľ sa koeficient N rovná ôsmim. Najprv zvolíme statický prúd cez LED rovnajúci sa 3 mA. Potom, aby sa zachoval rovnaký jas LED v osemcifernom indikátore, bude potrebný impulzný prúd:

I seg din = I seg stat× N= 3 mA × 8 = 24 mA.

Len niektoré série digitálnych mikroobvodov sotva dokážu poskytnúť taký prúd. Pre väčšinu sérií mikroobvodov budú potrebné zosilňovače vyrobené na tranzistorových spínačoch.

Teraz si určme prúd, ktorý potečie prepínačom, ktorý prepína napájanie jednotlivým bitom osembitovej zobrazovacej jednotky. Ako je zrejmé z diagramu znázorneného na obrázku 2, kľúčom môže pretekať prúd z ktoréhokoľvek segmentu indikátora. Keď sa zobrazí číslo 8, všetkých sedem segmentov indikátora bude musieť svietiť, čo znamená, že impulzný prúd pretekajúci kľúčom v tomto momente možno určiť nasledovne:

I cl = I segding× N seg= 24 mA × 7 = 168 mA.

Ako sa vám páči tento prúd?! V rádioamatérskych obvodoch sa často stretávam s riešeniami, kde je spínací prúd odoberaný priamo z výstupu dekodéra, ktorý nedokáže vyprodukovať prúd väčší ako 20 mA a kladiem si otázku – kde mám takýto indikátor hľadať? V úplnej tme? Výsledkom je „zariadenie na nočné videnie“, teda zariadenie, ktorého hodnoty sú viditeľné iba v úplnej tme.

Teraz sa pozrime na schematický diagram výslednej zobrazovacej jednotky. Je to znázornené na obrázku 3.



Obrázok 3. Schéma dynamickej zobrazovacej jednotky

Teraz, keď sme dostali dynamický zobrazovací obvod, môžeme diskutovať o jeho výhodách a nevýhodách. Nepochybnou výhodou dynamického zobrazenia je malý počet prepojovacích vodičov, čo ho v niektorých prípadoch robí nepostrádateľným, napríklad pri práci s maticovými indikátormi.

Nevýhodou je prítomnosť veľkých impulzných prúdov a keďže akýkoľvek vodič je anténa, dynamická indikácia slúži ako silný zdroj rušenia. Ďalším zdrojom rušenia je napájanie.

Upozorňujeme, že nábehové hrany spínacích impulzov sú veľmi krátke, takže ich harmonické zložky pokrývajú rádiový frekvenčný rozsah až po ultrakrátke vlny.

Použitie dynamickej indikácie teda umožňuje minimalizovať počet spojovacích vodičov medzi digitálnym zariadením a indikátorom, ale zároveň je silným zdrojom rušenia, takže jeho použitie v rádiových prijímacích zariadeniach je nežiaduce.

Ak je z nejakého dôvodu, napríklad potreba použiť maticové indikátory, potrebné použiť dynamickú indikáciu, potom je potrebné prijať všetky opatrenia na potlačenie rušenia.

Opatrenia na potlačenie rušenia z dynamickej indikácie zahŕňajú tienenie jednotky, prepojovacieho kábla a dosiek. Použitie minimálnej dĺžky pripojovacích vodičov s použitím filtrov napájacieho zdroja. Pri tienení bloku môže byť potrebné tieniť samotné indikátory. V tomto prípade sa zvyčajne používa kovová sieť. Táto mriežka môže súčasne zvýšiť kontrast zobrazených znakov.

Literatúra:

Spolu s článkom „Dynamické zobrazenie“ si prečítajte:

Indikátory sú navrhnuté tak, aby osobe zobrazovali rôzne typy informácií. Najjednoduchší typ informácií je...
http://site/digital/Indic.php

Indikátory vypúšťania plynu sa používajú na indikáciu bitovej informácie a na zobrazenie desatinnej informácie. Pri konštrukcii desatinných indikátorov je katóda...
http://site/digital/GazIndic/

V súčasnosti sa LED diódy používajú takmer všade na zobrazovanie binárnych informácií. Je to spôsobené...
http://site/digital/LED.php

Princípy činnosti indikátorov z tekutých kryštálov... Prevádzkové režimy indikátorov z tekutých kryštálov... Vytváranie farebného obrazu...
http://site/digital/LCD.php

Dynamické zobrazenie je jedným z problémov, ktorým čelia začínajúci programátori mikrokontrolérov. Veľa sa o tom hovorilo, ale rozhodol som sa zálohovať to, čo je známe, pomocou obrázkov a príkladov zdrojového kódu v C, aby som si uľahčil zvládnutie tejto metódy zobrazenia.

1 Základy alebo úvod

V prvom rade si definujme terminológiu, ktorú budeme v celom článku používať.

Ak potrebujete ovládať displej pozostávajúci z jedinej sedemsegmentovej familiárnosti, nespôsobuje to žiadne problémy – možno si to predstaviť ako 8 nezávislých LED. Ak potrebujete zobraziť viac informácií ako jeden znak, začínajú problémy: 2 známe miesta tvoria 16 LED diód, tri - 24 atď., To znamená, že pre trojmiestny displej jednoducho nemusí byť dostatok pinov mikrokontroléra. uveďte 6 alebo viacmiestne displeje a najmä maticové ukazovatele.

Pre zjednodušenie sa dohodnime, že všetky naše indikátory majú spoločnú katódu. Riešenie problému je pomerne jednoduché: pripojte svorky segmentov všetkých indikátorov k sebe. Teraz, ak chcete vydávať informácie na prvé známe miesto, mali by ste použiť požadované úrovne na segmentové čiary a pripojiť spoločný výstup prvého indikátora k spoločnému vodiču obvodu. Samozrejme, vysoké hladiny musia byť prítomné na spoločných katódach všetkých ostatných indikátorov. Je zrejmé, že sa rozsvietia potrebné segmenty prvého indikátora. Pre výstup do druhého, tretieho atď. indikátory by mali robiť to isté, t.j. Aplikovaním logickej nuly na jednu zo spoločných katód vyberieme aktuálne zobrazenú číslicu a stav segmentových čiar určuje viditeľný symbol.

Aby bol celý displej vnímaný ako nepretržite žiariaci, číslice by sa mali prepínať rýchlo – viac ako 25-krát za sekundu. Ako vidíte, úrovne všetkých výstupov (ktoré sa mimochodom výrazne zmenšili ako pri bežnom prístupe) sa priebežne menia, t.j. majú nie statické úrovne, ale dynamické, odtiaľ názov indikačnej metódy – dynamický.

Dynamický zobrazovaný obraz

2 Typy hardvérovej implementácie

2.1 Ploché matice

Ak abstrahujeme od sedemsegmentových indikátorov, náš displej možno znázorniť ako maticu jednotlivých LED diód, ktorých anódy sú spojené do riadkov matice a katódy do stĺpcov. Vlastne je to presne tak.

Je zrejmé, že dodaním požadovaných úrovní do riadkov a stĺpcov našej matice môžeme rozsvietiť akýkoľvek elementárny segment LED (známy ako pixel - toto je tradičnejší pojem vo vzťahu k maticovým displejom). V závislosti od toho, ako presne meníme úrovne v riadkoch a stĺpcoch, môžeme získať niekoľko typov dynamického zobrazenia:

  • po riadkoch;
  • podľa stĺpcov;
  • segment po segmente (na pixel);
  • zmiešaným spôsobom.

Na možnosť stĺpca sme sa pozreli v predchádzajúcej kapitole. Možnosť riadku sa od nej líši len tým, že riadky a stĺpce našej matice sú prehodené. Metóda segmentu po segmente znamená, že v každom danom čase iba jeden riadok a jeden stĺpec obsahuje úroveň potrebnú na rozsvietenie LED. To znamená, že v ľubovoľnom čase môže svietiť iba jedna LED celej matice (na rozdiel od predchádzajúcich možností, kedy sa môže rozsvietiť celý riadok alebo celý stĺpec súčasne). Tento spôsob pripomína skenovanie televízora, kedy lúč prechádza okolo celej obrazovky a osvetľuje fosfor na tých správnych miestach. Zmiešaná možnosť, ako už názov napovedá, spočíva v tom, že súčasne „aktívne“ úrovne môžu byť prítomné na niekoľkých riadkoch a stĺpcoch naraz.

Prvé dve možnosti sú veľmi jednoduché na implementáciu, a preto sú široko používané. Tretia možnosť sa používa menej často, pretože vyžaduje vyššiu rýchlosť aktualizácie informácií v riadkoch a stĺpcoch a priemerný prúd cez segment (t. j. jas segmentu) je v tomto prípade výrazne nižší ako v iných. Posledná zmiešaná metóda je najmenej častá, hoci má množstvo pozitívnych vlastností. V prvom rade táto metóda vyžaduje, aby sa v radových a stĺpcových obvodoch používali stabilné zdroje prúdu, inak bude jas svetelných segmentov nevyhnutne závisieť od ich celkového počtu. A výpočet kombinácií signálov v riadkoch a stĺpcoch nie je veľmi jednoduchý.

2.2 Viacrozmerné matice

Príklady, ktoré sme uvažovali, predpokladajú implementáciu monochromatického displeja, t.j. pozostávajúce z jednofarebných LED diód. Čo robiť, ak chcete získať viacfarebný displej napríklad z RGB LED? Sú dve možné riešenia.

Prvým je jednoducho zvýšiť počet riadkov (alebo stĺpcov) našej matice, pričom každá RGB LED sa považuje za 3 nezávislé samostatné LED. Veľkou nevýhodou tohto prístupu je trojnásobné zvýšenie počtu riadkov (alebo stĺpcov). Jednoduchý príklad ľahko ukazuje, čo to v praxi znamená: pomocou dvoch osembitových mikrokontrolérov mikrokontrolérov môžeme mať monochromatickú maticu segmentov 8x8 alebo farebnú maticu 4x4. Súhlaste, že v druhom prípade je prakticky nemožné zobraziť čokoľvek zrozumiteľné...

Druhým spôsobom je prejsť od „plochej“ matice segmentov k „multidimenzionálnej“. Ak signál každého riadku prechádza cez multiplexer 1x3, potom si môžeme systém zobrazenia RGB LED predstaviť ako 3 nezávislé matice pôvodného rozmeru: každá matica pozostáva z LED diód rovnakej farby a pomocou multiplexora vyberieme požadovanú maticu. riadiace signály. Obrázok vysvetľuje, čo bolo povedané.

Je zrejmé, že v prípade viacrozmernej matice je potrebný aj dodatočný počet riadiacich čiar, avšak tento počet nie je taký veľký: na rovnakých dvoch portoch ovládača môžeme získať farebný displej 7x7!!!

2.3 Spôsoby zmenšenia rozmerov matíc

Ak je počet pinov mikrokontroléra veľmi obmedzený, budeme musieť hľadať spôsoby, ako znížiť počet riadkov a stĺpcov našej matice. Samozrejme, zázraky sa nedejú a v tomto prípade budeme musieť zaplatiť použitím ďalších mikroobvodov okrem mikrokontroléra. Ako ste možno uhádli, tu môžete použiť predtým diskutovanú metódu „multidimenzionálnych“ matíc - nikto nám predsa nezakáže jednoducho použiť trojnásobný počet jednofarebných LED namiesto RGB LED? Hlavná vec je správne ich usporiadať...

Takže môžeme zmenšiť rozmer matice pomocou:

  • dekodéry alebo multiplexory;
  • posuvné registre.

S multiplexermi sme sa už stretli skôr, dekodér, ako tušíte, sa zásadne nelíši od multiplexora. Treba len dodať, že použitím dekodérov/multiplexorov pre riadky aj stĺpce je možné zmenšiť rozmer matice pozdĺž oboch rozmerov naraz, ale v tomto prípade môže byť potrebné použiť iba dynamickú indikáciu segmentu po segmente, so všetkými jeho nevýhodami.

Posunové registre môžu pomôcť oveľa lepšie ako dešifrovače. Zvážte schému na obrázku nižšie.

Je ľahké vidieť, že akýkoľvek počet riadkov a stĺpcov bude vyžadovať iba zvýšenie počtu registrov a počet zapojených riadiacich liniek mikrokontroléra zostane rovnaký! Malou nevýhodou tohto prístupu je, že so zvyšujúcim sa počtom registrov v reťazci sa bude musieť zvýšiť rýchlosť sekvenčného výstupu informácií do nich, čo nie je vždy ľahké dosiahnuť. Napríklad bežné mikrokontroléry rodiny AVR, prakticky neumožňujú prekročiť sériovú výstupnú rýchlosť 10 megabitov/s. Na druhej strane, ak použijete iné ovládače, ktoré dokážu vydávať signály rýchlejšie, môžu nastať problémy iného poradia: šírenie vysokofrekvenčného hodinového signálu pozdĺž dlhého vedenia (a pri veľkom počte registrov to bude nevyhnutne jeden ) sa vyskytuje úplne inak ako nízkofrekvenčný, takže pri rozmiestnení dosky plošných spojov a ďalších veciach, ktoré nebudeme v tomto článku uvažovať, budú potrebné špeciálne opatrenia.

3 Metódy implementácie softvéru

Nebudeme uvažovať o softvérovej implementácii všetkých spomínaných možností dynamického zobrazenia – to by článok neprimerane nafúklo. Obmedzíme sa len na tri najpopulárnejšie príklady: plochú maticu s priamym riadením riadkov a stĺpcov, to isté s použitím dekodéra a napokon variant s použitím posuvných registrov. Vo všetkých prípadoch sa bude venovať osobitná pozornosť všetkým nuansám implementácie softvéru, to znamená, že kód C bude sprevádzať vysvetlenia iba v prípadoch, keď sa to zhoduje so zámerom autora, a vôbec nie s vašou úrovňou školenia. . Týmto naznačujem, že by ste mali poznať základy C bezo mňa.

Pre všetky príklady sa zhodneme, že náš displej je postavený na sedemsegmentových indikátoroch so spoločnou katódou.

3.1 Najjednoduchší spôsob

Je zrejmé, že v programe by bolo najpohodlnejšie mať určité pole, ktorého obsah by jednoznačne určil, ktoré segmenty v ktorých známych oblastiach displeja svietia - akýsi analóg RAM na obrazovke.

Uveďme definíciu nasledujúcich konštánt:

#define SCR_SZ 6 /* počet oboznámení sa s displejom */ #define ROWS PORTB /* port zobrazenia “riadkov”, t.j. správa segmentov */ #define COLS PORTD /* port správy „stĺpca“, t.j. spoločné katódy */

Teraz deklarujme pole obrazovky:

Unsigned char SCR;

Na začiatok budeme predpokladať, že každý prvok poľa zodpovedá známosti displeja a každý bit tohto prvku zodpovedá konkrétnemu segmentu indikátora. Ktorý bit zodpovedá ktorému segmentu – v tomto prípade na tom nezáleží, rovnako ako nezáleží na tom, ako sú tieto bity nastavené v bajtoch nášho poľa, zatiaľ len predpokladáme, že tam už sú. Pre jednoduchosť budeme tiež predpokladať, že spoločné katódy sú pripojené k pinom portu COLS postupne: najmenej významný bit je indikátor úplne vpravo, potom druhý, potom tretí atď.

Ako dosiahnuť, aby sa toto pole „zobrazilo“ na displeji? Napíšeme nasledujúci kód:

< SCR_SZ; pos++){ ROWS = SCR; COLS = ~(1 << pos); }

Bude vykonávať požadovanú funkciu? Áno. Ale to nie je dobré.

V prvom rade si uvedomte, že nemáme žiadnu kontrolu nad tým, ako rýchlo sa aktualizuje obsah riadkov a stĺpcov. Po druhé, všimnite si, že v čase, keď sa nový prvok poľa vytlačí RIADKY na linkách COLS Starý význam je stále prítomný! Kam to vedie? Okrem toho na zlomok sekundy oboznámená oblasť zobrazí segmenty susednej familiárnej oblasti, t.j. niektoré segmenty budú falošne osvetlené.

Tomuto efektu sa môžete vyhnúť takto: pred aktualizáciou obsahu RIADKY, vždy zhasnite známe miesto, ktoré bolo predchádzajúce. Aby ste sa neobťažovali s určovaním predchádzajúcej známosti, môžete všetko uhasiť naraz. Náš kód má teda nasledujúcu formu:

Nesigned char poz; while(1) for(pos = 0; poz< SCR_SZ; pos++){ COLS = 0xFF; ROWS = SCR; COLS = ~(1 << pos); delay(); }

Pridali sme zatemnenie celého displeja pred aktualizáciou stavu segmentových čiar (vyslaním spoločných katód vysoko vypneme indikátor bez ohľadu na to, čo sa nachádza na anódach) a zaviedli oneskorenie na konci cyklu. Teraz bude displej fungovať oveľa lepšie. Ale napísali sme dobrý program? Bohužiaľ nie.

Faktom je, že nekonečný cyklus zobrazovania zatiaľ čo proste nám to nedovolí robiť nič iné. Čo to budeme mať za program, ktorý dokáže niečo zobraziť len na ukazovateli?! Samozrejme, všetko nie je 100% zlé, keďže niečo užitočné sa dá urobiť pomocou prerušení... a namiesto oneskorenia meškanie () môžete vykonávať niektoré akcie... Ale toto všetko je veľmi, veľmi pokrivené: nie je vhodné vykonávať niečo zložité a ťažkopádne v obsluhe prerušení; na druhej strane, ak namiesto oneskorenia robíte niečo zložité a ťažkopádne, potom je ťažké zabezpečiť rovnaký výpočtový čas, inak sa ukáže, že známe miesta žiaria rôzne časové obdobia, ktoré budú vizuálne vyzerať ako ich žiara alebo blikanie rôzneho jasu.

Vo všeobecnosti možno túto možnosť povoliť len ako výnimku, len ako vyučovací príklad, alebo v prípade (ale opäť len výnimočne!), keď je hlavný riešený problém veľmi jednoduchý (môže to byť napr. , problém merania pomocou ADC napätie a zobrazte ho na displeji).

Čo by si mal urobiť? Odpoveď je ako vždy jednoduchá: všetky procesy, ktoré sa musia vykonať bez povšimnutia pri riešení hlavnej úlohy (a indikáciou, samozrejme, je taký proces), by sa mali vykonávať pomocou prerušení časovača.
Prerušenia budú prichádzať v presne stanovených intervaloch, čo zabezpečí rovnomerné osvetlenie známych nápisov. Indikácia pozadia nám umožní jednoducho zapísať niečo do poľa v správnom čase v hlavnej slučke SCR- a okamžite sa objaví na displeji! A všetky úpravy kódu sa zredukujú na skutočnosť, že namiesto slučiek používame funkciu obsluhy prerušení:

ISR(TIMER0_OVF_vect)( statický znak bez znamienka pos = 0; COLS = 0xFF; ROWS = SCR; COLS = ~(1<< pos); if(++pos == SCR_SZ) pos = 0; }

Pár komentárov.

Variabilné poz, s uvedením čísla aktuálneho svetelného znaku, urobíme z neho lokálnu statickú premennú tak, aby si zachovala svoju hodnotu od prerušenia po prerušenie. Na konci funkcie nezávisle (veď už nemáme slučku) zvyšujeme číslo známeho miesta, až kým nedosiahneme limit – v tomto prípade ideme opäť na začiatok.

V hlavnom programe budeme musieť iba inicializovať porty a časovač (v tomto prípade - Časovač 0), aby pretekala v intervaloch, ktoré potrebujeme, a umožňovala prerušenia. Potom už nemusíte premýšľať o indikácii - bude fungovať ticho a pokojne sama. Ale ako určiť požadovaný interval pretečenia časovača? Veľmi jednoduché. Ľudské oko vníma blikanie s frekvenciou vyššou ako 25 Hz ako nepretržitú žiaru. Máme 6 indikátorov, každý z nich by mal blikať s touto frekvenciou, čo znamená, že informácie na displeji by sa mali aktualizovať s frekvenciou 25 x 6 = 150 Hz alebo viac. Teraz vypočítajme hodnotu preddeličky časovača: vydeľte hodinovú frekvenciu MK 256 ( Časovač 0 každý má AVR osembitový, čo znamená, že po napočítaní do 256) pretečie – to bude požadovaná hodnota preddeličky časovača. Samozrejme, je nepravdepodobné, že by sa výsledok zhodoval s jednou zo štandardných hodnôt preddeličky - to nie je problém, môžete si vziať najbližšiu menšiu vhodnú hodnotu. Displej bude pracovať na vyššej frekvencii, ale to nezhorší jeho kvalitu! Vedľajším efektom bude veľká záťaž jadra MK pre displej. Ak to výrazne ruší hlavný program, budete musieť prepnúť zobrazenie na iný časovač, napríklad 16-bitový Časovač 1 alebo zadajte počítadlo pre vynechané pretečenia časovača:

#define SKIP 15 /* počet prerušení časovača na preskočenie */ ISR(TIMER0_OVF_vect)( statický znak bez znamienka pos = 0; preskočenie statického znaku bez znamienka = SKIP; if (--skip) return; skip = SKIP; COLS = 0xFF; ROWS = SCR; COLS = ~(1<< pos); if(++pos == SCR_SZ) pos = 0; }

V týchto zjednodušených príkladoch predpokladáme, že do portu COLS, okrem spoločných katód indikátorov nie je nič iné pripojené. V skutočnom živote sa však takéto šťastie nestáva často a so zvyšnými linkami tohto portu je s najväčšou pravdepodobnosťou spojené niečo iné. Preto by ste pri organizovaní dynamického zobrazenia mali vždy zabezpečiť, aby stav všetkých liniek portov, ktoré nie sú priamo zapojené do zobrazenia, zostal nezmenený. To sa robí jednoducho: namiesto jednoduchého zapisovania novej hodnoty do portu by ste mali použiť maskovanie nepotrebných bitov:

COLS |= 0x3F; // takže zhasneme všetky známe miesta COLS &= ~(1<

Obaja operátori nemenia hodnotu najvýznamnejších bitov portu COLS.

3.2 Metóda s dekodérom

Dekodér je možné použiť buď na konverziu HEX alebo BCD kód na sedemsegmentové symboly, alebo na výber jedného zo stĺpcov matice. Obidve možnosti sa budú líšiť od najjednoduchšej metódy diskutovanej skôr len v tom, ako bude organizovaný výstup na porty RIADKY a/alebo COLS, ku ktorému budú pripojené vstupy dekodéra.
Možnosť použitia dekodéra na získanie sedemsegmentového symbolu:

ISR(TIMER0_OVF_vect)( statický znak bez znamienka = 0; COLS |= 0x3F; ROWS = (ROWS & 0xF0) | (SCR & 0x0F); COLS &= ~(1<< pos); if(++pos == SCR_SZ) pos = 0; }

Ako vidíte, zmeny sú minimálne - pred zobrazením RIADKY znakový kód z poľa SCR, sú maskované najvýznamnejšie bity a potom sa nastavujú najmenej významné bity v súlade s kódom znaku. To znamená, že sa domnievame, že dekodér je pripojený k 4 najmenej významným bitom portu RIADKY.

Dúfam, že nemá zmysel uvádzať príklad na dekódovanie stĺpcov - všetko je už jasné.

3.3 Spôsob registrácie

Aj keď sa dynamická indikácia pomocou posuvných registrov zásadne nelíši od predtým diskutovaných metód, existuje niekoľko možností jej implementácie. Budeme uvažovať o najjednoduchšom - výstup bitov čisto softvérovo. A pri implementácii iných (pomocou USI/USART/SPI/TWI), môžete si to vyskúšať sami.

Pre variant predtým zvoleného zobrazenia 6 a sedemsegmentových známych miest používame 2 posuvné registre typu 74HC595. Tento register je riadený tromi signálmi: hodinovými impulzmi sériového vstupu dát CLK, samotné údaje ÚDAJE a impulz simultánneho paralelného výstupu informácií zapísaných v registri SET. Poďme deklarovať zodpovedajúce makrá (pre jednoduchosť pošleme všetky signály na jeden port):

#define CLK _BV(PB0) #define DATA _BV(PB1) #define SET _BV(PB2) #define REG_PORT PORTB

Na zápis do registra je vhodné napísať samostatnú funkciu:

Static void shift(unsigned char d)( unsigned char i; for (i=0; i< 8; i++){ // устанавливаем нужный уровень DATA if(d & 1) REG_PORT |= DATA; else REG_PORT &= ~DATA; REG_PORT |= CLK; // даем импульс CLK REG_PORT &= ~CLK; d >>= 1; } }

Je veľmi vhodné, aby bola táto funkcia statická, pretože použije sa v obsluhe prerušení. Kompilátor s najväčšou pravdepodobnosťou vytvorí statické funkcie vo formulári v rade-vloženia do obsluhy prerušení, t.j. nebude sa zbytočne používať zásobník, čo nie je zaručené pre nestatické funkcie.

Teraz bude naša obsluha prerušení vyzerať takto:

ISR(TIMER0_OVF_vect)( statický znak bez znamienka pos = 0; shift(SCR); shift(~(1)<< pos)); REG_PORT |= SET; // выдаем импульс SET REG_PORT &= ~SET; if(++pos == SCR_SZ) pos = 0; }

Keďže údaje zapísané do registrov sa na jeho výstupoch objavujú súčasne, nie je potrebné najskôr zhasnúť indikátory. Malo by sa pamätať na to, že softvérový sekvenčný výstup je pomerne dlhý proces, najmä pre matice veľkých rozmerov, takže by mal byť čo najviac optimalizovaný na rýchlosť. To sa dá najlepšie urobiť pomocou hardvéru sériového výstupu, ktorý sa nachádza v MCU.

4 Pre tých, ktorí nikdy nemajú dosť

Takže ste sa oboznámili so základmi implementácie dynamického zobrazenia. Ale ako to už býva, otázok neubúda, ale pribúda. Predvídajúc niektoré z nich sa pokúsim okamžite poskytnúť potrebné odpovede.

4.1 Anódy, katódy - čo si vybrať?

Všetko, čo sme predtým zvážili, sa týkalo indikátorov so spoločnými katódami. Čo ak ho chcete použiť so spoločnými anódami? Vo všeobecnosti zostáva všetko rovnaké, až na to, že pred výstupom bude potrebné invertovať údaje - vymazanie známosti sa vykonáva výstupom núl v COLS, zapaľovanie - respektíve jednotky a segmenty v RIADKY bude obsahovať nuly namiesto jednotiek. Takže obsluha prerušenia by vyzerala asi takto:

ISR(TIMER0_OVF_vect)( statický znak bez znamienka pos = 0; COLS &= 0xC0; ROWS = ~SCR; COLS |= (1<< pos); if(++pos == SCR_SZ) pos = 0; }

Je to jednoduché. Pokiaľ sa, samozrejme, nepokúsite napísať univerzálny kód vhodný pre spoločné anódy aj spoločné katódy. Existujú dva spôsoby, ako to urobiť: buď pomocou direktív podmienenej kompilácie alebo pomocou konverznej funkcie. Ukážem prvú možnosť a navrhnem, aby ste o druhej premýšľali sami.

#define COMMON_ANODE 1 ISR(TIMER0_OVF_vect)( statický znak bez znamienka pos = 0; #if COMMON_ANODE != 1 COLS &= 0xC0; ROWS = ~SCR; COLS |= (1<< pos); #else COLS |= 0x3F; ROWS = SCR; COLS &= ~(1 << pos); #endif if(++pos == SCR_SZ) pos = 0; }

Aj keď je to trochu ťažkopádne, po napísaní ho môžete použiť vo všetkých projektoch prakticky bez zmien.

4.2 Blikanie

V mnohých prípadoch sa displej používa nielen ako prostriedok na zobrazenie informácií prichádzajúcich zvnútra zariadenia, ale aj na zobrazenie používateľského vstupu. A v tomto prípade je potrebné vedieť na displeji nejako oddeliť nemenné od premenlivého. Najjednoduchší spôsob, ako to urobiť, je nechať blikať zodpovedajúce známe miesto (alebo niekoľko známych miest).

Je to veľmi jednoduché. Predstavme si globálnu premennú, ktorej každý jednotkový bit bude označovať blikajúci symbol:

blikajúci znak bez znamienka = 0;

Teraz trochu upravíme obsluhu prerušení:

ISR(TIMER0_OVF_vect)( statický znak bez znamienka = 0; statický znak bez znamienka = 0; COLS |= 0x3F; if(!(bliknutie & (1)<

Ako vidíte, pribudla len jedna statická premenná – počítadlo vstupov do obsluhy prerušení vstup a operátor testovania stavu. Logika je jednoduchá: výstup ďalšej familiárnosti sa vykonáva iba vtedy, ak je buď v príslušnom bite blikať nula alebo najvýznamnejší bit počítadla vstup sa rovná 1. Ak, predpokladajme, blikať obsahuje všetky nuly, potom je táto podmienka vždy splnená - zobrazia sa všetky známe miesta. Ak blikať obsahuje v jednom zo svojich bitov 1, potom sa príslušný znak rozsvieti iba v čase, keď sa najvýznamnejší bit počítadla rovná 1. Keďže počítadlo sa zvyšuje pri každom zadaní obsluhy prerušenia, príslušný znak sa blikanie s frekvenciou 128-krát menšou ako je frekvencia prerušenia.

4.3 Nastavenie jasu segmentov

O úprave jasu som písal v samostatnom článku, ktorý sa tak volal.

4.4 Ľubovoľné rozmiestnenie kolíkov

Už skôr bolo povedané, že šťastie z vyhradenia celého portu MK na zobrazenie je dosť zriedkavé. Je však ešte zriedkavejšie získať pohodlnú stopu dosky s plošnými spojmi, ak sa jeden port používa výhradne pre riadky a druhý port sa používa pre stĺpce matice displeja. Oveľa častejšie sa optimálne sledovanie dosiahne iba vtedy, keď sa riadky a stĺpce zmiešajú medzi dvoma alebo dokonca viacerými portami mikrokontroléra. Ak počas zobrazovania zorganizujete softvérové ​​preusporiadanie bitov, nebudete musieť obetovať krásu dosky plošných spojov.

Pozrime sa na nejaký abstraktný príklad. Nech je zabezpečené najlepšie sledovanie s nasledujúcim rozložením signálov pozdĺž línií portov MK:

Segment A

Segment B

Segment H

Segment C

Segment D

Segment G

Segment E

Segment F

Ako vidíte, maticové riadky sú zmiešané medzi tromi portami a všetky nepoužívané riadky týchto portov by prirodzene nemali meniť svoju úroveň počas procesu zobrazovania.

Najlepšie je začať s vývojom dynamickej indikačnej funkcie pre tento prípad distribúciou segmentov cez symbolové bity. Predtým sme verili, že v poli SCR Ukladáme bitové masky postáv, t.j. Jednotky v byte označujú svetelné segmenty. Nerozmýšľali sme nad tým, ktorý bit zodpovedá ktorému segmentu. Takže teraz je čas sa nad tým zamyslieť.

Účel portových línií je vhodné namaľovať vo forme troch dosiek:

1

A

0

4

H

3

2

B

F

E

5

G

D

C

Musíme zhromaždiť všetky segmenty do jedného bajtu. Toto sa bude musieť vykonať pri zmenových operáciách, takže by ste sa ich mali pokúsiť rozdeliť tak, aby ste urobili minimum zmien. Poďme sa rozprávať.

Ak sa segment bit FEGDC nechajte v symbole tak, aby spadli do PORTD bez posunov, potom segment H môže zostať aj v 6. bite symbolu a tiež sa nemusí pred výstupom posúvať PORTC, ale pre segmenty A A IN zostanú bity 7 a 3, teda s najväčšou pravdepodobnosťou segment IN bude musieť byť pred výstupom posunuté o 3 pozície a segment A- do 6. Zameriam sa na túto možnosť a môžete pokračovať v hľadaní minimálnych posunov (posuny o viacero pozícií nie sú až taká rýchla operácia, preto je vhodné ich počet zredukovať na minimum).

Takže v našom prípade bolo rozloženie bitov cez znakový bajt nasledovné:

A

H

F

E

B

G

D

C

Označme bitové masky pre výstup na príslušné porty:

D

0

0

1

1

0

1

1

1

0x37

B

1

0

0

0

0

0

0

0

0x80

C

0

1

0

0

1

0

0

0

0x48

Pomocou týchto masiek používame operáciu „bitový AND“ na výber potrebných bitov pre výstup na port.

Deklarujme konštanty masky:

#define MASKD 0x37 #define MASKB 0x80 #define MASKC 0x48

Predtým sme vypisovali symbol na jeden port RIADKY, teraz bude tento postup rozdelený do troch častí:

PORTD = (PORTD & ~MASKD) | (SCR & MASKD); PORTB = (PORTB & ~MASKB) | ((SCR & MASKB) >> 6); PORTC = (PORTC & ~MASKC) | ((SCR & _BV(6)) | (((SCR & _BV(3)) >> 3);

Upozorňujeme, že pre výber na PORTC jeden bit musí byť na výstupe bez posunu a druhý - s posunom, takže namiesto MASKC Musel som použiť samostatné makrá _BV().

Teraz zostáva rozhodnúť, ako uhasiť a osvetliť zodpovedajúce známe miesta. Deklarujme konštanty zodpovedajúce bitom kontroly známosti:

#define COM0 _BV(0) #define COM1 _BV(3) #define COM2 _BV(4) #define COM3 _BV(5) #define COM4 _BV(7) #define COM5 _BV(3) #define COM_D (COM5) #define COM_C (COM2 | COM3 | COM4) #define COM_B (COM0 | COM1)

Ak chcete uhasiť všetkých známych, musíte do portov vypísať príslušné konštanty COM_x:

PORTD |= COM_D; PORTC |= COM_C; PORTB |= COM_B;

Ale ak chcete zapnúť známosť, budete musieť byť zradný (nemá zmysel vydávať výstup na všetky tri porty, pretože v konkrétnom porte bude aktívny iba jeden bit, v závislosti od hodnoty poz), napríklad pomocou operátora prepínač:

Switch(pos)( case 0: PORTB &= ~COM0; break; case 1: PORTB &= ~COM1; break; case 2: PORTC &= ~COM2; break; case 3: PORTC &= ~COM3; break; case 4: PORTC &= ~COM4; prerušenie; prípad 5: PORTD &= ~COM5; prerušenie; )

Nie je to najkrajší spôsob, ale funguje.

Náš obslužný program prerušení má teda nasledujúcu formu:

ISR(TIMER0_OVF_vect)( statický znak bez znamienka = 0; statický znak bez znamienka = 0; // potlačenie PORTD |= COM_D; PORTC |= COM_C; PORTB |= COM_B; // zobrazenie PORTD = (PORTD & ~MASKD) | ( SCR & MASKD); PORTB = (PORTB & ~MASKB) | ((SCR & MASKB) >> 6); PORTC = (PORTC & ~MASKC) | ((SCR & _BV(6)) | (((SCR & _BV (3)) >> 3); // blikať, ak(!(blikať & (1<< pos)) || (++entry & 0x80)) { switch(pos){ case 0: PORTB &= ~COM0; break; case 1: PORTB &= ~COM1; break; case 2: PORTC &= ~COM2; break; case 3: PORTC &= ~COM3; break; case 4: PORTC &= ~COM4; break; case 5: PORTD &= ~COM5; break; } } if(++pos == SCR_SZ) pos = 0; }

Teraz zostáva prísť na to, ako pohodlnejšie opísať symboly pre výstup... Navrhujem urobiť nasledovné: definovať konštanty zodpovedajúce bitom segmentov a potom „zostrojiť“ potrebné symboly z týchto konštánt:

// elementárne segmenty #define _A _BV(7) #define _B _BV(3) #define _C _BV(0) #define _D _BV(1) #define _E _BV(4) #define _F _BV(5) #define _G _BV (2) #define _H _BV(6) // číslicové symboly #define d_0 (_A | _B | _C | _D | _E | _F) #define d_1 (_B | _C) #define d_2 (_A | _B | _G | _D | _E) // a tak ďalej

Ak teda potrebujete zobraziť nulu úplne vpravo na displeji, stačí napísať na správne miesto:

SCR = d_0;

Ak v inom projekte potrebujete rozložiť bity inak, zmeníte iba čísla v makrách _BV() pre elementárne segmenty a všetky symboly sa automaticky „prerobia“. V najjednoduchších prípadoch opísaných na začiatku nebudete musieť robiť nič iné, ale pre možnosť „bitového preskupenia“ budete musieť, samozrejme, pohrať.

4.5 Podpora tlačidiel

Pri tradičnom nedostatku MK pinov je problém veľkého počtu tlačidiel, bez ktorých sa len málokedy zaobíde nejaké zariadenie, veľmi akútny. Používajú sa rôzne matricové inklúzie atď. triky, avšak miernym skomplikovaním funkcie dynamického zobrazenia je jednoduché mať k dispozícii toľko tlačidiel, koľko je známych na displeji a v tomto prípade budete navyše potrebovať použiť iba jeden port mikrokontroléra. Pravda, na každé tlačidlo musíte ešte nainštalovať diódu.

Toto je schematicky znázornené na obrázku.

A program vyzerá takto:

#define keypin() (!(PIND & _BV(KEY))) ISR(TIMER0_OVF_vect)( statický znak bez znamienka pos = 0; statický znak bez znamienka = 0; statický znak bez znamienka tmp_key = 0; ROWS = 0; if(keypin( )) tmp_key |= 1<< pos; COLS |= 0x3F; if(!(blink & (1<< pos)) || (++entry &0x80)){ ROWS = (ROWS & 0xF0) | (SCR & 0x0F); COLS &= ~(1 << pos); } if(++pos == SCR_SZ){ pos = 0; key = tmp_key; tmp_key = 0; } }

Tu KEY- toto je makro, ktoré nastavuje bit zvoleného portu, na ktorom sú „pripojené“ všetky tlačidlá keypin() vráti logickú hodnotu TRUE, ak je vybraný kolík logický nízky. V príklade sú tlačidlá spojené s PORTD.

Zakaždým, keď dôjde k prerušeniu časovača, všetky segmenty najskôr zhasnú - je to potrebné, aby prúd cez LED nespôsobil chybnú detekciu stlačeného tlačidla. Potom je vstup tlačidla vyzvaný - ak je úroveň nízka, znamená to, že je stlačené tlačidlo pripojené k príslušnej pozičnej katóde. Vo variabilnom tmp_key stavy tlačidiel sa zhromažďujú a prepisujú do globálnej premennej kľúč po dokončení cyklu zobrazenia. Jediné, čo musíte urobiť, je z času na čas analyzovať význam kľúč a spracovať zistené kliknutia:

Static unsigned char get_key())( unsigned char tmp = 0; tmp = key; _delay_ms(10); if(key == tmp) return tmp; else return 0; )

Táto jednoduchá funkcia zaisťuje, že tlačidlá nebudú odskakovať, napriek tomu, že vzhľadom na „dynamický“ charakter pollingu tlačidiel je pravdepodobnosť odskoku už aj tak nízka.

5 Čo ešte?

Takže ste zvládli celkom typické techniky na implementáciu dynamického zobrazenia. Myslím, že toto ti bude stačiť na prvýkrát a možno aj na celý život. Nakoniec je hlavnou vecou pochopiť techniky a algoritmy a vždy môžete sami pridať jemnosti a nuansy. Čo však ešte môže čakať „blízko“ dynamického zobrazenia?

Ako som už povedal, môžete pridať, dokonca až po nezávislú reguláciu každého segmentu.

Môžete premýšľať o optimálnosti obsluhy prerušení - na vzdelávacie účely som napísal dosť hrubý kód, ktorý som napríklad používal všade SCR, aj keď optimálne by bolo načítať hodnotu do lokálnej premennej raz a potom s jej hodnotou pracovať. Aj keď optimalizátor určite pomôže s mojím prístupom, pre cvičné účely sa oplatí vyskúšať a optimalizovať sa, sledovať sa z hľadiska veľkosti výsledného kódu a/alebo rýchlosti programu.

Môžete sa zamyslieť nad zaujímavým nápadom automatického nastavenia jasu displeja v závislosti od úrovne okolitého svetla. Ako viete, LED indikátory sú tým menej viditeľné, čím sú tmavšie - jednoducho sa rozmazávajú. Preto je v tme rozumné znížiť jas indikátorov a zvýšiť ho počas denného svetla. Najjednoduchšie je použiť samostatný fotorezistor alebo LED ako svetelný senzor, ale môžete to urobiť inak: je známe, že LED môže fungovať aj ako fotodióda, teda ak na indikáciu použijete port pripojený k vstupu ADC, potom, ak chcete, môžete zmerať foto-emf nesvietivého segmentu indikátora a použiť túto hodnotu na úpravu jasu...

Môžete sa zamyslieť nad využitím hardvéru sériového výstupu, ktorý som už naznačil.

Zaujímavú verziu úplne univerzálneho prístupu k dynamickému zobrazovaniu, s ktorou sa tiež odporúčam zoznámiť, navrhol o MOLCHEC. Stručne povedané, podstata: rozdelenie segmentov podľa bitov symbolov, priradenie portov na ovládanie indikátora, dokonca aj typ indikátora - skrátka všetky, všetky, všetky parametre - sú špecifikované vo forme konfiguračnej tabuľky v EEPROM. Na základe tejto tabuľky je všetko usporiadané programovo: od inverzie v závislosti od typu indikátora až po preusporiadanie bitov na rôznych portoch. V tomto prípade zostáva zdrojový kód programu dynamického zobrazovania vždy nezmenený a konfiguračnú tabuľku zostavuje koncový používateľ v závislosti od svojich preferencií. Metóda je skutočne univerzálna a flexibilná, je však spojená so zvýšenou spotrebou programovej pamäte.


3 pridané ARV, o 06:48 25.08.2010
Miša, na tvojom mieste by som nedával takéto kategorické výroky „ty to nedokážeš“, „nikto to nenapísal“ alebo „autorské práva“, pretože po prvé to nie je slušné a po druhé:
1. Na matici 10x16 som už dávno urobil plazivú čiaru (tak to bolo) - video z jej fungovania nájdete v tejto poznámke http://site/content/view/160/38/
2. Napísal som článok (nájdete v aktualitách - na dnes posledný) ako si vyrobiť ticker na LCD. Ak trochu namáhate mozog, potom je prerobenie algoritmu na výstup do matice maličkosťou.
3. na mojej stránke nie je ani jeden odniekiaľ skopírovaný článok (copy-paste nie je autorské právo, urobili ste preklep), všetky materiály sú úplne originálne. Mnohé stránky majú kópie týchto materiálov s mojím súhlasom (alebo so súhlasom autorov materiálov, ktorí majú plné právo publikovať svoje materiály na mnohých miestach naraz).

Komentáre môžu zanechávať iba registrovaní užívatelia.
Zaregistrujte sa alebo sa prihláste do svojho účtu.

DAby sa na indikátore zobrazilo viacmiestne číslo, musíte s ním najskôr vykonať zložitú manipuláciu, ktorá spočíva v rozbití čísla na jeho zložky. Ako príklad uvediem zobrazenie čísla 1234 na štvorsegmentovom sedemsegmentovom ukazovateli so spoločnou anódou.


Ak chcete zobraziť štvormiestne číslo, musíte vytvoriť jednu spoločnú premennú, v ktorej bude ležať číslo, ktoré chcete zobraziť (premenná W), štyri premenné, v ktorých budú uložené údaje pre každý znak (N) a ďalšie štyri premenné pre prechodné transformácie (M), aby ste sa nedotkli hlavnej premennej. Premenná musí zodpovedať hodnote, ktorá v nej bude uloženája Takže pre premennúWtypu bude postačovaťcelé číslo , pretože premenná tohto typu je schopná uložiťZmeňte hodnoty z -32768 na +32767 (aleboslovo pokiaľ neplánujete použiť záporné čísla). V premennýchNbudú tam čísla od 0 do 9, takže pomocou premennej akobyte
. A v premennýchM buderovnaké hodnoty ako v premennejW, tak nastavíme typ celé číslo .

Dim W ako celé číslo
Dim N1 As Byte
Dim N2 As Byte
Dim N3 ako Byte
Dim N4 ako Byte
Dim M1 ako celé číslo
Dim M2 ako celé číslo
Dim M3 ako celé číslo
Dim M4 ako Integer


Po deklarovaní premenných nakonfigurujeme výstupné portyktorý sa použije na pripojenie indikátora:

DDRC = &B11111111
DDRD = &B11111111


DDRC =&B 00001111 a DDRD =&B 01111111 (štyri prvé úseky prístavu Cpre anódy a prvých šesť portov D pre segmenty).

Potom priradíme k premennej W hodnotu, ktorú zobrazíme na indikátore:

W=1234

"Arial","sans-serif""> V hlavnej slučke programu priradíme premenným M hodnotu premennejW, robím toto:

M1 = W
M2 = M1
M3 = M1
M4 = M1


"Arial","sans-serif""> Toto nie je paranoja)), robí sa to s cieľom, aby všetky premenné M obsahovali rovnaký počet, pretože počas operácie priradenia môže ľahko preniknúť prerušenie (ak nejaké existuje a nie je vypnuté), do ktorého obsluhy premenlivýW môže zmeniť. A ak by zadanie vyzeralo takto: M1= W, M2= W, M3= W, M4= W premenné M budú obsahovať rôzne hodnoty, čo povedie k neporiadku v odčítaní.

Po priradení hodnôt k premenným začneme pracovať
každý z nich sa transformuje takým spôsobom, že na premennú N naraziť na hodnotu, ktorá bude
zobrazené na indikátore: v premennej
N 1 by mala byť "1", in N 2 – „2“, v N 3 – „3“ a v N 4 – „4“.

M1 = M1 / ​​1 000 " M1 = 1 234 / 1 000 = 1,234
N1 = Abs (ml) " N1 = Abs (1,234) = 1

Abs – funkcia, ktorá vracia celé číslo do premennej.Do premennej N 1 hit jeden, čo je presne to, čo bolo požadované.

Na priradenie dvojky k premennej N Operácia 2 bude trochu komplikovanejšia:

M2= M2 Mod 1000 " M2 =1234 Mod 1000 = 234
M2 = M2 / 100 " M2 = 234 / 100 = 2,34
N2 = Abs (m2) " N2 = Abs (2,34) = 2

"Arial","sans-serif""> Na začiatok funkciaMod prvé tri vrátime do premennej
číslice čísla (zvyšok delenia 1000) a potom je všetko ako v prvom prípade.

S poslednými dvoma číslicami je to takmer rovnaké:

M3 = M3 Mod100
M3 = M3 / 10
N3 = Abs (m3)

M4 = M4 Mod 10
N4= Abs (m4)


Teraz naše premenné obsahujú hodnoty, ktoré chceme zobraziť, je čas, aby mikrokontrolér kopol nohami a zobrazil tieto hodnoty na indikátore, aby sme to dosiahli, nazývame podprogram spracovania zobrazenia:

"Arial","sans-serif"">

Gosub Led

"Arial","sans-serif""> Procesor preskočí na podprogram s označenímLed:

LED:

Portc = &B00001000

"Arial","sans-serif""> Tu slúžime na vysokej úrovniPORTC .3 máme k tejto nohe pripojenú anódu prvej kategórie. Potom zvolíme, ktoré segmenty je potrebné rozsvietiť, aby sa zobrazila hodnota prvej premennej. Pre nás je jedna, takže nula bude na jej nohách Portd .1a Portd .2, čo zodpovedá segmentom Indikátor B a C.

Vyberte prípad N1









Koniec Vyberte
Čaká 5

"Arial","sans-serif""> Po rozsvietení potrebných segmentov počkajte 5 ms a pokračujte zobrazením nasledujúcich čísel:

Portc = &B00000100
Vyberte prípad N2
Prípad 0 : Portd = &B11000000
Prípad 1: Portd = &B11111001
Prípad 2: Portd = &B10100100
Prípad 3: Portd = &B10110000
Prípad 4: Portd = &B10011001
Prípad 5: Portd = &B10010010
Prípad 6: Portd = &B10000010
Prípad 7: Portd = &B11111000
Prípad 8: Portd = &B10000000
Prípad 9: Portd = &B10010000
Koniec Vyberte

Čaká 5

Portc = &B00000010

Vyberte prípad N3
Prípad 0 : Portd = &B11000000
Prípad 1: Portd = &B11111001
Prípad 2: Portd = &B10100100
Prípad 3: Portd = &B10110000
Prípad 4: Portd = &B10011001
Prípad 5: Portd = &B10010010
Prípad 6: Portd = &B10000010
Prípad 7: Portd = &B11111000
Prípad 8: Portd = &B10000000
Prípad 9: Portd = &B10010000
Koniec Vyberte

Čaká 5

Portc = &B00000001

Vyberte prípad N4
Prípad 0 : Portd = &B11000000
Prípad 1: Portd = &B11111001
Prípad 2: Portd = &B10100100
Prípad 3: Portd = &B10110000
Prípad 4: Portd = &B10011001
Prípad 5: Portd = &B10010010
Prípad 6: Portd = &B10000010
Prípad 7: Portd = &B11111000
Prípad 8: Portd = &B10000000
Prípad 9: Portd = &B10010000
Koniec Vyberte

Čaká 5

"Arial","sans-serif""> Po zobrazení informácií na indikátore sa musíte vrátiť do hlavnej programovej slučky, kde je potrebné slučku dokončiť a označiť koniec programu.

"Arial","sans-serif""> Toto dostaneme na konci:

"Arial","sans-serif"">

"Arial","sans-serif""> Kvôli malému oneskoreniu spínania nebude prepínanie pre ľudské oko viditeľné a uvidíme celé číslo 1234.

Zdroj a projekt v Proteus si môžete stiahnuť nižšie:"Arial","sans-serif"">



 


Čítať:



Triedy a priestory názvov Používanie a deklarovanie priestorov názvov

Triedy a priestory názvov Používanie a deklarovanie priestorov názvov

Triedy a priestory názvov Triedy .NET Framework Snáď najväčšou výhodou písania riadeného kódu – aspoň čo sa týka...

Brožúra na tému "počítač a deti" Správna poloha rúk

Brožúra k téme

Urobte špeciálne cvičenia pre oči! 1. Intenzívne stláčanie a uvoľňovanie očí v rýchlom tempe a časté žmurkanie očí. 2. Pohyb očí...

Snowboarding: ako to všetko začalo?

Snowboarding: ako to všetko začalo?

Snowboarding je olympijský šport, ktorý zahŕňa zostup zo zasnežených svahov a hôr na špeciálnom vybavení - snowboarde. Pôvodne zimné...

Foto, kde sa nachádza na mape sveta, popis

Foto, kde sa nachádza na mape sveta, popis

Od staroveku až po súčasnosť bolo vo svete vytvorených mnoho vodných ciest – umelých kanálov. Hlavnými úlohami takýchto umelých je uľahčiť...

feed-image RSS