V lekcii sa dozvieme o schémach pripojenia sedemsegmentových LED indikátorov k mikrokontrolérom, o tom, ako ovládať indikátory.

LED sedemsegmentové indikátory zostávajú jedným z najobľúbenejších prvkov na zobrazovanie digitálnych informácií.

To je uľahčené nasledujúcimi vlastnosťami.

  • Nízka cena. V indikačných prostriedkoch nie je nič lacnejšie ako LED digitálne ukazovatele.
  • Rôzne veľkosti. Najmenšie a najväčšie indikátory sú LED. Poznám LED indikátory s výškou číslic od 2,5 mm do 32 cm.
  • Žiari v tme. V niektorých aplikáciách je táto vlastnosť takmer rozhodujúca.
  • Majú rôzne farby svetla. Existujú dokonca dve farby.
  • Dostatočne nízke riadiace prúdy. Moderné LED indikátory je možné pripojiť k výstupom mikrokontrolérov bez ďalších kláves.
  • Umožňujú drsné prevádzkové podmienky (rozsah teplôt, vysoká vlhkosť, vibrácie, agresívne prostredie atď.). Z hľadiska tejto kvality nemajú LED indikátory medzi ostatnými typmi zobrazovacích prvkov obdobu.
  • Neobmedzená životnosť.

Typy LED indikátorov.

Sedemsegmentový LED indikátor zobrazuje znak pomocou siedmich LED segmentov číslice. Ôsma LED dióda rozsvieti desatinnú čiarku. V sedemsegmentovom ukazovateli je teda 8 segmentov.

Segmenty sú označené latinskými písmenami od „A“ do „H“.

Anódy alebo katódy každej LED sú kombinované v indikátore a tvoria spoločný vodič. Preto existujú indikátory so spoločnou anódou a spoločnou katódou.

LED indikátor so spoločnou anódou.

LED indikátor so spoločnou katódou.

Statické LED ovládanie.

K mikrokontroléru je potrebné pripojiť LED indikátory cez odpory, ktoré obmedzujú prúd.

Výpočet odporu je rovnaký ako pri jednotlivých LED.

R = (U zásobovanie - U segment) / I segment

Pre tento obvod: I segment = (5 - 1,5) / 1000 = 3,5 mA

Moderné LED indikátory svietia pomerne jasne už pri prúde 1 mA. Pre obvod so spoločnou anódou sa rozsvietia segmenty, na ktorých riadiacich výstupoch bude mikrokontrolér generovať nízku úroveň.

V schéme zapojenia indikátora so spoločnou katódou sa mení polarita napájacích a riadiacich signálov.

Rozsvieti sa segment, na ktorého riadiacom výstupe sa vytvorí vysoký stupeň(5 V).

Multiplexný režim ovládania LED.

Na pripojenie každého sedemsegmentový ukazovateľ pre mikrokontrolér je potrebných osem kolíkov. Ak existujú 3 - 4 ukazovatele (číslice), úloha sa stáva prakticky nemožným. Len málo kolíkov mikrokontroléra. V tomto prípade môžu byť indikátory pripojené v multiplexnom režime, v režime dynamickej indikácie.

Závery segmentov s rovnakým názvom každého ukazovateľa sa kombinujú. Ukazuje sa matica LED pripojených medzi výstupy segmentov a spoločné výstupy indikátorov. Tu je obvod pre multiplexné ovládanie trojmiestneho indikátora so spoločnou anódou.

Na pripojenie troch indikátorov bolo potrebných 11 kolíkov a nie 24, ako v režime statickej kontroly.

Pri dynamickej indikácii svieti vždy iba jedna číslica. Signál vysokej úrovne (5 V) sa privádza na spoločný výstup jedného z bitov a signály nízkej úrovne sa posielajú na výstupy segmentov pre tie segmenty, ktoré by mali v tomto bite svietiť. Po určitom čase sa zapáli ďalší výboj. Na jeho spoločný výstup sa aplikuje vysoká úroveň a stavové signály pre tento bit sa posielajú do segmentových výstupov. A tak pre všetky bity v nekonečnej slučke. Čas cyklu sa nazýva čas obnovenia indikátora. Ak je doba regenerácie dostatočne krátka, ľudské oko si prepínanie výbojov nevšimne. Bude sa zdať, že všetky výboje neustále svietia. Aby sa zabránilo blikaniu indikátorov, má sa za to, že frekvencia regeneračného cyklu by mala byť aspoň 70 Hz. Snažím sa používať aspoň 100Hz.

Dynamický indikačný obvod pre LED diódy so spoločnou katódou vyzerá takto.

Polarita všetkých signálov je obrátená. Teraz sa na spoločný vodič aktívneho výboja aplikuje nízka úroveň a na segmenty, ktoré by mali svietiť, sa aplikuje vysoká úroveň.

Výpočet prvkov dynamickej indikácie svetelných diód (LED) indikátorov.

Výpočet je o niečo komplikovanejší ako pri statickom režime. Pri výpočte je potrebné určiť:

  • priemerný prúd segmentov;
  • segmenty impulzného prúdu;
  • odpor segmentového odporu;
  • pulzný prúd spoločných záverov výbojov.

Pretože číslice indikátora sa postupne rozsvietia, potom jas žiary určuje priemerný prúd. Musíme si ho vybrať na základe parametrov indikátora a požadovaného jasu. Priemerný prúd určí jas indikátora na úrovni zodpovedajúcej statickému riadeniu s rovnakým konštantným prúdom.

Zvoľme priemerný segmentový prúd 1 mA.

Teraz vypočítajme impulzný prúd segmentu. Na zabezpečenie požadovaného priemerného prúdu musí byť pulzný prúd N-krát väčší. Kde N je počet číslic indikátora.

Segmujem. imp. = Segm. priem. * N

Pre našu schému som segm. imp. = 1 * 3 = 3 mA.

Vypočítame odpor rezistorov, ktoré obmedzujú prúd.

R \u003d (výkon U - segment U) / segment I. imp.

R \u003d (5 - 1,5) / 0,003 \u003d 1166 ohmov

Určujeme impulzné prúdy spoločných záverov výbojov. Súčasne môže svietiť 8 segmentov, čo znamená, že impulzný prúd jedného segmentu musí byť vynásobený 8.

I kategória imp. = Segm. imp. * osem

Pre našu schému vypúšťam imp. = 3*8 = 24 mA.

  • odpor rezistorov je zvolený 1,1 kOhm;
  • výstupy mikrokontroléra segmentového riadenia musia poskytovať prúd minimálne 3 mA;
  • výstupy mikrokontroléra na výber indikačnej číslice musia poskytovať prúd minimálne 24 mA.

Pri takýchto aktuálnych hodnotách je možné indikátor pripojiť priamo na svorky dosky Arduino, bez použitia ďalších kľúčov. Pre jasné indikátory sú takéto prúdy dosť.

Schémy s ďalšími kľúčmi.

Ak indikátory vyžadujú väčší prúd, musia sa použiť ďalšie spínače, najmä pre signály výberu číslic. Celkový vybíjací prúd je 8-násobok prúdu jedného segmentu.

Schéma zapojenia LED indikátora so spoločnou anódou v multiplexnom režime s tranzistorovými spínačmi pre voľbu číslic.

Na výber bitu v tomto obvode je potrebné generovať signál nízkej úrovne. Príslušný kľúč sa otvorí a dodá energiu do vybitia indikátora.

Schéma zapojenia LED indikátora so spoločnou katódou v multiplexnom režime s tranzistorovými spínačmi pre voľbu číslic.

Na výber bitu v tomto obvode je potrebné vygenerovať signál vysokej úrovne. Príslušný spínač otvorí a zatvorí spoločný výstup výboja so zemou.

Môžu existovať obvody, v ktorých je potrebné použiť tranzistorové spínače pre oba segmenty a spoločné výbojové vedenia. Takéto schémy sa dajú ľahko syntetizovať z dvoch predchádzajúcich. Všetky zobrazené obvody sa používajú, keď je indikátor napájaný napätím rovným napätiu mikrokontroléra.

Klávesy pre indikátory so zvýšeným napájacím napätím.

Existujú indikátory veľkých veľkostí, v ktorých každý segment pozostáva z niekoľkých LED zapojených do série. Na napájanie takýchto indikátorov je potrebný zdroj s napätím väčším ako 5 V. Spínače musia zabezpečovať spínanie vysokého napätia riadené signálmi úrovne mikrokontroléra (zvyčajne 5 V).

Obvod kláves, ktoré zatvárajú signály indikátora na zem, zostáva nezmenený. A vypínače by mali byť zostavené podľa inej schémy, napríklad tejto.

V tejto schéme je aktívny výboj vybraný vysokou úrovňou riadiaceho signálu.

Medzi prepnutím bitov indikátora na krátky čas (1-5 µs) by sa mali všetky segmenty vypnúť. Tento čas je potrebný na dokončenie prechodných procesov spínania kľúčov.

Konštrukčne možno závery výbojov kombinovať ako v jednom prípade viacmiestneho ukazovateľa, alebo zostaviť viacmiestny ukazovateľ zo samostatných jednociferných. Okrem toho môžete indikátor zostaviť z jednotlivých LED diód spojených do segmentov. Zvyčajne sa to robí, keď je potrebné zostaviť indikátor veľmi veľkých rozmerov. Všetky vyššie uvedené schémy budú platné pre takéto možnosti.

V ďalšej lekcii pripojíme k Arduino doske sedemsegmentový LED indikátor, napíšeme knižnicu na ovládanie.

Kategória: . Môžete si uložiť záložku.

Niekedy je potrebné k mikrokontroléru pripojiť niekoľko sedemsegmentových indikátorov alebo LED maticu, pričom na zobrazenie informácií slúži dynamická indikácia. Podstatou dynamickej indikácie je postupné zobrazovanie informácií na indikátoroch. Nižšie uvedený diagram ukazuje príklad pripojenia niekoľkých sedemsegmentových indikátorov (napríklad so spoločnou katódou) na implementáciu dynamickej indikácie, vo všeobecnosti, berúc do úvahy bod, sa získa 8 segmentov, ale staromódnym spôsobom sú nazval sa tak. Všetky závery (anódy) segmentov rovnakého mena sú spojené dohromady, celkovo 8 vedení, ktoré sú pripojené k mikrokontroléru cez odpory. Spoločná katóda každého indikátora je pripojená k mikrokontroléru cez tranzistor.


Algoritmus indikácie je nasledovný: najprv nastavíme požadované logické úrovne na riadkoch v závislosti od toho, ktoré segmenty musia byť zapnuté na prvom indikátore (indikácia zľava doprava), pričom vysoká logická úroveň sa má zapnúť, nízka až vypnúť segment. Ďalej aplikujeme vysokú logickú úroveň na základňu tranzistora VT1, čím je spoločná katóda prvého indikátora pripojená k spoločnému vodiču, v tomto okamihu sa rozsvietia tie segmenty, na ktorých anódach je logická jednotka. Po určitom čase (pauza) indikátor vypneme privedením nízkej logickej úrovne na bázu tranzistora, potom opäť zmeníme logické úrovne na linkách v súlade s výstupnou informáciou určenou pre druhý indikátor a odošleme signál zapnutia do tranzistora VT2. Teda v poradí v kruhovom cykle prepíname všetky ukazovatele, to je celá dynamická indikácia.

Aby ste získali solídny obraz bez blikania, prepínanie musí prebiehať vysokou rýchlosťou, aby sa zabránilo blikaniu LED diód, obnovovacia frekvencia musí byť nastavená od 70 Hz a viac, ja ju zvyčajne nastavujem na 100 Hz. Pre vyššie uvedenú konštrukciu je pauza vypočítaná nasledovne: pre frekvenciu 100 Hz je perióda 10 ms, sú len 4 indikátory, respektíve doba žiaru každého indikátora je nastavená na 10/4 = 2,5 ms. V jednom kryte sú viacmiestne sedemsegmentové indikátory, v ktorých sú rovnomenné segmenty spojené vo vnútri samotného krytu, samozrejme na ich použitie je potrebné použiť dynamickú indikáciu.

Pre implementáciu dynamickej indikácie je potrebné použiť prerušenia pri pretečení jedného z časovačov. Nižšie je uvedený kód pomocou časovača TMR0:

;Implementácia dynamickej indikácie pre 4 sedemsegmentové indikátory;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; swapf STATUS,W ; clrf STATUS ; movwf STATUS_TEMP ; ; bcf ind1 ;vypnúť 1. indikátor bcf ind2 ;vypnúť 2. indikátor bcf ind3 ;vypnúť 3. indikátor bcf ind4 ;vypnúť 4. indikátor; incf list,F ;prírastok registra list movlw .5 ;skontroluj obsah registra list xorwf list,W ;skontroluj, či sa rovná 5 btfss STATUS,Z ; goto met1 ;číslo v registri listov sa nerovná 5 movlw .1 ;číslo v registri listov je 5: zapíš číslo 1 movwf list ;do registra listov ; met1 movlw .1 ;skontroluj obsah registra list xorwf list,W , rovná sa číslu 1 btfss STATUS,Z ; goto met2 ;číslo v registri listov sa nerovná 1: skok na met2 movf datind1,W ;číslo v registri listov sa rovná 1: skopíruj movwf PORTB ;obsah registra datind1 do registra PORTB bsf ind1 ;zapni 1. indikátor met2 movlw .2 ;skontrolujte obsah registračného listu xorwf list,W , rovná sa 2 btfss STATUS,Z ; goto met3 ;číslo v registri listu sa nerovná 2: skok na met3 movf datind2,W ;číslo v registri listu je 2: skopíruj movwf PORTB ;obsah registra datind2 do registra PORTB bsf ind2 ;zapni 2. indikátor goto exxit ;skoč na štítok exxit met3 movlw .3 ;skontroluj obsah registra list xorwf list,W , rovná sa 3 btfss STATUS,Z ; goto met4 ;číslo v registri listu sa nerovná 3: skok na met4 movf datind3,W ;číslo v registri listu je 3: skopíruj movwf PORTB ;obsah registra datind3 do registra PORTB bsf ind3 ;zapni 3. indikátor goto exxit ;skoč na štítok exxit met4 movf datind4,W ;kopírovať obsah registra datind3 movwf PORTB ;do registra PORTB bsf ind4 ;zapnúť 4. indikátor; movlw .100 ;zapis 156 do casoveho registra TMR0 movwf TMR0 ; ; movwf STAV ; swapf W_TEMP,F ; swapf W_TEMP,W ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Hlavný program ................. movlw b"11010011" ; OPTION_REG, čím sa nastaví interný ; nastavenie pomeru preddeličky 1:16 ; clrf list ;vynulovanie listu registra pred spustením; prerušenia pri pretečení TMR0, vykonané; clrf datind1 ;vymazanie registrov pre výstup informácií na clrf datind2 ;indikátory, je to ekvivalentné vypnutiu clrf datind3 ;indikátory, ako indikátory so spoločnou clrf datind4 ;katódou; bcf INTCON,T0IF ;vymazať príznak prerušenia pri pretečení TMR0 bsf INTCON,T0IE ;povoliť prerušenia pri pretečení TMR0 bsf INTCON,GIE ;povoliť globálne prerušenia; movlw b"00000110" ; 13.52 príklad výstupu movwf datind1 ; movlw b"11001111" ; movwf zo dňa2 ; movlw b"01101101" ; movwf zo dňa3 ; movlwb"01011011" ; movwf zo dňa4 ; ; . ................; .................; .................; ; koniec, koniec celého programu;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Implementácia dynamickej indikácie pre 4 sedemsegmentové indikátory

;Príklad hodinovej frekvencie 4 MHz, strojový cyklus 1 µs

org 0000h ;spustenie vykonávania programu na adrese 0000h

goto Start ;prejdite na označenie Štart

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Prerušte rutinu

org 0004h ;spustenie vykonávania podprogramu na adrese 0004h

movwf W_TEMP ;uložiť hodnoty registra kľúčov

swapf STATUS,W ;

movwf STATUS_TEMP ;

bcf ind1 ;vypnite 1. indikátor

bcf ind2 ;vypnite 2. indikátor

bcf ind3 ;vypnite 3. indikátor

bcf ind4 ;vypnite 4. indikátor

incf list,F ;prírastkový list registra

movlw .5 , skontrolujte obsah registračného listu

xorwf list,W ; rovné 5

btfss STATUS,Z ;

goto met1 ;číslo v registrovom liste sa nerovná 5

movlw .1 ;číslo v registri listov je 5: napíšte číslo 1

movwf list ;zaregistrovať list

met1 movlw .1 , skontrolujte obsah registra listov

xorwf list,W ; rovná sa číslu 1

btfss STATUS,Z ;

goto met2 ;číslo v registri listov sa nerovná 1: skok na met2

movf datind1,W ;číslo v registri listov je 1: kópia

movwf PORTB ; obsah registra datind1 do registra PORTB

bsf ind1 ;zapnite 1. indikátor

goto exit ;prejdi na označenie exit

met2 movlw .2 , skontrolujte obsah registra listov

xorwf list,W ; rovná sa číslu 2

btfss STATUS,Z ;

goto met3 ;číslo v registri listov sa nerovná 2: skok na met3

movf datind2,W ;číslo v registri listov je 2: kópia

movwf PORTB ; obsah registra datind2 do registra PORTB

bsf ind2 ;zapnite 2. indikátor

goto exit ;prejdi na označenie exit

met3 movlw .3 , skontrolujte obsah registra listov

xorwf list,W ; rovná sa číslu 3

btfss STATUS,Z ;

goto met4 ;číslo v registri listov sa nerovná 3: skok na met4

movf datind3,W ;číslo v registri listov je 3: kópia

movwf PORTB ; obsah registra datind3 do registra PORTB

bsf ind3 ;zapnite 3. indikátor

goto exit ;prejdi na označenie exit

met4 movf datind4,W ; skopírujte obsah registra datind3

movwf PORTB ;do registra PORTB

bsf ind4 ;zapnite 4. indikátor

exit bcf INTCON,T0IF ;resetovať príznak prerušenia pretečenia TMR0

movlw .100 ;zapíšte číslo 156 do registra časovača TMR0

swapf STATUS_TEMP,W ; obnovenie obsahu kľúčových registrov

swapf W_TEMP,F ;

swapf W_TEMP,W ;

retfie ;ukončiť rutinu prerušenia

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Hlavný program

Štart ................. ; pôvodné nastavenie registrov

................. ;špeciálny účel

.................

bsf STATUS,RP0 ;zapis binárne číslo 11010011 zaregistrovať

movlw b"11010011" ;OPTION_REG, čím sa nastaví interný

movwf OPTION_REG ; zdroj hodín pre TMR0

bcf STATUS,RP0 ;povoliť preddeličku pred TMR0

;Nastavte pomer preddeličky na 1:16

clrf Shet ; pred spustením resetujte register listov

;pretečenie prerušenia TMR0, vykonané

;raz po zapnutí

clrf datind1 ; vymazať registre pre výstup informácií

clrf datind2 ;indikátory, ekvivalentné vypnutiu

clrf datind3 ;ukazovatele, keďže ukazovatele so spoločným

clrf datind4 ;katóda

bcf INTCON,T0IF ;resetovať príznak prerušenia pretečenia TMR0

bsf INTCON,T0IE ;povoliť prerušenia pretečenia TMR0

bsf INTCON,GIE; povoliť globálne prerušenia

movlw b"00000110" ; Príklad výstupu 13.52

movlw b"11001111" ;

movlw b"01101101" ;

movlwb"01011011" ;

................. ;

................. ;

................. ;

koniec ; koniec celého programu

V hlavnom programe sme najskôr nastavili časovač pomocou registra OPTION_REG, predtým som hovoril o používaní časovačov pre . Ďalej vymažeme register listov určený na zadávanie počtu od 1 do 4 pre každý ukazovateľ. Tento register sa inkrementuje v rutine prerušenia a tam sa upraví (bude počítať od 1 do 4), tzv toto čistenie vykonaný raz po zapnutí. Na základe tohto registra určíme, ktorý ukazovateľ zaradiť a vydáme mu zodpovedajúce údaje. Ďalším krokom je vymazanie registrov ukladania informácií, pričom štyri registre dataind1,2,3,4 zodpovedajú štyrom indikátorom. Vymazanie je ekvivalentné vypnutiu indikátorov, keďže pri obsluhe prerušenia sa obsah týchto registrov prenesie do registra PORTB, ku ktorému sú pripojené anódy indikátora. Je to potrebné, aby sa po povolení prerušení na indikátoroch nezobrazovali žiadne odpadky, v zásade to nie je možné, ak sa na výstup okamžite zapíšu správne informácie. Ďalej resetujte príznak prerušenia pretečenia časovača, povoľte prerušenia pretečenia TMR0 a nakoniec povoľte globálne prerušenia.

V rutine prerušenia najskôr vypneme všetky indikátory (aplikovaním nízkych logických úrovní na bázy tranzistorov), pretože nie je známe, ktorý z nich je zapnutý. Zväčšíme register hárku, kontrolujeme zhodnosť s číslom 5, ak je taká zhoda, napíšeme do registra číslo 1, keďže je potrebné počítať od 1 do 4. Ďalej skontrolujeme, ktoré číslo je v hárku register, ktorým načítame dáta z PORTB do PORTB informačných registrov (dataind) pre príslušný indikátor a zapneme ho. Potom resetujeme príznak prerušenia pretečenia TMR0, zapíšeme číslo 100 do časovača (výpočet tejto hodnoty je uvedený nižšie) na časové oneskorenie a ukončíme obsluhu prerušenia. Pri prvom prerušení sa rozsvieti prvý indikátor, pri druhom prerušení druhý atď. v kruhovom cykle. V hlavnom programe zostáva len načítať údaje do registrov na ukladanie informácií pre každý indikátor. V podprograme prerušenia nezabudnite uložiť a obnoviť hodnoty kľúčových registrov, o tom som písal v článku o.

Na výstup čísel je lepšie použiť generátor znakov vo forme dátovej tabuľky. Napríklad, aby sa na indikátoroch zobrazilo číslo 3456, musí byť rozdelené na číslice, zatiaľ čo na uloženie čísel číslic je lepšie použiť samostatné registre (od 0 do 9), potom tieto registre spustiť cez generátor znakov, čím získanie správnych bajtov (načítaných do dataind registrov) na zapálenie príslušných segmentov.

Frekvenciu generátora hodín budeme brať ako 4 MHz, cyklus stroja je 1 μs. Nech je obnovovacia frekvencia každého indikátora 100 Hz (perióda T = 10 ms), požadované časové oneskorenie je 10/4 = 2,5 ms. Faktor preddeličky pre TMR0 je nastavený na 1:16, pričom maximálne možné oneskorenie je 256x16 = 4096 µs a potrebujeme pauzu 2,5 ms. Vypočítajme číslo na zápis do TMR0: 256-((256x2,5)/4,096) = 256-156,25 = 99,75. Po zaokrúhlení dostaneme číslo 100.

Nižšie si môžete stiahnuť model programu Proteus, firmware a zdrojový kód s implementáciou dynamickej indikácie na 4-miestnom indikátore so spoločnou katódou pomocou mikrokontroléra PIC16F628A. Napríklad čísla 0000 sú zobrazené na indikátore; 0001; 0002; 13,52; 9764.

Teraz zvážte pripojenie matice s rozlíšením 8x8 pixelov (LED). Štruktúra matice sa zvyčajne uvažuje z hľadiska riadkov a stĺpcov. Na obrázku nižšie sú v každom stĺpci pripojené katódy všetkých LED a v každom rade anódy. Reťazce (8 riadkov, LED anódy) sú pripojené cez odpory k mikrokontroléru. Každý stĺpec (LED katódy) je pripojený k mikrokontroléru cez 8 tranzistorov. Algoritmus indikácie je rovnaký, najskôr nastavíme potrebné logické úrovne na riadkoch, podľa ktorých majú svietiť LED v stĺpci, potom pripojíme prvý stĺpec (indikácia zľava doprava). Po určitej pauze stĺpec vypneme a zmeníme logické úrovne na riadkoch, aby sa zobrazil druhý stĺpec, potom pripojíme druhý stĺpec. A tak striedavo pendlovať všetky kolóny. Nižšie je schéma pripojenia matice k mikrokontroléru.


Celkovo je na pripojenie takejto matice potrebných 16 kolíkov mikrokontroléra, čo je dosť veľa, preto je na zníženie riadiacich vedení lepšie použiť sériové posuvné registre.

Najbežnejším sériovým registrom je mikroobvod 74HC595, ktorý obsahuje posuvný register na načítanie dát a prídržný register, cez ktorý sa dáta prenášajú na výstupné linky. Načítanie dát do neho je jednoduché, na hodinovom vstupe SH_CP nastavíme logickú 0, na dátovom vstupe DS potom nastavíme požadovanú logickú úroveň, po ktorej prepneme hodinový vstup na 1, pričom hodnotu úrovne uložíme (na vstupe DS) vnútri posuvného registra. Zároveň sú dáta posunuté o jeden bit. Znova nastavte výstup SH_CP na 0, nastavte požadovanú úroveň na vstupe DS a zvýšte SH_CP na 1. Po úplnom načítaní posuvného registra (8 bitov) nastavte výstup ST_CP na 1, v tomto momente sa dáta prenesú do úložný register a privádzaný do výstupných vedení Q0 ... Q7, po ktorých resetujeme výstup ST_CP. Počas sekvenčného načítavania sa údaje posúvajú z Q0 na Q7. Pin Q7' je pripojený k poslednému bitu posuvného registra, tento pin je možné pripojiť na vstup druhého mikroobvodu, takže môžete načítať dáta do dvoch alebo viacerých mikroobvodov naraz. Pin OE prepne výstupné vedenia do tretieho (vysokoodporového) stavu, keď je naň privedená logická 1. Pin MR je určený na resetovanie posuvného registra, teda nastavenie nízkych logických úrovní na výstupoch spúšťačov registra. , čo je ekvivalentné načítaniu ôsmich núl. Nižšie je uvedený diagram načítania údajov do mikroobvodu 74NS595 s nastavením hodnoty 11010001 na výstupných vedeniach Q0 ... Q7 za predpokladu, že na začiatku boli nuly:


Zvážte pripojenie matice 8×8 k mikrokontroléru PIC16F628A pomocou dvoch posuvných registrov 74HC595, schéma je znázornená nižšie:


Dáta sa načítajú do čipu DD2 (regulácia logickej úrovne na riadkoch, LED anódy), potom sa prenesú cez pin Q7 na DD3 (riadenie stĺpcov), najskôr načítame bajt, aby sme povolili stĺpec, potom bajt s logickými úrovňami v riadkoch. Stĺpce spínacej matice tranzistorov (LED katódy) sú pripojené k výstupným vedeniam DD3. Nižšie je uvedený programový kód na zobrazenie obrázka na matici:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Implementácia dynamickej indikácie pre maticu s rozlíšením 8x8 ;Frekvencia generátora hodín napr. 4 MHz, takt stroja 1 µs org 0000h ;spustenie vykonávania programu od adresy 0000h goto Start ;skok na štítok Štart ;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Prerušenie rutiny org 0004h ;spustenie vykonávania podprogramu od adresy 0004h movwf W_TEMP ;uloženie hodnôt kľúčového registra ​​swapf STATUS,W ; clrf STATUS ; movwf STATUS_TEMP ; ; movwf FSR_osn ;do registra FSR_osn movf FSR_prer,W ;obnovenie predtým uloženej hodnoty movwf FSR ;registra FSR z registra FSR_prer ;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;načítať obsah registra stolb do čipu movf stolb,W ;skopírovať obsah registra stolb movwf var ;do registra var met2 btfsc var,0 ;nastaviť výstup ds v súlade s btfss var,0 ; bcf ds; bcf sh_cp ; rrf var,F ;Posuvný register var právo pripraviť;ďalší bit goto met2 ;scetbit sa nerovná nule: skok na označenie met2 ;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;nahrať obsah registra INDF do čipu;74HC595 (sériový posuvný register) movf INDF,W ;kopírovať obsah registra INDF movwf var ;do registra var movlw .8 ;zapísať číslo 8 do registra scetbit, pre počítanie movwf scetbit ;prenesené bity met1 btfsc var ,7 ;nastav výstup ds podľa bsf ds ;hodnota 7. bitu registra var btfss var,7 ; bcf ds; bsf sh_cp ;hodinový výstup sh_cp na zachytenie údajov bcf sh_cp ; rlf var,F ;Posuňte register var doľava na prípravu;ďalší bit decfsz scetbit,F ;Zníženie s podmienkou registra scetbit goto met1 ;scetbit sa nerovná nule: Skok na označenie met1 ; bsf st_cp, hodiny výstupu st_cp na prenos načítaného bcf st_cp, bajtov na výstupné riadky čipov 74HC595; bcf STATUS,C ;vynulovanie bitu C stavu registra pred posunom rrf stolb,F ;ľavý posuvný register stolb ; incf FSR,F ;Zvýšte register FSR, pripravte ďalej ;Zaregistrujte sa na odoslanie údajov na 74HC595 decfsz list,F ;Znížte s podmienkou registra shet goto exxit ;Registr listu sa nerovná 0: Skok na ukončenie movlw data1 ;Registr listu sa rovná 0: Najprv zapíšte adresu movwf FSR ;Registrácia na ukladanie informácií do registra FSR movlw .8 ;Zápis čísla 8 do registra listov, na udržiavanie listu movwf ;Počítanie stĺpcov ; exit bcf INTCON,T0IF ;reset príznak prerušenia pretečenia TMR0 movlw . 124 ;zapis cislo 124 do casoveho registra TMR0 movwf TMR0 ; ; movf FSR,W ;Uložiť aktuálnu hodnotu FSR movwf FSR_prer ;Do FSR_prer movf FSR_osn ,W ;Obnoviť predtým uloženú hodnotu movwf FSR ;FSR z FSR_osn ; swapf STATUS_TEMP,W ;obnovenie obsahu kľúčových registrov movwf STATUS ; swapf W_TEMP,F ; swapf W_TEMP,W ; ; retfie ;opustenie podprogramu prerušenia;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Spustenie hlavného programu ................ ;Počiatočné nastavenie registrov ................. ;Špeciálny účel..... ............ bsf STATUS,RP0 ;zapíšte binárne číslo 11010011 do registra movlw b"11010010" ;OPTION_REG, čím sa nastaví interný movwf OPTION_REG ;zdroj hodín pre TMR0 bcf STATUS,RP0 ;predvoľba preddeličky TMR0, nastavte pomer preddeličky 1:8; movlw .8 ;zapis cislo 8 do registra listov, pred spustenim movwf shet ;tmr0 prerusenia pretecenia, spustene;raz, po zapnuti movlw b"10000000" ;zapis binarne cislo 10000000 do movwf stolb ;registr stolb, povoli sa 1.stlpec vykonaná raz, po zapnutí napájania; movlw data1 ;Zapíšte adresu prvého registra (úložné registre movwf FSR_prer ;informácie) do registra FSR_prer, vykoná sa;jedenkrát po zapnutí; movlw .8 ;vymazanie 8 registrov výstupu informácií do movwf tmp ;matica, ekvivalentná vypnutiu movlw data1 ;matica movwf FSR ; met3 clrf INDF ; incf FSR,F ; decfsz tmp,F ; goto met3 ; ; bcf INTCON,T0IF ;vymazať príznak prerušenia pri pretečení TMR0 bsf INTCON,T0IE ;povoliť prerušenia pri pretečení TMR0 bsf INTCON,GIE ;povoliť globálne prerušenia; m1 movlw data1 ; Príklad výstupu R movwf FSR ; movlw b"00000000" ; movwf INDF ; incf FSR,F ; movlw b"01111111" ; movwf INDF ; incf FSR,F ; movlwb"00001001" ; movwf INDF ; incf FSR,F ; movlwb"00011001" ; movwf INDF ; incf FSR,F ; movlwb"00101001" ; movwf INDF ; incf FSR,F ; movlw b"01000110" ; movwf INDF ; incf FSR,F ; movlw b"00000000" ; movwf INDF ; incf FSR,F ; movlw b"00000000" ; movwf INDF ; ; .................; .................; .................; ; koniec, koniec celého programu;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Implementácia dynamickej indikácie pre maticu s rozlíšením 8x8

;Príklad hodinovej frekvencie 4 MHz, strojový cyklus 1 µs

org 0000h ;spustenie vykonávania programu na adrese 0000h

goto Start ;prejdite na označenie Štart

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Prerušte rutinu

org 0004h ;spustenie vykonávania podprogramu na adrese 0004h

movwf W_TEMP ;uložiť hodnoty registra kľúčov

swapf STATUS,W ;

movwf STATUS_TEMP ;

movf FSR,W ;uložiť aktuálnu hodnotu registra FSR

movwf FSR_osn ;do registra FSR_osn

movf FSR_prer,W ; obnoví predtým uloženú hodnotu

movwf FSR ;FSR z FSR_prer

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;74HC595 (sériový posuvný register)

movf stolb,W ; skopírujte obsah registra stolb

movwf var ;zaregistrovať var

movlw .8 ;zapíšte číslo 8 do registra scetbit, pre počítanie

movwf scetbit ;prenesené bity

met2 btfsc var,0 ;nastav ds vystup podla

bsf ds ; 7. bitová hodnota registra var

bsf sh_cp; výstup hodín sh_cp na zachytenie údajov

rrf var,F ; posun registra var právo pripraviť

; ďalší kúsok

decfsz scetbit,F ;zníženie s podmienkou registra scetbit

goto met2 ;scetbit sa nerovná nule: skok na označenie met2

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;74HC595 (sériový posuvný register)

movf INDF,W ; skopírujte obsah registra INDF

movwf var ;zaregistrovať var

movlw .8 ;zapíšte číslo 8 do registra scetbit, pre počítanie

movwf scetbit ;prenesené bity

met1 btfsc var,7 ;nastav ds vystup podla

bsf ds ; 7. bitová hodnota registra var

bsf sh_cp; výstup hodín sh_cp na zachytenie údajov

rlf var,F ;posun doľava var na prípravu

; ďalší kúsok

decfsz scetbit,F ;zníženie s podmienkou registra scetbit

goto met1 ;scetbit sa nerovná nule: skok na označenie met1

bsf st_cp ;hodiny výstupu st_cp na prenos načítané

bcf st_cp ;bajtov na 74HC595 výstupných riadkov

bcf STATUS,C ; pred posunom vymažte bit C stavového registra

rrf stolb,F ;ľavý posuvný register stolb

incf FSR,F ;prírastok registra FSR, pripraviť ďalšie

Zaregistrujte sa na odosielanie údajov na 74HC595

decfsz list,F ;zmenšenie pomocou listu stavu registra

goto exit ;listový register sa nerovná 0: skok na výstup

movlw data1 ;listový register je 0: napíšte adresu prvého

movwf FSR ;Zaregistrujte sa na ukladanie informácií do FSR

movlw .8 ;zapíšte číslo 8 do registra listov, pre referenciu

movwf list ;stĺpec počíta

movlw b"10000000" ;zapíšte binárne číslo 10000000 do

movwf stolb ;registrujte stolb, aby ste zahrnuli 1. stĺpec

exit bcf INTCON,T0IF ;resetovať príznak prerušenia pretečenia TMR0

movlw .124 ;zapíšte číslo 124 do registra časovača TMR0

movf FSR,W ;uložiť aktuálnu hodnotu registra FSR

movwf FSR_prer ;do registra FSR_prer

movf FSR_osn ,W ; obnoví predtým uloženú hodnotu

movwf FSR ;FSR od FSR_osn

swapf STATUS_TEMP,W ; obnovenie obsahu kľúčových registrov

swapf W_TEMP,F ;

swapf W_TEMP,W ;

retfie ;ukončiť rutinu prerušenia

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Hlavný program

Štart ................. ;úvodné nastavenie registrov

................. ;špeciálny účel

.................

bsf STATUS,RP0 ;na registráciu napíšte binárne číslo 11010011

movlw b"11010010" ;OPTION_REG, čím sa nastaví interný

movwf OPTION_REG ; zdroj hodín pre TMR0

bcf STATUS,RP0 ;povoliť preddeličku pred TMR0

;Nastavte pomer preddeličky na 1:8

movlw .8 ;pred spustením zapíšte číslo 8 do registra listov

movwf Shet ; Pretečenie TMR0 prerušuje, beží

;raz po zapnutí

movlw b"10000000" ;zapíšte binárne číslo 10000000 do

movwf stolb ;registrujte stolb, aby ste zahrnuli 1. stĺpec

Informácie s logickými úrovňami pre riadky každého stĺpca sú uložené v 8 registroch na ukladanie informácií, ku ktorým sa pristupuje. Adresa prvého registra sa nazýva data1. Okrem prvotného zápisu registrov shet a stolb je potrebné do registra FSR_prer zapísať adresu prvého registra ukladania informácií (register je data1, zápis do FSR_prer sa vykoná raz, potom sa upraví v handler), až potom povoľte prerušenia pretečenia TMR0.

Pred povolením prerušení je žiaduce vyčistiť registre ukladania informácií, táto operácia sa vykonáva pomocou dodatočného registra tmp (ako počítadla) a nepriameho adresovania, vymazanie je ekvivalentné vypnutiu matice.

V rutine obsluhy prerušení načítame obsah registra stolb do čipu DD2 (pri prvom vstupe do handlera po povolení prerušení register obsahuje číslo 10000000, ako je uvedené vyššie). Načítanie začína od nízkeho bitu registra stolb, ktorý sa pri načítavaní posúva v smere z Q0 na Q7 (vo vnútri čipu DD2), algoritmus načítania bol diskutovaný vyššie, takže si myslím, že nebude ťažké pochopiť kód . Ďalej načítame obsah registra INDF do DD2, ide o jeden z registrov na ukladanie informácií, ktorého adresa je v FSR (pri prvom vstupe do handlera po povolení prerušení FSR obsahuje adresu prvého register ukladania informácií nazývaný dáta1). Načítanie začína od najvyššieho bitu registra INDF. Po načítaní uvažovaných 2 bajtov nataktujeme výstup st_cp, čím sa stiahnuté dáta prenesú na výstupné linky mikroobvodov DD2, DD3. Pri prvom vstupe do handlera sa teda prepne prvý stĺpec matice, v ktorom sa rozsvietia LED diódy, na anódach ktorých je vysoká logická úroveň, v súlade s obsahom registra data1 (tzv. prvý register uchovávania informácií).

Ďalej posunieme register stolb o jeden bit doprava, aby sme pripravili druhý stĺpec matice na prepnutie pri ďalšom vstupe do obsluhy prerušení. Príznak C registra STATUS musí byť pred posunom vymazaný, pretože k posunu dochádza cez tento príznak a jeho stav nie je v čase posunu známy. Po posune inkrementujeme register FSR a pripravíme ďalší úložný register (po registri data1) s úrovňami logických riadkov pre druhý stĺpec. Ďalej dekrementujeme listový register s podmienkou a ak sa nerovná nule, resetujeme príznak prerušenia pretečenia TMR0, zapíšeme číslo do časovača a ukončíme obsluhu prerušenia.

Keď nabudúce zadáte obslužný program, aktivuje sa druhý stĺpec matice atď. Pri vynulovaní listového registra (po prepnutí 8. stĺpca) sa do neho zapíše číslo 8 pre ďalší cyklus prepínania stĺpcov, navyše sa opraví hodnota registra stolb, adresa prvého registra ukladania informácií ( údaje1) sa zapisujú do registra FSR.

Vypočítajme časové oneskorenie pre časovač TMR0, hodinová frekvencia je 4 MHz, cyklus stroja je 1 µs. Aby sme sa vyhli blikaniu LED, vezmime obnovovaciu frekvenciu každého stĺpca ako 100 Hz (perióda T = 10 ms), časové oneskorenie je 10/8 = 1,25 ms. Pomer preddeličky TMR0 sme nastavili na 1:8, pričom maximálne možné oneskorenie je 256x8 = 2048 µs. Pre pauzu 1,25 ms by mal časovač počítať (256x1,25) / 2,048 = 156,25-krát, zaokrúhlením nahor dostaneme 156 impulzov. V súlade s tým je potrebné do časovača zapísať číslo 256-156 = 100. Nie je to však celkom správna hodnota, pretože vykonanie rutiny prerušenia trvá nejaký čas, v tomto prípade to trvá asi 190 µs, prepočítané so zohľadnením pri zohľadnení koeficientu preddeličky dostaneme 190/8 = 23,75 alebo 24 počtov. Správna hodnota na zápis do TMR0 je: 100+24=124.

V hlavnom programe napíšeme 8 registrov na ukladanie informácií v súlade s tým, čo chceme zobraziť na matici. Nižšie je uvedený diagram vysvetľujúci výstup informácií do matice pre vyššie uvedený kód.


Okrem posuvných registrov existujú špecializované ovládače na zobrazovanie informácií na sedemsegmentových ukazovateľoch a LED matrica, v tomto prípade dynamickú indikáciu implementuje vodič sám, zostáva len poslať mu dáta na zobrazenie. Skontroloval som jeden z týchto populárnych ovládačov v článku o.

Pod odkazom si môžete stiahnuť firmvér a zdrojový kód pre mikrokontrolér PIC16F628A s implementáciou dynamickej indikácie na matici 8x8 pomocou dvoch posuvných registrov 74HC595, schéma zapojenia bola diskutovaná vyššie. Na matrici sa striedavo zobrazujú písmená R, L, číslo 46, smajlík a len vzor v podobe kríža, táto animácia je znázornená na videu nižšie.

so značkami, . Čítať .

Dynamická indikácia je jedným z problémov, ktorým čelia začínajúci programátori mikrokontrolérov. Veľa sa o tom popísalo, ale rozhodol som sa, že to, čo je známe, upevním pomocou obrázkov a príkladov zdrojových textov v jazyku C, aby bolo ľahšie zvládnuť túto metódu zobrazenia.

1 Základy základov, alebo úvod

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

Ak chcete ovládať displej pozostávajúci z jedného známeho sedemsegmentového displeja, nespôsobuje to žiadne problémy - môže byť reprezentovaný ako 8 nezávislých LED. Ak potrebujete zobraziť viac informácií ako jeden znak, začínajú problémy: 2 známosť je 16 LED, tri - 24 atď., To znamená, že pre trojmiestny displej nemusia výstupy mikrokontroléra stačiť, nehovoriac 6 alebo viac bitové displeje a najmä maticové indikátory.

Pre jednoduchosť súhlasíme s tým, že všetky naše indikátory sú so spoločnou katódou. Riešenie problému je pomerne jednoduché: navzájom prepojte výstupy segmentov všetkých indikátorov. Teraz, ak chcete zobraziť informácie v prvom oboznámení, 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 požadované segmenty prvého indikátora. Pre výstup do druhého, tretieho atď. indikátory by mali robiť to isté, t.j. aplikáciou logickej nuly na jednu zo spoločných katód vyberieme aktuálne zobrazený bit a stav segmentových čiar určuje viditeľný symbol.

Aby bol celý displej vnímaný ako nepretržite rozsvietený, číslice sa musia prepínať rýchlo – častejšie ako 25-krát za sekundu. Ako vidíte, úrovne všetkých záverov (ktorých sa, mimochodom, výrazne znížili ako pri bežnom prístupe) sa priebežne menia, t.j. nemajú statické úrovne, ale dynamické, odtiaľ názov metódy zobrazenia – dynamický.

Obraz s dynamickým zobrazením

2 Varianty implementácie hardvéru

2.1 Ploché matice

Ak abstrahujeme od sedemsegmentových indikátorov, tak 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. V skutočnosti je to presne ono.

Je zrejmé, že aplikovaním požadovaných úrovní na riadky a stĺpce našej matice môžeme rozsvietiť akýkoľvek elementárny segment LED (aka pixel - toto je tradičnejší výraz pre maticové displeje). V závislosti od toho, ako presne budeme meniť úrovne v riadkoch a stĺpcoch, môžeme získať niekoľko typov dynamickej indikácie:

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

Možnosť podľa stĺpcov sme zvážili v predchádzajúcej kapitole. Možnosť po riadkoch sa od nej líši len tým, že riadky a stĺpce našej matice sú zamenené. Metóda segment-by-segment spočíva v tom, že vždy len jeden riadok a jeden stĺpec má úroveň potrebnú na rozsvietenie LED. To znamená, že kedykoľvek môže svietiť iba jedna LED z celej matice (na rozdiel od predchádzajúce možnosti keď je možné rozsvietiť celý riadok alebo celý stĺpec súčasne). Táto metóda sa podobá televíznemu skenovaniu, keď lúč prechádza okolo celej obrazovky a osvetľuje sa dovnútra správnych miestach fosfor. Zmiešaná verzia, 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 viac vysoké rýchlosti aktualizácie informácií o 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 zvážili, predpokladajú implementáciu monochromatický displej, t.j. pozostáva z jednofarebných LED diód. Čo 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 tak, že každú RGB LED budeme považovať za 3 nezávislé samostatné LED. Veľkou nevýhodou tohto prístupu je trojnásobné zvýšenie počtu riadkov (alebo stĺpcov). Na jednoduchý príklad je ľahké vidieť, čo to znamená v praxi: pomocou dvoch osembitových výstupkov mikrokontroléra môžeme mať monochromatickú maticu 8x8 segmentov alebo farbu 4x4. Súhlaste s tým, že v druhom prípade je prakticky nemožné zobraziť čokoľvek zrozumiteľné ...

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

Je zrejmé, že v prípade viacrozmernej matice je potrebný aj ďalší počet riadiacich liniek, tento počet však 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. Zázraky sa samozrejme nedejú a v tomto prípade budeme musieť zaplatiť tým, že okrem mikrokontroléra sa použijú aj ďalšie mikroobvody. Ako ste možno uhádli, tu môžete použiť predtým zvažovanú metódu „multidimenzionálnych“ matíc - koniec koncov, nikto nám nezakáže jednoducho použiť trojitý počet jednofarebných LED namiesto RGB LED? Hlavná vec je správne ich usporiadať...

Takže môžeme zmenšiť rozmer matice použitím:

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

S multiplexormi sme sa už stretli skôr, dekodér, ako tušíte, sa od multiplexora zásadne líši. Treba len dodať, že použitím dekodérov/multiplexerov pre riadky aj stĺpce je možné dosiahnuť zmenšenie rozmeru matice v oboch rozmeroch naraz, avšak v tomto prípade môže byť potrebné použiť len segment po- segmentová dynamická indikácia so všetkými jej nedostatkami.

Posunové registre vedia pomôcť oveľa lepšie ako dekodéry. 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ý! Malé mínus tento prístup je, že s narastajúcim počtom registrov v reťazci bude potrebné zvýšiť rýchlosť sekvenčného výstupu informácií v nich, čo nie je vždy ľahko dosiahnuteľné. Takže napríklad bežné mikrokontroléry rodiny AVR, prakticky neumožňujú prekonať 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 začať problémy iného poradia: šírenie vysokofrekvenčného hodinového signálu pozdĺž dlhého vedenia (a keď veľké čísla registrov, nevyhnutne to tak bude) je úplne odlišný od nízkofrekvenčného, ​​takže pri zapájaní budú potrebné špeciálne opatrenia vytlačená obvodová doska a ďalšie veci, ktoré v tomto článku nebudeme uvažovať.

3 spôsoby implementácie softvéru

Nebudeme uvažovať o softvérovej implementácii všetkých spomenutých možností dynamickej indikácie – tým sa článok neprimerane nafúkne. Obmedzíme sa len na tri „najbežnejš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 využitím posuvných registrov. Vo všetkých prípadoch sa bude venovať osobitná pozornosť všetkým nuansám implementácia softvéru, to znamená, že kód C bude sprevádzaný vysvetleniami iba v prípadoch, keď sa to zhoduje so zámerom autora a v žiadnom prípade nie s úrovňou vašej odbornej prípravy. 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ť pole, ktorého obsah by jednoznačne určoval, ktoré segmenty v ktorých známych oblastiach displeja svietia - akýsi analóg obrazovky RAM.

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

#define SCR_SZ 6 /* počet znakov zobrazenia */ #define ROWS PORTB /* port zobrazenia "riadkov", t.j. správa segmentov */ #define COLS PORTD /* port pre správu "stĺpcov", t.j. spoločné katódy */

Teraz deklarujme obrazovku poľa:

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á určitému segmentu indikátora. Ktorý bit zodpovedá ktorému segmentu - v tomto prípade nezáleží na tom, 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é na kolíky portu COLS sekvenčne: 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 je to zlé.

V prvom rade si všimnite, že nemáme žiadnu kontrolu nad rýchlosťou, akou sa aktualizuje obsah riadkov a stĺpcov. Po druhé, všimnite si, že v čase, keď je nový prvok poľa výstupom do RIADKY na linkách COLS stará hodnota je stále prítomná! Kam to vedie? Navyše, na nejaký zlomok sekundy sa na známosti zobrazia segmenty susednej známosti, t.j. niektoré segmenty budú nesprávne zvýraznené.

Tomuto efektu sa môžete vyhnúť takto: pred aktualizáciou obsahu RIADKY, vždy zrušte známosť, ktorá bola predchádzajúca. Aby ste sa neobťažovali s definíciou predchádzajúcej známosti, môžete všetko uhasiť naraz. Náš kód teda vyzerá takto:

unsigned char pos; 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 (uvedením vysokej úrovne na spoločné katódy, vypneme indikátor bez ohľadu na to, čo je prítomné 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 len nám nedovolí robiť nič iné. Aký to budeme mať program, ktorý vie len niečo zobraziť na ukazovateli?! Samozrejme, všetko nie je 100% zlé, pretože na prerušeniach sa dá urobiť niečo užitočné ... a namiesto oneskorenia meškanie () môžete vykonávať niektoré akcie ... Ale to všetko je veľmi, veľmi pokrivené: nie je žiaduce vykonávať niečo zložité a ťažkopádne v obsluhe prerušenia; na druhej strane, ak sa namiesto oneskorenia urobí 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ámosť žiari na inú dobu, čo bude vizuálne vyzerať ako ich žiara alebo blikanie rôzneho jasu.

Vo všeobecnosti môže byť táto možnosť povolená len ako výnimka, iba ako príklad školenia, alebo v prípade (ale päť, iba ako výnimka!), Keď je hlavný problém, ktorý treba vyriešiť, veľmi jednoduchý (to môže byť napr. napríklad problém merania ADC napätie a zobraziť ho).

Čo treba urobiť? Odpoveď je ako vždy jednoduchá: všetky procesy, ktoré by sa mali vykonávať nepostrehnuteľne od riešenia 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čí rovnomernosť žiary známosti. 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 zmeny kódu sa prejavia tak, že namiesto slučiek používame funkciu obsluhy prerušenia:

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.

premenlivý poz, označujúce číslo aktuálnej žiariacej známosti, vytvoríme lokálnu statickú premennú tak, aby si zachovala svoju hodnotu od prerušenia po prerušenie. Na konci funkcie si sami (veď už nemáme cyklus) zvyšujeme číslo známosti, až kým nedosiahneme limit – v tomto prípade sa vrátime 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 si nemôžete spomenúť na indikáciu - 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 takouto 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 pretečie, počíta až do 256) – to bude požadovaná hodnota preddeličky časovača. Samozrejme, je nepravdepodobné, že výsledok bude zodpovedať jednej zo štandardných hodnôt preddeličky - to nie je problém, môžete si vziať najbližšiu menšiu vhodnú hodnotu. Indikácia bude fungovať na vyššej frekvencii, ale nezníži to jej kvalitu! Vedľajším účinkom bude veľké zaťaženie jadra MK pre indikáciu. Ak to výrazne zasahuje do hlavného programu, budete musieť preniesť indikáciu na iný časovač, napríklad 16-bitový Časovač 1 alebo zadajte počítadlo na preskočenie 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 port COLS, okrem spoločných katód indikátorov nie je nič iné pripojené. V reálnom živote sa však takéto šťastie nestáva často a so zvyšnými líniami tohto prístavu je s najväčšou pravdepodobnosťou spojené niečo iné. Preto by sa pri organizovaní dynamickej indikácie malo vždy zabezpečiť nemennosť stavu všetkých portových liniek, ktoré nie sú priamo zapojené do indikácie. To sa robí jednoducho: namiesto jednoduchého zapisovania novej hodnoty do portu by sa malo použiť maskovanie nepotrebných bitov:

COLS |= 0x3F; // takže zhasneme všetku známosť COLS &= ~(1<

Oba príkazy nemenia hodnotu vysokých bitov portu COLS.

3.2 Metóda dekodéra

Dekodér možno použiť buď na konverziu HEX alebo BCD kód na sedemsegmentové znaky, alebo na výber jedného zo stĺpcov matice. Obe možnosti sa budú líšiť od najjednoduchšej metódy zvažovanej 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 znaku:

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 v RIADKY znakový kód z poľa SCR, sú vysoké bity maskované, potom sú nízke bity nastavené podľa znakového kódu. To znamená, že uvažujeme, ž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 - aj tak je všetko jasné.

3.3 Metóda s registrami

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ýstupe bitov čisto softvérovými prostriedkami. A pri implementácii iných (pomocou USI/USART/SPI/TWI) si môžete vyskúšať sami.

Pre variant predtým zvoleného zobrazenia 6 sedemsegmentových znakových medzier používame 2 posuvné registre typu 74HC595. Tento register je riadený tromi signálmi: hodinami sériového vstupu dát CLK, skutočné údaje ÚDAJE a impulz simultánneho paralelného výstupu informácie zapisovanej do registra SET. Deklarujme príslušné makrá (pre jednoduchosť „prenesieme“ 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 žiaduce, aby táto funkcia bola 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ží do obsluhy prerušenia, t.j. nedôjde k zbytočnému používaniu zásobníka, čo nie je zaručené pri nestatických funkciách.

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 na jeho výstupoch sa súčasne objavujú aj údaje zapísané do registrov, nie je potrebné najskôr vypínať indikátory. Malo by sa pamätať na to, že sekvenčný výstup programu je pomerne dlhý proces, najmä pre matice veľkých rozmerov, takže by ste ho mali čo najviac optimalizovať z hľadiska rýchlosti. 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 dynamickej indikácie. 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. A ak chcete použiť s bež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 na COLS, zapaľovanie - respektíve jednotky a segmenty v RIADKY bude obsahovať nuly namiesto jednotiek. Obsluha prerušenia sa teda zmení na niečo takéto:

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

Všetko je jednoduché. Pokiaľ sa, samozrejme, nepokúsite napísať univerzálny kód, ktorý je vhodný pre spoločné anódy aj spoločné katódy. Dá sa to urobiť dvoma spôsobmi: buď pomocou direktív podmienenej kompilácie, alebo pomocou transformačnej funkcie. Ukážem prvú možnosť a navrhujem premýšľať o druhej samostatne.

#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; }

Je to trochu ťažkopádne, ale ak ho napíšete raz, môžete ho použiť vo všetkých projektoch takmer 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 informácií zadaných používateľom. A v tomto prípade je potrebné vedieť na displeji nejako oddeliť nezmenené od meniteľného. Najjednoduchší spôsob, ako to urobiť, je nechať blikať zodpovedajúcu známosť (alebo niekoľko známostí).

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

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 rovná sa 1. Ak, predpokladajme, blikať obsahuje všetky nuly, potom je táto podmienka vždy splnená - zobrazia sa všetky známosti. Ak blikať obsahuje 1 v jednom zo svojich bitov, potom sa príslušný znak zobrazí iba v čase, keď je najvýznamnejší bit počítadla 1. Keďže počítadlo sa zvyšuje pri každom zadaní obsluhy prerušenia, zodpovedajúci znak bude blikať pri frekvencia 128-krát menšia ako frekvencia prerušenia.

4.3 Nastavenie jasu segmentov

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

4.4 Svojvoľné rozdelenie záverov

Predtým sa hovorilo, že šťastie prideliť celý port MK na indikáciu padá pomerne zriedka. Ale ešte menej často je šťastie získať pohodlné sledovanie PCB, 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 smerovanie dosiahne iba vtedy, keď sa riadky a stĺpce zmiešajú medzi dvoma alebo dokonca viacerými portami mikrokontroléra. Nebudete musieť obetovať krásu dosky plošných spojov, ak počas indikácie zorganizujete softvérovú výmenu bitov.

Uvažujme o nejakom abstraktnom príklade. Nech je zabezpečené najlepšie sledovanie s nasledujúcim rozložením signálov pozdĺž línií MC portov:

Segment A

Segment B

segment H

Segment C

Segment D

G segment

Segment E

Segment F

Ako vidíte, maticové čiary sú zmiešané medzi tromi portami a všetky nevyužité linky týchto portov by samozrejme počas procesu indikácie nemali meniť svoju úroveň.

Najlepšie je začať s vývojom dynamickej indikačnej funkcie pre tento prípad rozložením segmentov cez symbolové bity. Predtým sme to zvažovali v poli SCR ukladáme bitové masky znakov, 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. Budete to musieť urobiť pri zmenových operáciách, takže by ste sa mali snažiť rozdeliť ich tak, aby ste urobili minimum zmien. Poďme diskutovať.

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 znaku a tiež sa nemusí pred výstupom posúvať PORTC, ale pre segmenty ALE a AT zostanú bity 7 a 3, teda s najväčšou pravdepodobnosťou segment AT bude musieť byť pred výstupom posunuté o 3 pozície a segment ALE- do 6. Pri tejto možnosti sa zastavím a môžete pokračovať v hľadaní minima smien (posuny o viacero pozícií nie sú až taká rýchla operácia, preto je žiaduce ich počet zredukovať na minimum).

Takže v našom prípade sme dostali nasledujúcu distribúciu bitov podľa bajtov:

A

H

F

E

B

G

D

C

Všimnite si 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 pomocou operácie „bitový AND“ vyberieme potrebné bity pre výstup na port.

Deklarujme konštanty masky:

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

Predtým sme vypisovali znak na jeden port RIADKY, teraz je tento postup rozdelený na tri časti:

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ýstup do PORTC jeden bit musí byť na výstupe bez posunu a druhý - s posunom, takže namiesto MASKC museli použiť samostatné makrá _BV().

Teraz zostáva rozhodnúť, ako uhasiť a zapáliť zodpovedajúcu známosť. 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)

Aby ste uhasili všetku známosť, je potrebné vydať príslušné konštanty na porty COM_x:

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

Aby ste však umožnili oboznámenosť, musíte byť inteligentní (nemá zmysel vydávať výstup na všetky tri porty, pretože v závislosti od hodnoty bude aktívny iba jeden bit na určitom porte 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; // zhasne PORTD |= COM_D; PORTC |= COM_C; PORTB |= COM_B; // zobrazí 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 vytlačiť nulu úplne vpravo od displeja, 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 znaky budú automaticky "prerobené". V najjednoduchších prípadoch opísaných na začiatku nebudete musieť robiť vôbec nič iné, ale v prípade možnosti „bitovej výmeny“ si budete musieť, samozrejme, pohrať.

4.5 Podpora tlačidiel

Pri tradičnom nedostatku výstupov MK 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, miernym skomplikovaním funkcie dynamickej indikácie je však jednoduché získať toľko tlačidiel, koľko je na displeji známe, pričom navyše stačí použiť len jeden port mikrokontroléra. Pravda, každé tlačidlo musí byť stále umiestnené na dióde.

Schematicky je to znázornené na obrázku.

A programovo to 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 kľúč- ide o makro, ktoré nastavuje bit zvoleného portu, na ktorom sú všetky tlačidlá "zapojené", makro keypin() vráti boolovskú hodnotu TRUE, ak je vybratý pin logicky nízky. V príklade sú tlačidlá spojené s PORTD.

Vždy, keď dôjde k prerušeniu časovača, všetky segmenty najskôr zhasnú - je to potrebné, aby prúd cez LED neviedol k chybnému nerozpoznaniu stlačeného tlačidla. Potom sa vyzve vstup tlačidla - ak je nízka úroveň, potom sa stlačí tlačidlo pripojené k príslušnej pozičnej katóde. V premennej tmp_key akumulujú sa stavy tlačidiel, ktoré sa prepisujú do globálnej premennej kľúč po dokončení cyklu zobrazenia. Z času na čas je potrebné analyzovať hodnotu kľúč a zvládnuť zistené lisy:

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 zaručuje, že nedôjde k cvakaniu tlačidiel, aj keď vzhľadom na „dynamický“ charakter dopytovania tlačidiel je už pravdepodobnosť klepania nízka.

5 Čo ešte?

Takže ste si osvojili celkom typické techniky implementácie dynamickej indikácie. Myslím, že toto ti bude stačiť na prvýkrát a možno aj na celý život. Nakoniec je hlavnou vecou pochopenie techník a algoritmov a jemnosti a nuansy je možné vždy pridať sami. Čo však ešte môže čakať „v blízkosti“ dynamickej indikácie?

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

Môžete sa zamyslieť nad optimálnosťou obsluhy prerušení - na vzdelávacie účely som napísal skôr 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ď s mojím prístupom určite pomôže optimalizátor, pre prax sa oplatí vyskúšať a optimalizovať sa, riadiť sa veľkosťou výsledného kódu a/alebo rýchlosťou 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 horšie rozlíšiteľné, čím sú tmavšie okolo - len sa rozmazávajú. Preto je v tme rozumné znížiť jas indikátorov a zvýšiť ho počas dňa. 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, takže ak na indikáciu použijete port pripojený k vstupu ADC, potom, ak je to potrebné, môžete zmerať foto-emf nesvietivého segmentu indikátora a použiť túto hodnotu na nastavenie jasu ...

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

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


3 Napísané ARV, o 06:48 25.08.2010
Miša, na tvojom mieste by som nedával takéto rázne vyhlásenia „nedokážeš to“, „nikto nenapísal“ alebo „autorské práva“, pretože to po prvé nie je slušné a po druhé:
1. Už dávnejšie som spravil bežiacu čiaru na matici 10x16 (čo to bolo) - video z jej práce 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ý) o tom, ako urobiť 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 článok odniekiaľ skopírovaný (copy-paste nie je autorské právo, máte to zapečatené), 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 naraz na mnohých miestach).

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

Indikátory sú zvyčajne umiestnené na miestach vhodných na prezeranie informácií, ktoré sú na nich zobrazené. Zvyšok digitálneho obvodu môže byť umiestnený na iných doskách plošných spojov. S nárastom počtu 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 hodnoty.

Počet pripojovacích vodičov možno znížiť tým, že indikátory budú pracovať v impulznom režime. Ľudské oko má zotrvačnosť a ak sú indikátory nútené zobrazovať informácie striedavo dostatočne vysokou rýchlosťou, potom sa človeku bude zdať, že všetky indikátory zobrazujú svoje informácie nepretržite. Vďaka tomu je možné striedavo prenášať zobrazované informácie na rovnakých vodičoch. 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 zahrnutia sedemsegmentových LED indikátorov znázornených na obrázku 1. Tento obvod môže poskytnúť dynamickú indikáciu výstupných digitálnych informácií.


Obrázok 1. Štrukturálny diagram dynamickej indikácie

Obvod zobrazený na obrázku 1 zobrazuje štyri digitálne číslice. Každý bit je krátko pripojený k svojmu vstupu prepínača. Generátor slúži na nastavenie rýchlosti aktualizácie informácií na 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 BCD 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 BCD 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žovanom obvode bude štyrikrát nižšia ako frekvencia generátora. To znamená, že na získanie frekvencie blikania indikátora 100 Hz je potrebná frekvencia oscilá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 doske displeja 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 indikačnom obvode by sme potrebovali 7 × 4 = 28 vodičov. Ako vidíte, je tu výhra. 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 indikačného obvodu sa však používa veľmi zriedkavo.

Teraz vypočítajme prúd, ktorý preteká každým segmentom LED, keď svieti. Na tento účel používame ekvivalentný obvod toku prúdu cez jeden zo segmentov indikátora. Táto schéma je znázornená na obrázku 2.


Ako už bolo spomenuté, LED vyžaduje na správnu funkciu prúd 3 až 10 mA. Nastavíme minimálny prúd LED na 3 mA. V pulznom režime prevádzky sa však jas žiary indikátora zníži N-krát, 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ť hodnotu impulzného prúdu pretekajúceho segmentom. Pre osemmiestny ukazovateľ sa koeficient N rovná ôsmim. Predpokladajme, že sme na začiatku zvolili statický prúd cez LED rovnajúci sa 3 mA. Potom, aby sa zachoval rovnaký jas LED v osemcifernom indikátore, je 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 určme prúd, ktorý bude pretekať kľúčom a prepneme napájanie na jednotlivé bity osembitovej zobrazovacej jednotky. Ako je zrejmé z obvodu znázorneného na obrázku 2, kľúčom môže pretekať prúd ktoréhokoľvek segmentu indikátora. Keď sa zobrazí číslo 8, bude potrebné rozsvietiť všetkých sedem segmentov indikátora, čo znamená, že impulzný prúd pretekajúci kľúčom v tomto okamihu možno určiť takto:

I cl \u003d I segdin× 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 dodať prúd väčší ako 20 mA a kladiem si otázku - kde môžem vidieť takýto indikátor? V úplnej tme? Ukazuje sa "zariadenie na nočné videnie", to znamená zariadenie, ktorého hodnoty sú viditeľné iba v úplnej tme.

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



Obrázok 3. Schéma dynamického indikačného bloku

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

Ako nevýhodu treba uviesť prítomnosť veľkých pulzných prúdov a keďže akýkoľvek vodič je anténa, dynamická indikácia slúži ako silný zdroj rušenia. Ďalšou cestou rušenia je napájanie.

Všimnite si, že čelá spínacích impulzov sú veľmi krátke, takže ich harmonické zložky pokrývajú rádiofrekvenč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ímačoch je nežiaduce.

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

Ako opatrenia na potlačenie rušenia dynamickou indikáciou možno spomenúť tienenie jednotky, prepojovací kábel a dosky. Použitie minimálnej dĺžky spojovacích vodičov, použitie výkonových filtrov. 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á indikácia“ čítajú:

Indikátory sú určené na zobrazenie rôznych typov informácií o osobe. Najjednoduchší druh informácií je...
http://website/digital/Indic.php

Indikátory vybitia sa používajú ako na indikáciu bitových informácií, tak aj na zobrazenie desatinných informácií. Pri konštrukcii desatinných indikátorov katódy...
http://website/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://website/digital/LED.php

Princípy činnosti indikátorov z tekutých kryštálov ... Režimy činnosti indikátorov z tekutých kryštálov ... Vytvorenie farebného obrazu ...
http://website/digital/LCD.php

DAby sa na indikátore zobrazilo viacmiestne číslo, musíte s ním najskôr vykonať zložitú manipuláciu, ktorá spočíva v rozdelení čísla na jeho zložky. Ako príklad uvediem zobrazenie čísla 1234 na štvorsegmentovom sedemsegmentovom indikátore 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é, ktoré budú ukladať ú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úWpostačí typcelé číslo , keďže premenná tohto typu je schopná xpAnimovať hodnoty od -32768 do +32767 (aleboslovo pokiaľ neplánujete použiť záporné čísla). V premennýchNbudú ležať čísla od 0 do 9, takže bude stačiť použiť premennú typubyte
. 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 nastavíme porty pre výstupktorý 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 šesť prvých portov D čiastkové segmenty).

Potom priraďte 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 vo všetkých premenných M bol rovnaký počet, pretože počas operácie priraďovania môže ľahko vniknúť prerušenie (ak nejaké existuje a nie je zakázané), v handleri ktorého premennáW môže zmeniť. A ak by zadanie vyzeralo takto: М1= W, M2= W, M3= W, M4= W v premenných M bude ležať rôzne významyčo povedie k neporiadku v čítaní.

Po zadaní premenné hodnoty začať pracovať s
každý z nich sa prevedie takým spôsobom, že na premennú N dostal hodnotu, ktorá bude
zobrazené na indikátore: v premennej
N 1 by mala byť "1", in N2 - "2", v N3 - "3" a v N4 - "4".

M1=M1/1000" M1=1234/1000=1,234
N1=Abs(ml)" N1=Abs(1,234)=1

abs – funkcia, ktorá vracia celé číslo premennej.Do premennej N 1 zasiahol jednotku, čo bolo skutočne potrebné.

Na priradenie dvojky k premennej N 2 operácia 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""> Ak chcete začať s funkciouMod vraciame prvé tri
číslice čísla (zvyšok delenia 1000) a potom je všetko ako v prvom prípade.

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

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 vykopol nohy a zobrazil tieto hodnoty na indikátore, preto nazývame podprogram spracovania zobrazenia:

"Arial","sans serif"">

Gosub Led

"Arial","sans serif""> Procesor preskočí na podprogram označenýLed:

LED:

Portc = &B00001000

"Arial","sans serif""> Tu slúžime na vysokej úrovniPORTC .3 sme na túto nohu pripojili anódu prvej kategórie. Potom zvolíme, ktoré segmenty rozsvietime, aby sa zobrazila hodnota prvej premennej. Je jednou z nás, takže nula bude na jej nohách Portd .1 a 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čkáme 5 ms a pristúpime k zobrazeniu 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""> Tu je to, čo dostaneme na konci:

"Arial","sans serif"">

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

Nižšie si môžete stiahnuť zdrojový kód a projekt v Proteus:"Arial","sans serif"">