V lekci se seznámíme se schématy připojení sedmisegmentových LED indikátorů k mikrokontrolérům, o tom, jak indikátory ovládat.

LED sedmisegmentové indikátory zůstávají jedním z nejoblíbenějších prvků pro zobrazování digitálních informací.

To je usnadněno následujícími vlastnostmi.

  • Nízká cena. V indikačních prostředcích není nic levnějšího než LED digitální ukazatele.
  • Různé velikosti. Nejmenší a největší indikátory jsou LED. vím LED indikátory s výškou číslic od 2,5 mm do 32 cm.
  • Svítící ve tmě. V některých aplikacích je tato vlastnost téměř rozhodující.
  • Mají různé barvy světla. Barvy jsou dokonce dvě.
  • Dostatečně nízké řídicí proudy. Moderní LED indikátory lze připojit k výstupům mikrokontrolérů bez dalších kláves.
  • Umožňují drsné provozní podmínky (rozsah teplot, vysoká vlhkost, vibrace, agresivní prostředí atd.). Z hlediska této kvality nemají LED indikátory mezi ostatními typy zobrazovacích prvků obdoby.
  • Neomezená životnost.

Typy LED indikátorů.

Sedmisegmentový LED indikátor zobrazuje znak pomocí sedmi LED segmentů číslice. Osmá LED svítí desetinnou čárku. V sedmisegmentovém ukazateli je tedy 8 segmentů.

Segmenty jsou označeny latinskými písmeny od „A“ do „H“.

Anody nebo katody každé LED jsou spojeny v indikátoru a tvoří společný vodič. Proto existují indikátory se společnou anodou a společnou katodou.

LED indikátor se společnou anodou.

LED indikátor se společnou katodou.

Statické LED ovládání.

K mikrokontroléru je nutné připojit LED indikátory přes odpory, které omezují proud.

Výpočet rezistorů je stejný jako u jednotlivých LED.

R = (U zásobování - U segment) / I segment

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

Moderní LED indikátory svítí poměrně jasně již při proudu 1 mA. U obvodu se společnou anodou se rozsvítí segmenty, na jejichž řídicích výstupech bude mikrokontrolér generovat nízkou úroveň.

Ve schématu zapojení indikátoru se společnou katodou se mění polarita napájecího a řídicího signálu.

Rozsvítí se segment, na jehož ovládacím výstupu se vytvoří vysoká úroveň(5 V).

Multiplexní režim ovládání LED.

Pro připojení každého sedmisegmentového indikátoru k mikrokontroléru je potřeba osm kolíků. Pokud existují 3 - 4 indikátory (číslice), pak se úkol stává prakticky nemožným. Jen málo pinů mikrokontroléru. V tomto případě lze indikátory připojit v multiplexním režimu, v režimu dynamické indikace.

Závěry stejnojmenných segmentů každého indikátoru jsou kombinovány. Ukazuje se matice LED připojených mezi výstupy segmentů a společné výstupy indikátorů. Zde je obvod pro multiplexní ovládání třímístného indikátoru se společnou anodou.

Pro připojení tří indikátorů bylo zapotřebí 11 pinů, nikoli 24, jako v režimu statického ovládání.

Při dynamické indikaci svítí vždy pouze jedna číslice. Vysokoúrovňový signál (5 V) je přiveden na společný výstup jednoho z bitů a nízkoúrovňové signály jsou posílány na segmentové výstupy pro ty segmenty, které mají v tomto bitu svítit. Po určité době dojde k zapálení dalšího výboje. Na jeho společný výstup je aplikována vysoká úroveň a stavové signály pro tento bit jsou odesílány do segmentových výstupů. A tak pro všechny bity v nekonečné smyčce. Doba cyklu se nazývá obnovovací čas indikátoru. Pokud je doba regenerace dostatečně krátká, pak lidské oko přepínání výbojů nezaznamená. Bude se zdát, že všechny výboje neustále svítí. Aby se zabránilo blikání indikátorů, má se za to, že frekvence regeneračního cyklu by měla být alespoň 70 Hz. Snažím se používat alespoň 100Hz.

Dynamický indikační obvod pro LED se společnou katodou vypadá takto.

Polarita všech signálů je obrácená. Nyní je aplikována nízká hladina na společný vodič aktivního výboje a vysoká hladina je aplikována na segmenty, které by měly svítit.

Výpočet prvků dynamické indikace indikátorů svítivých diod (LED).

Výpočet je poněkud složitější než u statického režimu. Při výpočtu je nutné určit:

  • průměrný proud segmentů;
  • impulsní proudové segmenty;
  • odpor segmentového odporu;
  • pulzní proud společných závěrů výbojů.

Protože číslice indikátoru se postupně rozsvěcují, pak jas záře určuje průměrný proud. Musíme jej zvolit na základě parametrů indikátoru a požadovaného jasu. Průměrný proud určí jas indikátoru na úrovni odpovídající statickému řízení se stejným konstantním proudem.

Zvolme průměrný segmentový proud 1 mA.

Nyní vypočítejme impulsní proud segmentu. Pro zajištění požadovaného průměrného proudu musí být pulzní proud Nkrát větší. Kde N je počet číslic indikátoru.

I segm. imp. = I segm. prům. *N

Pro naše schéma I segm. imp. = 1 * 3 = 3 mA.

Vypočítáme odpor rezistorů, které omezují proud.

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

R \u003d (5–1,5) / 0,003 \u003d 1166 ohmů

Určujeme pulzní proudy společných závěrů výbojů. Současně může svítit 8 segmentů, což znamená, že pulzní proud jednoho segmentu musí být vynásoben 8.

I kategorie imp. = I segm. imp. * 8

Pro naše schéma vypouštím imp. = 3 * 8 = 24 mA.

  • odpor rezistorů je zvolen 1,1 kOhm;
  • výstupy mikrokontroléru segmentového řízení musí poskytovat proud minimálně 3 mA;
  • výstupy mikrokontroléru pro volbu indikační číslice musí poskytovat proud minimálně 24 mA.

S takovými hodnotami proudu lze indikátor připojit přímo ke svorkám desky Arduino, bez použití dalších klíčů. Pro jasné indikátory jsou takové proudy dostačující.

Schémata s dalšími klíči.

Pokud indikátory vyžadují větší proud, musí být použity další spínače, zejména pro signály volby číslic. Celkový vybíjecí proud je 8násobek proudu jednoho segmentu.

Schéma zapojení LED indikátoru se společnou anodou v multiplexním režimu s tranzistorovými spínači pro volbu číslic.

Pro výběr bitu v tomto obvodu je nutné generovat signál nízké úrovně. Odpovídající klíč se otevře a napájí vybití indikátoru.

Schéma zapojení LED indikátoru se společnou katodou v multiplexním režimu s tranzistorovými spínači pro volbu číslic.

Pro výběr bitu v tomto obvodu je nutné generovat signál vysoké úrovně. Odpovídající spínač otevře a sepne společný výstup výboje k zemi.

Mohou existovat obvody, ve kterých je nutné použít tranzistorové spínače jak pro segmenty, tak pro společné výboje. Taková schémata lze snadno syntetizovat ze dvou předchozích. Všechny zobrazené obvody se používají, když je indikátor napájen napětím rovným napětí mikrokontroléru.

Klávesy pro indikátory se zvýšeným napájecím napětím.

Existují indikátory velkých velikostí, ve kterých se každý segment skládá z několika LED zapojených do série. Pro napájení takových indikátorů je potřeba zdroj s napětím větším než 5 V. Spínače musí zajišťovat spínání vysokého napětí řízené signály úrovně mikrokontroléru (obvykle 5 V).

Obvod kláves, které uzavírají signály indikátoru k zemi, zůstává nezměněn. A vypínače by měly být sestaveny podle jiného schématu, například tohoto.

V tomto schématu je aktivní výboj zvolen vysokou úrovní řídicího signálu.

Mezi přepnutím bitů indikátoru na krátkou dobu (1-5 µs) by se měly všechny segmenty vypnout. Tato doba je nezbytná k dokončení přechodných procesů přepínání klíčů.

Konstrukčně lze závěry výbojů kombinovat jako v jednom případě vícemístného indikátoru nebo sestavit vícemístný indikátor ze samostatných jednomístných. Navíc můžete indikátor sestavit z jednotlivých LED sdružených do segmentů. To se obvykle provádí, když je nutné sestavit indikátor velmi velkých rozměrů. Pro takové možnosti budou platit všechna výše uvedená schémata.

V další lekci připojíme k desce Arduino sedmisegmentový LED indikátor, napíšeme knihovnu pro jeho ovládání.

Kategorie: . Můžete vytvořit záložku.

Někdy je potřeba k mikrokontroléru připojit několik sedmisegmentových indikátorů nebo LED matici, zatímco k zobrazení informací se používá dynamická indikace. Podstatou dynamické indikace je sériový výstup informací do indikátorů. Níže uvedený diagram ukazuje příklad připojení několika sedmisegmentových indikátorů (například se společnou katodou) k implementaci dynamické indikace, obecně se s přihlédnutím k bodu získá 8 segmentů, ale starým způsobem jsou nazvaný tak. Všechny závěry (anody) stejnojmenných segmentů jsou spojeny dohromady, celkem tedy 8 linek, které jsou k mikrokontroléru připojeny přes odpory. Společná katoda každého indikátoru je připojena k mikrokontroléru přes tranzistor.


Algoritmus indikace je následující: nejprve nastavíme požadované logické úrovně na řádcích v závislosti na tom, které segmenty musí být zapnuty na prvním indikátoru (indikace zleva doprava), s vysokou logickou úrovní pro zapnutí, nízkou až vypněte segment. Dále aplikujeme vysokou logickou úroveň na bázi tranzistoru VT1, čímž je společná katoda prvního indikátoru připojena ke společnému vodiči, v tuto chvíli se rozsvítí ty segmenty, na jejichž anodách je logická jednotka. Po určité době (pauza) indikátor vypneme aplikací nízké logické úrovně na bázi tranzistoru, poté opět změníme logické úrovně na linkách v souladu s výstupní informací určenou pro druhý indikátor a odešleme zapínací signál do tranzistoru VT2. Tedy v pořadí v kruhovém cyklu přepínáme všechny indikátory, to je celá dynamická indikace.

Pro získání solidního obrazu bez blikání je třeba přepínání provádět vysokou rychlostí, aby nedocházelo k blikání LED, obnovovací frekvence musí být nastavena od 70 Hz a více, já ji obvykle nastavuji na 100 Hz. Pro výše uvedenou konstrukci je pauza vypočítána následovně: pro frekvenci 100 Hz je perioda 10 ms, jsou pouze 4 indikátory, respektive doba svitu každého indikátoru je nastavena na 10/4 = 2,5 ms. V jednom pouzdře jsou vícemístné sedmisegmentové indikátory, ve kterých jsou stejnojmenné segmenty propojeny uvnitř samotného pouzdra, samozřejmě pro jejich použití je nutné použít dynamickou indikaci.

Pro implementaci dynamické indikace je nutné použít přerušení při přetečení jednoho z časovačů. Níže je uveden kód využívající časovač TMR0:

;Implementace dynamické indikace pro 4 sedmisegmentové indikátory;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; swapf STATUS,W ; clrf STAV ; movwf STATUS_TEMP ; ; bcf ind1 ;vypnout 1. indikátor bcf ind2 ;vypnout 2. indikátor bcf ind3 ;vypnout 3. indikátor bcf ind4 ;vypnout 4. indikátor; incf shet,F ;přírůstek registru shet movlw .5 ;zkontrolovat obsah registru shet xorwf shet,W ;zkontrolovat, zda se rovná 5 btfss STATUS,Z ; goto met1 ;číslo v registru listů se nerovná 5 movlw .1 ;číslo v registru listů je 5: zapište číslo 1 movwf list ;do registru listů ; met1 movlw .1 ;zkontrolovat obsah registru list xorwf shet,W , roven číslu 1 btfss STATUS,Z ; goto met2 ;číslo v registru listů není rovno 1: skok na met2 movf datind1,W ;číslo v registru listů je rovno 1: kopírování movwf PORTB ;obsah registru datind1 do registru PORTB bsf ind1 ;zapněte 1. indikátor met2 movlw .2 ;kontrola obsahu registrového listu xorwf shet,W , rovná se 2 btfss STATUS,Z ; goto met3 ;číslo v registru listů se nerovná 2: skok na met3 movf datind2,W ;číslo v registru listů je 2: zkopíruj movwf PORTB ;obsah registru datind2 do registru PORTB bsf ind2 ;zapni 2. indikátor goto exxit ;skoč na štítek exxit met3 movlw .3 ;zkontrolovat obsah registru list xorwf list,W , rovná se 3 btfss STATUS,Z ; goto met4 ;číslo v registru listu se nerovná 3: skok na met4 movf datind3,W ;číslo v registru listu je 3: zkopíruj movwf PORTB ;obsah registru datind3 do registru PORTB bsf ind3 ;zapni 3. indikátor goto exxit ;skoč na štítek exxit met4 movf datind4,W ;zkopírujte obsah registru datind3 movwf PORTB ;do registru PORTB bsf ind4 ;zapněte 4. indikátor; movlw .100 ;zápis 156 do registru časovače TMR0 movwf TMR0 ; ; movwf STAV ; swapf W_TEMP,F ; swapf W_TEMP,W ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Hlavní program ................. movlw b"11010011" ; OPTION_REG, čímž se nastaví vnitřní ; nastavení poměru předděličky 1:16 ; clrf shet ; reset registru Shet, před spuštěním, přerušení při přetečení TMR0, provedeno; clrf datind1 ;vymazání registrů pro výstup informací do clrf datind2 ;indikátory, to je ekvivalentní vypnutí clrf datind3 ;indikátory, jako indikátory se společnou clrf datind4 ;katodou; bcf INTCON,T0IF ;zrušte příznak přerušení přetečení TMR0 bsf INTCON,T0IE ;povolte přerušení přetečení TMR0 bsf INTCON,GIE ;povolte globální přerušení; movlw b"00000110" ; 13.52 příklad výstupu movwf datind1 ; movlw b"11001111" ; movwf ze dne2 ; movlw b"01101101" ; movwf ze dne3 ; movlwb"01011011" ; movwf ze dne4 ; ; . ................; .................; .................; ; konec, konec celého programu;

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

;Implementace dynamické indikace pro 4 sedmisegmentové indikátory

;Příklad hodinové frekvence 4 MHz, cyklus stroje 1 µs

org 0000h ;spusťte provádění programu na adrese 0000h

goto Start ;přejděte na štítek Start

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

;Přerušení rutiny

org 0004h ;spuštění provádění podprogramu na adrese 0004h

movwf W_TEMP ;uložení hodnot registru klíčů

swapf STATUS,W ;

movwf STATUS_TEMP ;

bcf ind1 ;vypnout 1. indikátor

bcf ind2 ;vypnout 2. indikátor

bcf ind3 ;vypnout 3. indikátor

bcf ind4 ;vypnout 4. indikátor

incf list,F ;přírůstek listu registru

movlw .5 ; zkontrolujte obsah registračního listu

xorwf shet,W ; rovno 5

btfss STATUS,Z ;

goto met1 ;číslo v registračním listu se nerovná 5

movlw .1 ;číslo v registru listů je 5: napište číslo 1

movwf list ;zaregistrovat list

met1 movlw .1 ; zkontrolujte obsah registru listů

xorwf list,W ; rovno číslu 1

btfss STATUS,Z ;

goto met2 ;číslo v registru listů není rovno 1: skok na met2

movf datind1,W ;číslo v registru listů je 1: kopie

movwf PORTB; obsah registru datind1 do registru PORTB

bsf ind1 ;zapněte 1. indikátor

goto exit ;přejít na štítek exit

met2 movlw .2 ; zkontrolujte obsah registru listů

xorwf list,W ; rovno číslu 2

btfss STATUS,Z ;

goto met3 ;číslo v registru listů není rovno 2: skok na met3

movf datind2,W ;číslo v registru listů je 2: kopie

movwf PORTB, obsah registru datind2 do registru PORTB

bsf ind2 ;zapněte 2. indikátor

goto exit ;přejít na štítek exit

met3 movlw .3 ; zkontrolujte obsah registru listů

xorwf list,W ; rovno číslu 3

btfss STATUS,Z ;

goto met4 ;číslo v registru listů není rovno 3: skok na met4

movf datind3,W ;číslo v registru listů je 3: kopie

movwf PORTB; obsah registru datind3 do registru PORTB

bsf ind3 ;zapněte 3. indikátor

goto exit ;přejít na štítek exit

met4 movf datind4,W ; zkopírujte obsah registru datind3

movwf PORTB ;do registru PORTB

bsf ind4 ;zapněte 4. indikátor

exit bcf INTCON,T0IF ;resetovat příznak přerušení přetečení TMR0

movlw .100 ;zapište číslo 156 do registru časovače TMR0

swapf STATUS_TEMP,W ; obnovení obsahu registrů klíčů

swapf W_TEMP,F ;

swapf W_TEMP,W ;

retfie ;ukončit rutinu přerušení

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

;Hlavní program

Start ................. ; počáteční nastavení registrů

................. ;speciální účel

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

bsf STATUS,RP0 ;zápis binární číslo 11010011 k registraci

movlw b"11010011" ;OPTION_REG, čímž se nastaví vnitřní

movwf OPTION_REG ; zdroj hodin pro TMR0

bcf STATUS,RP0 ;povolit předděličku před TMR0

;Nastavte poměr předděličky na 1:16

clrf shet ; před spuštěním resetujte registr listů

;přetečení přerušení TMR0, provedeno

;jednou po zapnutí

clrf datind1 ; vymazat registry pro výstup informací do

clrf datind2 ;indikátory, ekvivalentní off

clrf datind3 ;ukazatele, jelikož ukazatele se společným

clrf datind4 ;katoda

bcf INTCON,T0IF ;resetovat příznak přerušení přetečení TMR0

bsf INTCON,T0IE ;povolit přerušení přetečení TMR0

bsf INTCON,GIE; povolit globální přerušení

movlw b"00000110" ; Příklad výstupu 13.52

movlw b"11001111" ;

movlw b"01101101" ;

movlwb"01011011" ;

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

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

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

konec; konec celého programu

V hlavním programu jsme nejprve nastavili časovač pomocí registru OPTION_REG, dříve jsem mluvil o použití časovačů pro . Dále vymažeme registr listů určený pro zadání počtu od 1 do 4 pro každý indikátor. Tento registr je inkrementován v rutině přerušení a tam upraven (bude počítat od 1 do 4), takže toto čištění provedeny jednou po zapnutí. Na základě tohoto registru určíme, který ukazatel zahrnout a vydáme mu odpovídající údaje. Dalším krokem je vymazání registrů úložiště informací, čtyři registry dataind1,2,3,4 odpovídající čtyřem indikátorům. Vymazání je ekvivalentní vypnutí indikátorů, protože při obslužné rutině přerušení se obsah těchto registrů přenese do registru PORTB, ke kterému jsou připojeny anody indikátoru. To je nezbytné, aby se po povolení přerušení na indikátorech nezobrazovaly žádné smetí, v zásadě to nelze provést, pokud jsou na výstup okamžitě zapsány správné informace. Dále resetujte příznak přerušení přetečení časovače, povolte přerušení přetečení TMR0 a nakonec povolte globální přerušení.

V rutině přerušení nejprve vypneme všechny indikátory (aplikací nízkých logických úrovní na báze tranzistorů), protože není známo, který je zapnutý. Zvyšujeme registr listu, kontrolujeme rovnost s číslem 5, pokud existuje taková shoda, zapište do registru číslo 1, protože je nutné počítat od 1 do 4. Dále zkontrolujeme, které číslo je v listu registr, kterým načteme data z PORTB do PORTB informačních registrů úložiště (dataind) pro příslušný indikátor a zapneme jej. Poté resetujeme příznak přerušení přetečení TMR0, zapíšeme do časovače číslo 100 (výpočet této hodnoty je uveden níže) na časové zpoždění a ukončíme obsluhu přerušení. Při prvním přerušení se rozsvítí první indikátor, při druhém přerušení druhý a tak dále v kruhovém cyklu. V hlavním programu zbývá pouze načíst data do registrů úložiště informací pro každý indikátor. V podprogramu přerušení nezapomeňte uložit a obnovit hodnoty klíčových registrů, o tom jsem psal v článku.

Pro výstup čísel je lepší použít generátor znaků ve formě datové tabulky. Například pro zobrazení čísla 3456 na indikátorech je nutné jej rozdělit na číslice, zatímco pro uložení čísel číslic je lepší použít samostatné registry (od 0 do 9), poté tyto registry spustit přes generátor znaků, čímž získání správných bajtů (načtených do dataind registrů) pro zapálení příslušných segmentů.

Frekvenci generátoru hodin budeme brát 4 MHz, cyklus stroje je 1 μs. Obnovovací frekvence každého indikátoru nechť je 100 Hz (perioda T = 10 ms), požadované časové zpoždění je 10/4 = 2,5 ms. Faktor předděličky pro TMR0 je nastaven na 1:16, přičemž maximální možné zpoždění je 256x16 = 4096 µs a potřebujeme pauzu 2,5 ms. Vypočítejme číslo, které se má zapsat do TMR0: 256-((256x2,5)/4,096) = 256-156,25 = 99,75. Po zaokrouhlení dostaneme číslo 100.

Níže si můžete stáhnout model programu Proteus, firmware a zdrojový kód s implementací dynamické indikace na 4-místném indikátoru se společnou katodou pomocí mikrokontroléru PIC16F628A. Na indikátoru se například zobrazí čísla 0000; 0001; 0002; 13,52; 9764.

Nyní zvažte připojení matice s rozlišením 8x8 pixelů (LED). Struktura matice je obvykle uvažována z hlediska řádků a sloupců. Na obrázku níže jsou v každém sloupci zapojeny katody všech LED a v každé řadě anody. Řetězce (8 linek, LED anody) jsou připojeny přes odpory k mikrokontroléru. Každý sloupec (LED katody) je připojen k mikrokontroléru přes 8 tranzistorů. Algoritmus indikace je stejný, nejprve na řádcích nastavíme potřebné logické úrovně, podle kterých mají LED ve sloupci svítit, poté připojíme první sloupec (indikace zleva doprava). Po určité pauze sloupec vypneme a změníme logické úrovně na řádcích tak, aby se zobrazil druhý sloupec, poté připojíme druhý sloupec. A tak střídavě dojíždět všechny kolony. Níže je schéma připojení matice k mikrokontroléru.


Celkově je pro připojení takové matice zapotřebí 16 pinů mikrokontroléru, což je poměrně hodně, proto je pro snížení řídicích linek lepší použít sériové posuvné registry.

Nejběžnějším sériovým registrem je mikroobvod 74HC595, který obsahuje posuvný registr pro načítání dat a přídržný registr, přes který jsou data přenášena na výstupní linky. Načítání dat do něj je jednoduché, na hodinovém vstupu SH_CP nastavíme logickou 0, na datovém vstupu DS pak nastavíme požadovanou logickou úroveň, načež hodinový vstup přepneme na 1, přičemž hodnotu úrovně uložíme (na vstupu DS) uvnitř posuvného registru. Zároveň jsou data posunuta o jeden bit. Znovu nastavte výstup SH_CP na 0, nastavte požadovanou úroveň na vstupu DS a zvyšte SH_CP na 1. Po plném načtení posuvného registru (8 bitů) nastavte výstup ST_CP na 1, v tuto chvíli se data přenesou do úložný registr a přiveden na výstupní linky Q0 ... Q7, načež resetujeme výstup ST_CP. Během sekvenčního načítání se data posunou z Q0 na Q7. Pin Q7' je připojen k poslednímu bitu posuvného registru, tento pin lze připojit ke vstupu druhého mikroobvodu, takže můžete načítat data do dvou nebo více mikroobvodů najednou. Pin OE přepne výstupní linky do třetího (vysokoodporového) stavu, když je na něj přivedena logická 1. Pin MR je určen k resetování posuvného registru, tedy nastavení nízkých logických úrovní na výstupech spouštěčů registru. , což je ekvivalentní načtení osmi nul. Níže je schéma načítání dat do mikroobvodu 74NS595, nastavení hodnoty 11010001 na výstupních linkách Q0 ... Q7 za předpokladu, že zpočátku byly nuly:


Zvažte připojení matice 8×8 k mikrokontroléru PIC16F628A pomocí dvou posuvných registrů 74HC595, schéma je uvedeno níže:


Data se načtou do čipu DD2 (regulace logické úrovně na řádcích, LED anody), poté se přenesou přes pin Q7 na DD3 (řízení sloupců), nejprve načteme bajt pro povolení sloupce, poté bajt s logickými úrovněmi na řádcích. Sloupce spínací matice tranzistorů (LED katody) jsou připojeny k výstupním linkám DD3. Níže je uveden programový kód pro zobrazení obrázku na matici:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Implementace dynamické indikace pro matici s rozlišením 8x8 ;Frekvence generátoru hodin např. 4 MHz, strojní cyklus 1 µs org 0000h ;spuštění provádění programu z adresy 0000h goto Start ;skok na popisek Start ;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Přerušit rutinu org 0004h ;spustit provádění podprogramu z adresy 0004h movwf W_TEMP ;uložit hodnoty registru klíčů swapf STATUS,W ; clrf STAV ; movwf STATUS_TEMP ; ; movwf FSR_osn ;do registru FSR_osn movf FSR_prer,W ;obnovení dříve uložené hodnoty movwf FSR ;registru FSR z registru FSR_prer ;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;nahrát obsah registru stolb do čipu movf stolb,W ;zkopírovat obsah registru stolb movwf var ;do registru var met2 btfsc var,0 ;nastavit výstup ds v souladu s btfss var,0 ; bcf ds; bcf sh_cp ; rrf var,F ;Posunovací registr var právo připravit;další bit goto met2 ;scetbit se nerovná nule: skok na štítek met2 ;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;nahrát obsah registru INDF do čipu;74HC595 (sériový posuvný registr) movf INDF,W ;zkopírovat obsah registru INDF movwf var ;do registru var movlw .8 ;zapsat číslo 8 do registru scetbit, pro počítání movwf scetbit ;přenesené bity met1 btfsc var ,7 ;nastavit výstupní ds podle bsf ds ;hodnota 7. bitu registru var btfss var,7 ; bcf ds; bsf sh_cp ;hodinový výstup sh_cp pro uložení dat bcf sh_cp ; rlf var,F ;Posunutí registru var vlevo pro přípravu;další bit decfsz scetbit,F ;Snížení s podmínkou registru scetbit goto met1 ;scetbit se nerovná nule: Skok na štítek met1 ; bsf st_cp, hodiny výstupu st_cp pro přenos načteného bcf st_cp, bajtů na výstupní linky čipů 74HC595; bcf STATUS,C ;reset bitu C stavu registru před posunem rrf stolb,F ;levý posuvný registr stolb ; incf FSR,F ;Zvýšení registru FSR, připravte další ;Zaregistrujte se pro odeslání dat na 74HC595 decfsz shet,F ;Snížení s podmínkou registru shet goto exxit ;Registr listu se nerovná 0: Skok k ukončení movlw data1 ;Registr listů se rovná 0: Nejprve zapište adresu movwf FSR ;Registr pro ukládání informací do registru FSR movlw .8 ;Zápis čísla 8 do registru listů, pro udržování listu movwf ;Počítání sloupců ; exit bcf INTCON,T0IF ;reset příznak přerušení přetečení TMR0 movlw . 124 ;zapište číslo 124 do registru časovače TMR0 movwf TMR0 ; ; movf FSR,W ;Uložit aktuální hodnotu FSR movwf FSR_prer ;Do FSR_prer movf FSR_osn ,W ;Obnovit dříve uloženou hodnotu movwf FSR ;FSR z FSR_osn ; swapf STATUS_TEMP,W ;obnovení obsahu registrů klíčů movwf STATUS ; swapf W_TEMP,F ; swapf W_TEMP,W ; ; retfie ;opuštění podprogramu přerušení;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Spuštění hlavního programu ................ ;Počáteční nastavení registrů ................. ;Speciální účel..... ............ bsf STATUS,RP0 ;zapište binární číslo 11010011 do registru movlw b"11010010" ;OPTION_REG, čímž nastavíte interní movwf OPTION_REG ;zdroj hodin pro TMR0 bcf STATUS,RP0 ;předem povolte předděličku TMR0, nastavte poměr předděličky 1:8; movlw .8 ;zapište číslo 8 do registru listů, před spuštěním movwf shet ;tmr0 přetečení přeruší, provede se;jednou, po zapnutí movlw b"10000000" ;zapište binární číslo 10000000 do movwf stolb ;registr stolb, je povoleno 1. sloupec; proveden jednou, po zapnutí napájení; movlw data1 ;Zapište adresu prvního registru (úložné registry movwf FSR_prer ;informace) do registru FSR_prer, provedeno;jednou po zapnutí; movlw .8 ;vymazání 8 registrů výstupu informací do movwf tmp ;matice, ekvivalentní vypnutí movlw data1 ;matice movwf FSR ; met3 clrf INDF ; incf FSR,F ; decfsz tmp,F ; goto met3 ; ; bcf INTCON,T0IF ;zrušte příznak přerušení přetečení TMR0 bsf INTCON,T0IE ;povolte přerušení přetečení TMR0 bsf INTCON,GIE ;povolte globální přerušení; m1 movlw data1 ; pří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 ; ; .................; .................; .................; ; konec, konec celého programu;

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

;Implementace dynamické indikace pro matici s rozlišením 8x8

;Příklad hodinové frekvence 4 MHz, cyklus stroje 1 µs

org 0000h ;spusťte provádění programu na adrese 0000h

goto Start ;přejděte na štítek Start

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

;Přerušení rutiny

org 0004h ;spuštění provádění podprogramu na adrese 0004h

movwf W_TEMP ;uložení hodnot registru klíčů

swapf STATUS,W ;

movwf STATUS_TEMP ;

movf FSR,W ;uložte aktuální hodnotu registru FSR

movwf FSR_osn ;do registru FSR_osn

movf FSR_prer,W ; obnoví dříve uloženou hodnotu

movwf FSR ;FSR z FSR_prer

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

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

movf stolb,W ; zkopírujte obsah registru stolb

movwf var ;zaregistrovat var

movlw .8 ;zapište číslo 8 do registru scetbit, pro počítání

movwf scetbit ;vysílané bity

met2 btfsc var,0 ;nastav ds vystup podle

bsf ds ;7. bitová hodnota registru var

bsf sh_cp ;hodinový výstup sh_cp pro zachycení dat

rrf var,F ; posun registru var právo připravit

; další kousek

decfsz scetbit,F ;dekrementace s podmínkou registru scetbit

goto met2 ;scetbit se nerovná nule: skok na štítek met2

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

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

movf INDF,W ; zkopírujte obsah registru INDF

movwf var ;zaregistrovat var

movlw .8 ;zapište číslo 8 do registru scetbit, pro počítání

movwf scetbit ;vysílané bity

met1 btfsc var,7 ;nastav ds vystup podle

bsf ds ;7. bitová hodnota registru var

bsf sh_cp ;hodinový výstup sh_cp pro zachycení dat

rlf var,F ;levý posun var k přípravě

; další kousek

decfsz scetbit,F ;dekrementace s podmínkou registru scetbit

goto met1 ;scetbit se nerovná nule: skok na štítek met1

bsf st_cp ;hodiny výstupu st_cp k přenosu načteny

bcf st_cp ;bajtů na 74HC595 výstupních řádků

bcf STATUS,C ; před posunem vymažte bit C stavového registru

rrf stolb,F ;levý posuvný registr stolb

incf FSR,F ;přírůstek registru FSR, připravit další

Zaregistrujte se pro odesílání dat na 74HC595

decfsz list,F ;dekrementace s listem stavu registru

goto exxit ;shet registr není roven 0: skok na exxit

movlw data1 ;registr list je 0: napište adresu prvního

movwf FSR ;Zaregistrujte se pro ukládání informací do FSR

movlw .8 ;zapište číslo 8 do registru listů, pro referenci

movwf list ;počet sloupců

movlw b"10000000" ;zapište binární číslo 10000000 do

movwf stolb ;zaregistrovat stolb, zahrnout 1. sloupec

exit bcf INTCON,T0IF ;resetovat příznak přerušení přetečení TMR0

movlw .124 ;zapište číslo 124 do registru časovače TMR0

movf FSR,W ;uložte aktuální hodnotu registru FSR

movwf FSR_prer ;do registru FSR_prer

movf FSR_osn ,W ; obnoví dříve uloženou hodnotu

movwf FSR ;FSR od FSR_osn

swapf STATUS_TEMP,W ; obnovení obsahu registrů klíčů

swapf W_TEMP,F ;

swapf W_TEMP,W ;

retfie ;ukončit rutinu přerušení

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

;Hlavní program

Start ................. ;počáteční nastavení registrů

................. ;speciální účel

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

bsf STATUS,RP0 ;zapište binární číslo 11010011 pro registraci

movlw b"11010010" ;OPTION_REG, čímž se nastaví vnitřní

movwf OPTION_REG ; zdroj hodin pro TMR0

bcf STATUS,RP0 ;povolit předděličku před TMR0

;Nastavte poměr předděličky na 1:8

movlw .8 ;před spuštěním zapište číslo 8 do registru listů

movwf shet ; Přetečení TMR0 přeruší, běží

;jednou po zapnutí

movlw b"10000000" ;zapište binární číslo 10000000 do

movwf stolb ;zaregistrovat stolb, zahrnout 1. sloupec

Informace s logickými úrovněmi pro řádky každého sloupce jsou uloženy v 8 registrech pro ukládání informací, ke kterým je přístup. Adresa prvního registru se jmenuje data1. Kromě prvotního zápisu registrů shet a stolb je nutné do registru FSR_prer zapsat adresu prvního registru úložiště informací (registr je data1, zápis do FSR_prer se provede jednou, poté se upraví v handler), teprve poté povolte přerušení přetečení TMR0.

Před povolením přerušení je žádoucí vymazat registry úložiště informací, tato operace se provádí pomocí přídavného registru tmp (jako čítače) a nepřímého adresování, vymazání je ekvivalentní vypnutí matice.

V rutině obsluhy přerušení načteme obsah registru stolb do čipu DD2 (při prvním vstupu do handleru po povolení přerušení registr obsahuje číslo 10000000, jak je uvedeno výše). Načítání začíná od spodního bitu registru stolb, který se při načítání posouvá ve směru z Q0 na Q7 (uvnitř čipu DD2), algoritmus načítání byl diskutován výše, takže si myslím, že nebude obtížné porozumět kódu . Dále načteme obsah registru INDF do DD2, jedná se o jeden z registrů úložiště informací, jehož adresa je v FSR (při prvním vstupu do handleru po povolení přerušení FSR obsahuje adresu prvního registr úložiště informací s názvem data1). Načítání začíná od horního bitu registru INDF. Po načtení uvažovaných 2 bajtů nataktujeme výstup st_cp, čímž se stažená data přenesou na výstupní linky mikroobvodů DD2, DD3. Na prvním vstupu do handleru se tedy přepne první sloupec matice, ve kterém se rozsvítí LED diody, na jejichž anodě je vysoká logická úroveň, v souladu s obsahem registru data1 (tzv. první registr ukládání informací).

Dále posuneme registr stolb o jeden bit doprava, abychom připravili druhý sloupec matice pro přepnutí při dalším vstupu do obsluhy přerušení. Příznak C registru STATUS musí být před posunem vymazán, protože k posunu dochází prostřednictvím tohoto příznaku a jeho stav není v době posunu znám. Po posunu inkrementujeme registr FSR a připravíme další úložný registr (po registru data1) s úrovněmi logických řádků pro druhý sloupec. Dále dekrementujeme registr listů s podmínkou, a pokud se nerovná nule, resetujeme příznak přerušení přetečení TMR0, zapíšeme číslo do časovače a ukončíme obsluhu přerušení.

Při příštím vstupu do handleru se aktivuje druhý sloupec matice atd. Při resetu registru listů (po přepnutí 8. sloupce) se do něj zapíše číslo 8 pro další cyklus přepínání sloupců, navíc se opraví hodnota registru stolb, adresa prvního registru úložiště informací ( data1) se zapisují do registru FSR.

Vypočítejme časové zpoždění pro časovač TMR0, taktovací frekvence je 4 MHz, cyklus stroje je 1 µs. Abychom se vyhnuli blikání LED, vezměme obnovovací frekvenci každého sloupce jako 100Hz (perioda T=10ms), časové zpoždění je 10/8 = 1,25ms. Poměr předděličky TMR0 jsme nastavili na 1:8, přičemž maximální možné zpoždění je 256x8 = 2048 µs. Při pauze 1,25 ms by měl časovač počítat (256x1,25) / 2,048 = 156,25 krát, zaokrouhlením nahoru dostaneme 156 impulsů. V souladu s tím je nutné do časovače zapsat číslo 256-156 = 100. To však není úplně správná hodnota, protože provedení rutiny přerušení nějakou dobu trvá, v tomto případě to trvá asi 190 µs, přepočteno za při zohlednění koeficientu předděličky dostaneme 190/8 = 23,75 nebo 24 počtů. Správná hodnota pro zápis do TMR0 je: 100+24=124.

V hlavním programu zapíšeme 8 registrů pro ukládání informací v souladu s tím, co chceme na matici zobrazit. Níže je schéma vysvětlující výstup informací do matice pro výše uvedený kód.


Kromě posuvných registrů existují specializované ovladače pro zobrazování informací na sedmisegmentových ukazatelích a LED matice, v tomto případě dynamickou indikaci implementuje řidič sám, zbývá mu pouze odeslat data k zobrazení. Zkontroloval jsem jeden z těchto populárních ovladačů v článku o.

Pod odkazem si můžete stáhnout firmware a zdrojový kód pro mikrokontrolér PIC16F628A s implementací dynamické indikace na matici 8x8 pomocí dvou posuvných registrů 74HC595, schéma zapojení bylo diskutováno výše. Na matrici se střídavě zobrazují písmena R, L, číslo 46, smajlík a jen vzor v podobě křížku, tato animace je znázorněna na videu níže.

se značkami, . Přečtěte si .

Dynamická indikace je jedním z problémů, kterým čelí začínající programátoři mikrokontrolérů. Bylo o tom řečeno mnoho, ale rozhodl jsem se, že to, co je známo, posílím pomocí obrázků a příkladů zdrojových textů v jazyce C, aby bylo snazší si tento způsob zobrazení osvojit.

1 Základy základů aneb úvod

Nejprve si definujme terminologii, kterou budeme v celém článku používat.

Pokud chcete ovládat displej skládající se z jednoho známého sedmisegmentového displeje, nečiní to žádné problémy – lze jej reprezentovat jako 8 nezávislých LED. Pokud potřebujete zobrazit více informací než jeden znak, začínají problémy: 2 známost je 16 LED, tři - 24 atd., to znamená, že pro třímístný displej nemusí výstupy mikrokontroléru stačit, nemluvě 6 nebo více bitové displeje a zejména maticové indikátory.

Pro zjednodušení souhlasíme s tím, že všechny naše indikátory jsou se společnou katodou. Řešení problému je celkem jednoduché: propojit výstupy segmentů všech indikátorů k sobě. Nyní, pokud chcete zobrazit informace jako první, měli byste aplikovat požadované úrovně na segmentové čáry a připojit společný výstup prvního indikátoru ke společnému vodiči obvodu. Vysoké hladiny samozřejmě musí být přítomny na společných katodách všech ostatních indikátorů. Je zřejmé, že požadované segmenty prvního indikátoru se rozsvítí. Pro výstup do druhého, třetího atd. indikátory by měly dělat totéž, tzn. aplikací logické nuly na jednu ze společných katod vybereme aktuálně zobrazený bit a stav segmentových čar určuje viditelný symbol.

Aby byl celý displej vnímán jako trvale svítící, musí se číslice přepínat rychle – častěji než 25krát za vteřinu. Jak vidíte, úrovně všech závěrů (kterých se mimochodem výrazně snížilo, než při obvyklém přístupu) se průběžně mění, tzn. nemají statické úrovně, ale dynamické, odtud název metody zobrazení - dynamická.

Obrázek s dynamickým zobrazením

2 Varianty hardwarové implementace

2.1 Ploché matice

Pokud abstrahujeme od sedmisegmentových indikátorů, pak lze náš displej reprezentovat jako matici jednotlivých LED, jejíž anody jsou sdruženy do řad matice a katody do sloupců. Vlastně to je přesně ono.

Je zřejmé, že použitím požadovaných úrovní na řádky a sloupce naší matice můžeme rozsvítit jakýkoli elementární LED segment (neboli pixel - toto je tradičnější termín pro maticové displeje). V závislosti na tom, jak přesně budeme měnit úrovně na řádcích a sloupcích, můžeme získat několik typů dynamické indikace:

  • po řádku;
  • po sloupcích;
  • segment po segmentu (na pixel);
  • smíšeným způsobem.

Možnost po sloupcích jsme zvažovali v předchozí kapitole. Volba po řádcích se od ní liší pouze tím, že řádky a sloupce naší matice jsou zaměněny. Metoda segment-by-segment spočívá v tom, že v každém okamžiku má pouze jeden řádek a jeden sloupec úroveň potřebnou k rozsvícení LED. To znamená, že kdykoli může svítit pouze jedna LED z celé matice (na rozdíl od předchozí možnosti kdy může svítit celý řádek nebo celý sloupec současně). Tato metoda se podobá televiznímu skenování, kdy paprsek prochází kolem celé obrazovky a osvětluje dovnitř správná místa fosfor. Smíšená verze, jak název napovídá, spočívá v tom, že současně "aktivní" úrovně mohou být přítomny na několika řádcích a sloupcích najednou.

První dvě možnosti jsou velmi snadno implementovatelné, a proto jsou široce používány. Třetí možnost se používá méně často, protože. vyžaduje více vysoké rychlosti aktualizace informací o řádcích a sloupcích a průměrný proud segmentem (tj. jas segmentu) je v tomto případě výrazně nižší než v jiných. Poslední smíšená metoda je nejméně častá, i když má řadu kladných vlastností. Tato metoda především vyžaduje použití stabilních zdrojů proudu v řadových a sloupcových obvodech, jinak bude jas svítících segmentů nevyhnutelně záviset na jejich celkový počet. A výpočet kombinací signálů na řádcích a sloupcích není příliš jednoduchý.

2.2 Vícerozměrné matice

Příklady, které jsme zvažovali, zahrnují implementaci monochromatický displej, tj. skládající se z jednobarevných LED diod. Co když chcete získat vícebarevný displej například z RGB LED? Existují dvě možná řešení.

První je jednoduše zvýšit počet řádků (nebo sloupců) naší matice tím, že každou RGB LED budeme považovat za 3 nezávislé samostatné LED. Velkou nevýhodou tohoto přístupu je 3x navýšení počtu řádků (resp. sloupců). Na jednoduchý příklad je snadné vidět, co to znamená v praxi: pomocí dvou osmibitových výstupků mikrokontroléru můžeme mít monochromatickou matici 8x8 segmentů nebo barvu 4x4. Souhlaste s tím, že ve druhém případě je prakticky nemožné zobrazit nic srozumitelného ...

Druhým způsobem je přechod od „ploché“ matice segmentů k „multidimenzionální“. Pokud signál každého řádku prochází multiplexerem 1x3, pak můžeme systém zobrazení RGB LED reprezentovat jako 3 nezávislé matice počátečního rozměru: každá matice se skládá z LED stejné barvy a požadovanou matici vybereme pomocí řídicí signály multiplexeru. Obrázek vysvětluje, co bylo řečeno.

Je zřejmé, že v případě vícerozměrné matice je také vyžadován další počet řídicích linek, tento počet však není tak velký: na stejných dvou portech ovladače můžeme získat barevný displej 7x7 !!!

2.3 Způsoby zmenšení rozměru matic

Pokud je počet pinů mikrokontroléru velmi omezený, budeme muset hledat způsoby, jak snížit počet řádků a sloupců naší matice. Zázraky se samozřejmě nedějí a v tomto případě budeme muset zaplatit tím, že kromě mikrokontroléru budou použity další mikroobvody. Jak asi tušíte, zde můžete použít dříve zvažovanou metodu „multidimenzionálních“ matic – přece nám nikdo nezakáže jednoduše použít trojnásobný počet jednobarevných LED namísto RGB LED? Hlavní je je vhodně uspořádat...

Takže můžeme zmenšit rozměr matice použitím:

  • dekodéry nebo multiplexery;
  • posuvné registry.

S multiplexery jsme se již setkali dříve, dekodér, jak správně tušíte, se od multiplexeru zásadně liší. Je třeba pouze dodat, že použitím dekodérů / multiplexerů pro řádky i sloupce je možné dosáhnout zmenšení rozměru matice v obou rozměrech najednou, v tomto případě však může být nutné použít pouze segment po segmentová dynamická indikace se všemi jejími nedostatky.

Posuvné registry mohou pomoci mnohem lépe než dekodéry. Zvažte schéma na obrázku níže.

Je snadné vidět, že jakýkoli počet řádků a sloupců bude vyžadovat pouze zvýšení počtu registrů a počet zapojených řídicích linek mikrokontroléru zůstane stejný! Malé mínus tento přístup je, že s rostoucím počtem registrů v řetězci bude nutné zvýšit rychlost sekvenčního výstupu informací v nich, což není vždy snadno dosažitelné. Tedy například běžné mikrokontroléry rodiny AVR, prakticky neumožňují překonat sériovou výstupní rychlost 10 megabitů / sec. Na druhou stranu, pokud použijete jiné řadiče, které dokážou vydávat signály rychleji, mohou začít problémy jiného řádu: šíření vysokofrekvenčního hodinového signálu po dlouhé lince (a při velkém počtu registrů to bude nevyhnutelně takové ) je zcela odlišný od nízkofrekvenčního, takže při zapojení budou vyžadována zvláštní opatření tištěný spoj a další věci, které v tomto článku nebudeme uvažovat.

3 Způsoby implementace softwaru

Nebudeme uvažovat o softwarové implementaci všech zmíněných možností dynamické indikace – tím se článek nesmyslně nafoukne. Omezíme se pouze na tři „nejběžnější“ příklady: plochá matice s přímým ovládáním řádků a sloupců, totéž s použitím dekodéru a nakonec varianta s využitím posuvných registrů. Ve všech případech bude zvláštní pozornost věnována všem nuancím implementace softwaru, to znamená, že kód C bude doprovázen vysvětlivkami pouze v případech, kdy se to shoduje se záměrem autora a v žádném případě ne s vaší úrovní školení. Tím naznačuji, že byste měli znát základy C beze mě.

U všech příkladů se shodneme na tom, že náš displej je postaven na sedmisegmentových indikátorech se společnou katodou.

3.1 Nejjednodušší způsob

Je zřejmé, že v programu by bylo nejpohodlnější mít pole, jehož obsah by jednoznačně určoval, které segmenty ve kterých známých oblastech displeje svítí - jakýsi analog obrazovky RAM.

Uveďme definici následujících konstant:

#define SCR_SZ 6 /* počet znakových mezer zobrazení */ #define ROWS PORTB /* port zobrazení "řádků", tzn. správa segmentů */ #define COLS PORTD /* port pro správu "sloupců", tzn. společné katody */

Nyní deklarujme obrazovku pole:

unsigned char SCR;

Pro začátek budeme předpokládat, že každý prvek pole odpovídá známosti displeje a každý bit tohoto prvku odpovídá určitému segmentu indikátoru. Který bit odpovídá kterému segmentu – v tomto případě nezáleží na tom, jak nezáleží na tom, jak jsou tyto bity nastaveny v bytech našeho pole, zatím budeme jen předpokládat, že tam již jsou. Také pro jednoduchost budeme předpokládat, že společné katody jsou připojeny k pinům portu COLS postupně: nejméně významný bit je indikátor nejvíce vpravo, pak druhý, pak třetí a tak dále.

Jak docílit toho, aby se toto pole „zobrazilo“ na displeji? Napíšeme následující kód:

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

Bude plnit požadovanou funkci? Ano. Ale je to špatné.

Nejprve si uvědomte, že nemáme žádnou kontrolu nad rychlostí aktualizace obsahu řádků a sloupců. Za druhé, všimněte si, že v době, kdy je nový prvek pole na výstupu ŘÁDKY na linkách COLS stará hodnota je stále přítomná! kam to vede? Navíc po nějaký zlomek sekundy se na známosti zobrazí segmenty sousední známé, tzn. některé segmenty budou falešně zvýrazněny.

Tomuto efektu se můžete vyhnout takto: před aktualizací obsahu ŘÁDKY, vždy zrušte známost, která byla předchozí. Abyste se neobtěžovali s definicí předchozí známosti, můžete uhasit vše najednou. Náš kód tedy vypadá takto:

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

Přidali jsme zatemnění celého displeje před aktualizací stavu segmentových čar (umístění vysoké úrovně na společné katody, indikátor vypneme bez ohledu na to, co je na anodě přítomno) a zavedli zpoždění na konci cyklus. Nyní bude displej fungovat mnohem lépe. Ale napsali jsme dobrý program? Bohužel ne.

Faktem je, že nekonečný cyklus zobrazování zatímco prostě nás nenechá dělat nic jiného. Co budeme mít za program, který umí jen něco zobrazit na ukazateli?! Všechno samozřejmě není 100% špatné, protože na přerušeních lze udělat něco užitečného ... a místo zpoždění zpoždění() můžete provádět některé akce ... Ale to vše je velmi, velmi pokřivené: není žádoucí provádět něco složitého a těžkopádného v obslužných rutinách přerušení; na druhou stranu, pokud se místo zpoždění udělá něco složitého a těžkopádného, ​​pak je těžké zajistit stejný výpočetní čas, jinak se ukáže, že známost svítí na jinou dobu, která bude vizuálně vypadat jako jejich záře nebo blikání různého jasu.

Obecně lze tuto volbu povolit pouze jako výjimku, pouze jako cvičný příklad, nebo v případě (ale pět, pouze jako výjimku!), kdy je hlavní problém, který je třeba vyřešit, velmi jednoduchý (může to být např. například problém měření ADC napětí a zobrazit jej).

co je třeba udělat? Odpověď je jako vždy jednoduchá: všechny procesy, které by měly být provedeny neznatelně od řešení hlavního úkolu (a indikací takový proces samozřejmě je), by měly být prováděny přerušeními časovače.
Přerušení budou přicházet v přesně definovaných intervalech, což zajistí rovnoměrnost záře známosti. Indikace na pozadí nám umožní jednoduše zapsat něco do pole ve správný čas v hlavní smyčce SCR- a okamžitě se objeví na displeji! A všechny změny kódu se projeví tím, že místo smyček používáme funkci obsluhy přerušení:

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

Pár komentářů.

variabilní poz, označující číslo aktuální svítící známosti, vytvoříme lokální statickou proměnnou tak, aby si zachovala svou hodnotu od přerušení k přerušení. Na konci funkce sami (koneckonců už nemáme cyklus) zvyšujeme číslo obeznámenosti, dokud nedosáhneme limitu – v tomto případě se vrátíme na začátek.

V hlavním programu budeme muset pouze inicializovat porty a časovač (v tomto případě - Časovač 0), aby přetékal v intervalech, které potřebujeme, a umožňoval přerušení. Poté si na indikaci nemůžete vzpomenout - bude fungovat tiše a klidně sama o sobě. Jak ale určit požadovaný interval přetečení časovače? Velmi jednoduché. Lidské oko vnímá blikání s frekvencí vyšší než 25 Hz jako nepřetržitou záři. Máme 6 indikátorů, každý z nich by měl blikat s takovou frekvencí, což znamená, že informace na displeji by se měly aktualizovat s frekvencí 25 x 6 = 150 Hz nebo více. Nyní spočítejme hodnotu předděličky časovače: vydělte taktovací frekvenci MK 256 ( Časovač 0 každý má AVR osmibitový, což znamená, že přeteče, počítá až 256) - to bude požadovaná hodnota časovače předděličky. Samozřejmě je nepravděpodobné, že výsledek bude odpovídat jedné ze standardních hodnot předděličky - to není problém, můžete vzít nejbližší menší vhodnou hodnotu. Indikace bude fungovat na vyšší frekvenci, ale to nezhorší její kvalitu! Vedlejším efektem bude velké zatížení jádra MK pro indikaci. Pokud to výrazně narušuje hlavní program, budete muset přenést indikaci na jiný časovač, například 16bitový Časovač 1 nebo zadejte počítadlo pro přeskočení přetečení časovače:

#define SKIP 15 /* počet přerušení časovače k ​​přeskočení */ ISR(TIMER0_OVF_vect)( statický znak bez znaménka pos = 0; statický znak bez znaménka přeskočit = SKIP; if (--skip) return; skip = SKIP; COLS = 0xFF; ŘÁDKY = SCR; COLS = ~(1<< pos); if(++pos == SCR_SZ) pos = 0; }

V těchto zjednodušených příkladech předpokládáme, že port COLS, kromě společných katod indikátorů není připojeno nic jiného. V reálném životě se však takové štěstí nestává často a se zbývajícími liniemi tohoto přístavu se nejspíš pojí něco jiného. Proto při organizování dynamické indikace je třeba vždy zajistit neměnnost stavu všech portů, které nejsou přímo zapojeny do indikace. To se provádí jednoduše: místo pouhého zápisu nové hodnoty do portu by se mělo použít maskování nepotřebných bitů:

COLS |= 0x3F; // takže uhasíme veškerou známost COLS &= ~(1<

Oba příkazy nemění hodnotu vysokých bitů portu COLS.

3.2 Metoda dekodéru

Dekodér lze použít buď ke konverzi HEX nebo BCD kód do sedmisegmentových znaků nebo k výběru jednoho ze sloupců matice. Obě možnosti se budou lišit od nejjednodušší metody zvažované dříve pouze v tom, jak bude organizován výstup na porty. ŘÁDKY a/nebo COLS ke kterému budou připojeny vstupy dekodéru.
Možnost použití dekodéru pro získání sedmisegmentového znaku:

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

Jak vidíte, změny jsou minimální - před zobrazením v ŘÁDKY znakový kód z pole SCR, jsou horní bity maskovány a poté jsou nastaveny nízké bity podle znakového kódu. To znamená, že uvažujeme, že dekodér je připojen ke 4. nejméně významným bitům portu ŘÁDKY.

Doufám, že nemá smysl uvádět příklad pro dekódování sloupců - stejně je vše jasné.

3.3 Metoda s registry

Přestože se dynamická indikace pomocí posuvných registrů zásadně neliší od dříve diskutovaných metod, existuje několik možností její implementace. Budeme zvažovat nejjednodušší - výstup bitů čistě softwarovými prostředky. A při implementaci dalších (pomocí USI/USART/SPI/TWI) si můžete vyzkoušet sami.

Pro variantu dříve zvoleného zobrazení 6 sedmisegmentových znakových mezer používáme 2 posuvné registry typu 74HC595. Tento registr je řízen třemi signály: hodinami vstupu sériových dat CLK, skutečné údaje DATA a puls současného paralelního výstupu informace zapsané do registru SOUBOR. Pojďme deklarovat odpovídající makra (pro jednoduchost „přeneseme“ všechny signály na jeden port):

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

Pro zápis do registru je vhodné napsat samostatnou funkci:

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 velmi žádoucí, aby tato funkce byla statická, protože bude použit v obsluze přerušení. Kompilátor s největší pravděpodobností udělá ve formuláři statické funkce v souladu-vloží do obsluhy přerušení, tzn. nedojde ke zbytečnému používání zásobníku, což u nestatických funkcí není zaručeno.

Nyní bude naše obsluha přerušení vypadat takto:

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

Vzhledem k tomu, že na jeho výstupech se současně objevují data zapsaná do registrů, není třeba nejprve vypínat indikátory. Je třeba si uvědomit, že sekvenční výstup programu je poměrně dlouhý proces, zejména u matic velkých rozměrů, takže byste jej měli co nejvíce optimalizovat z hlediska rychlosti. To lze nejlépe provést pomocí hardwaru sériového výstupu, který se nachází v MCU.

4 Pro ty, kteří nemají nikdy dost

Takže jste se seznámili se základy implementace dynamické indikace. Otázek ale jako obvykle neubývá, ale přibývá. Předvídat některé z nich, pokusím se okamžitě poskytnout potřebné odpovědi.

4.1 Anody, katody - co vybrat?

Vše, co jsme uvažovali dříve, se týkalo indikátorů se společnými katodami. A pokud chcete použít s běžnými anodami? Obecně zůstává vše při starém, až na to, že před výstupem bude nutné invertovat data - zatemnění obeznámenosti se provádí výstupem nul do COLS, zapalování - respektive jednotky a segmenty v ŘÁDKY bude obsahovat nuly místo jedniček. Obsluha přerušení se tedy změní na něco takového:

ISR(TIMER0_OVF_vect)( statický znak bez znaménka pos = 0; COLS &= 0xC0; ŘÁDKY = ~SCR; COLS |= (1<< pos); if(++pos == SCR_SZ) pos = 0; }

Všechno je jednoduché. Pokud se ovšem nepokusíte napsat univerzální kód, který je vhodný pro společné anody i společné katody. To lze provést dvěma způsoby: buď pomocí direktiv podmíněné kompilace, nebo pomocí transformační funkce. Předvedu první možnost a navrhuji přemýšlet o druhé samostatně.

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

Je to trochu těžkopádné, ale když to napíšete jednou, můžete to použít ve všech projektech téměř beze změn.

4.2 Blikání

V mnoha případech je displej využíván nejen jako prostředek k zobrazování informací přicházejících z vnitřku zařízení, ale také k zobrazování informací zadaných uživatelem. A v tomto případě je potřeba umět na displeji nějak oddělit nezměněné od proměnlivého. Nejjednodušší způsob, jak to udělat, je nechat blikat odpovídající známost (nebo několik známostí).

Je to velmi snadné. Představme si globální proměnnou, jejíž každý jednotlivý bit bude označovat blikající známost:

znak bez znaménka bliká = 0;

Nyní trochu upravíme obsluhu přerušení:

ISR(TIMER0_OVF_vect)( statický znak bez znaménka = 0; statický znak bez znaménka = 0; COLS |= 0x3F; if(!(bliknout & (1)<

Jak vidíte, byla přidána pouze jedna statická proměnná – čítač vstupů do obsluhy přerušení vstup a operátor pro testování stavu. Logika je jednoduchá: výstup dalšího známého se provádí pouze v případě, že buď v odpovídajícím bitu blikat nula nebo nejvýznamnější bit počítadla vstup rovná se 1. Pokud, předpokládejme, blikat obsahuje všechny nuly, pak je tato podmínka vždy splněna - zobrazí se všechny známé. Li blikat obsahuje 1 v jednom ze svých bitů, pak se odpovídající znak zobrazí pouze v době, kdy nejvýznamnější bit čítače je 1. Protože čítač se zvyšuje při každém vstupu obsluhy přerušení, odpovídající znak bude blikat při frekvence 128krát nižší než frekvence přerušení.

4.3 Nastavení jasu segmentů

O úpravě jasu jsem psal v samostatném článku, který se tak jmenoval.

4.4 Libovolná distribuce závěrů

Dříve se říkalo, že štěstí přidělit celý port MK pro indikaci padá jen zřídka. Ale ještě méně často je štěstí získat pohodlné trasování PCB, pokud je jeden port používán výhradně pro řádky a druhý port je používán pro sloupce matice displeje. Mnohem častěji je optimální směrování dosaženo pouze tehdy, když jsou řádky a sloupce smíchány mezi dvěma nebo dokonce více porty mikrokontroléru. Nebudete muset obětovat krásu desky plošných spojů, pokud během indikace zorganizujete softwarovou výměnu bitů.

Podívejme se na nějaký abstraktní příklad. Nechť je zajištěno nejlepší trasování s následující distribucí signálů podél čar portů MC:

Segment A

Segment B

segment H

Segment C

Segment D

G segment

Segment E

Segment F

Jak vidíte, maticové čáry jsou smíchány mezi třemi porty a všechny nevyužité linky těchto portů by samozřejmě neměly během procesu indikace měnit svou úroveň.

Nejlepší je začít vyvíjet dynamickou indikační funkci pro tento případ rozložením segmentů přes bity symbolů. Dříve jsme to uvažovali v poli SCR ukládáme bitové masky znaků, tzn. jednotky v byte označují světelné segmenty. Nepřemýšleli jsme o tom, který bit odpovídá kterému segmentu. Takže teď je čas se nad tím zamyslet.

Účel portových čar je vhodné namalovat ve formě tří desek:

1

A

0

4

H

3

2

B

F

E

5

G

D

C

Musíme shromáždit všechny segmenty do jednoho bajtu. Budete to muset udělat se směnnými operacemi, takže byste se měli pokusit je rozdělit tak, abyste udělali minimum směn. Pojďme diskutovat.

Pokud segment bit FEGDC ponechat v symbolu tak, aby spadaly do PORTD bez posunů, pak segment H může také zůstat v 6. bitu znaku a také nemusí být před výstupem posunut PORTC, ale pro segmenty A A V zůstanou bity 7 a 3, tedy nejspíše segment V bude muset být před výstupem posunut o 3 pozice a segment A- do 6. U této možnosti se zastavím a můžete pokračovat v hledání minima směn (posuny o více pozic nejsou tak rychlá operace, proto je žádoucí jejich počet snížit na minimum).

V našem případě jsme tedy dostali následující rozdělení bitů po bajtech:

A

H

F

E

B

G

D

C

Všimněte si bitových masek pro výstup na pří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

Pomocí těchto masek pomocí operace „bitový AND“ vybereme potřebné bity pro výstup na port.

Pojďme deklarovat konstanty masky:

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

Dříve jsme vypisovali znak na jeden port ŘÁDKY, nyní je tento postup rozdělen do tří částí:

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

Vezměte prosím na vědomí, že pro výstup do PORTC jeden bit musí být na výstupu bez posunu a druhý - s posunem, takže místo MASKC musel použít samostatná makra _BV().

Nyní zbývá rozhodnout, jak uhasit a rozsvítit odpovídající známost. Pojďme deklarovat konstanty odpovídající řídicím bitům obeznámenosti:

#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)

Abychom uhasili veškerou známost, je nutné na porty vydat odpovídající konstanty COM_x:

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

Ale abyste se seznámili, budete muset být chytří (nemá smysl vystupovat na všechny tři porty, protože v závislosti na hodnotě bude aktivní pouze jeden bit na určitém portu poz), například pomocí operátoru přepí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; přerušení; případ 5: PORTD &= ~COM5; přerušení; )

Není to nejhezčí způsob, ale funguje to.

Naše obsluha přerušení má tedy následující podobu:

ISR(TIMER0_OVF_vect)( statický znak bez znaménka = 0; statický znak bez znaménka = 0; // zhasne PORTD |= COM_D; PORTC |= COM_C; PORTB |= COM_B; // výstup PORTD = (PORTD & ~MASKD) | ( SCR & MASKD); PORTB = (PORTB & ~MASKB) | ((SCR & MASKB) >> 6); PORTC = (PORTC & ~MASKC) | ((SCR & _BV(6)) | (((SCR & _BV (3)) >> 3); // blikat if(!(bliknout & (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; }

Nyní zbývá přijít na to, jak popsat symboly pro výstup pohodlnějším způsobem ... Navrhuji udělat následující: definovat konstanty odpovídající bitům segmentů a poté „konstruovat“ potřebné symboly z těchto konstant:

// elementární 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 dále

Pokud tedy potřebujete vytisknout nulu úplně vpravo od displeje, stačí napsat na správné místo:

SCR = d_0;

Pokud v jiném projektu potřebujete rozdělit bity jinak, změníte pouze čísla v makrech _BV() pro elementární segmenty a všechny postavy budou automaticky "předělány". V nejjednodušších případech popsaných na začátku nebudete muset dělat vůbec nic jiného, ​​ale u možnosti „bit swapping“ si samozřejmě budete muset pohrát.

4.5 Podpora tlačítek

Při tradičním nedostatku MK výstupů je velmi akutní problém velkého počtu tlačítek, bez kterých se jen málokdy nějaké zařízení obejde. Používají se různé matricové inkluze atd. triky, ale mírným zkomplikováním funkce dynamické indikace je snadné mít k dispozici tolik tlačítek, kolik je na displeji znát, přičemž navíc stačí použít pouze jeden port mikrokontroléru. Je pravda, že každé tlačítko musí být umístěno na diodě.

Schematicky je to znázorněno na obrázku.

A programově to vypadá takto:

#define keypin() (!(PIND & _BV(KEY))) ISR(TIMER0_OVF_vect)( statický znak bez znaménka pos = 0; statický znak bez znaménka = 0; statický znak bez znaménka tmp_key = 0; ŘÁDKY = 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; } }

Tady klíč- jedná se o makro, které nastavuje bit zvoleného portu, na kterém jsou všechna tlačítka "připojena", makro keypin() vrátí booleovskou hodnotu TRUE, pokud je vybraný pin logicky nízký. V příkladu jsou tlačítka připojena k PORTD.

Pokaždé, když dojde k přerušení časovače, všechny segmenty nejprve zhasnou - je to nutné, aby proud procházející LED nevedl k chybné nedetekci stisknutého tlačítka. Poté je vstup tlačítka dotazován - pokud je nízká úroveň, je stisknuto tlačítko připojené k příslušné katodě pozice. V proměnné tmp_key se shromažďují stavy tlačítek, které se přepisují do globální proměnné klíč po dokončení cyklu zobrazení. Jen je potřeba čas od času analyzovat hodnotu klíč a manipulujte se zjištěnými lisy:

Static unsigned char get_key()( unsigned char tmp = 0; tmp = klíč; _delay_ms(10); if(key == tmp) return tmp; jinak return 0; )

Tato jednoduchá funkce zaručuje, že nedojde k žádnému chvění tlačítek, i když vzhledem k „dynamickému“ charakteru dotazování tlačítek je pravděpodobnost klepání již nízká.

5 Co ještě?

Takže jste zvládli docela typické techniky pro implementaci dynamické indikace. Myslím, že tohle ti bude stačit napoprvé a možná i na celý život. Nakonec je hlavní věcí porozumění technikám a algoritmům a jemnosti a nuance lze vždy přidat sami. Co ale ještě může čekat „u“ dynamické indikace?

Jak jsem řekl dříve, můžete přidat a až do nezávislé regulace každého segmentu.

Můžete přemýšlet o optimálnosti obsluhy přerušení - pro vzdělávací účely jsem psal spíše hrubý kód, například jsem používal všude SCR, i když optimálnější by bylo načíst hodnotu do lokální proměnné jednou a pak s její hodnotou pracovat. I když s mým přístupem určitě pomůže optimalizátor, pro praxi stojí za to vyzkoušet a optimalizovat se, ovládat se velikostí výsledného kódu a/nebo rychlostí programu.

Můžete přemýšlet o zajímavé myšlence automatického nastavení jasu displeje v závislosti na úrovni okolního světla. Jak víte, LED indikátory jsou tím hůře rozlišitelné, čím tmavší je kolem - jen se rozmazávají. Proto je ve tmě rozumné snížit jas indikátorů a zvýšit jej ve dne. Nejjednodušší je použít samostatný fotorezistor nebo LED jako světelný senzor, ale můžete to udělat jinak: je známo, že LED může fungovat také jako fotodioda, takže pokud pro indikaci použijete port připojený ke vstupu ADC, pak, pokud si to přejete, můžete změřit foto-emf nesvítícího segmentu indikátoru a pomocí této hodnoty upravit jas ...

Můžete přemýšlet o použití hardwarového sériového výstupu, což jsem již naznačil.

Zajímavou verzi zcela univerzálního přístupu k dynamické indikaci, se kterou se také doporučuji seznámit, navrhl o MOLCHEC. Stručně řečeno podstata: rozdělení segmentů po znakových bitech, přiřazení portů pro ovládání indikátoru a dokonce i typ indikátoru - zkrátka all-all-all parametry - se nastavují formou konfigurační tabulky v EEPROM. Programově je vše organizováno na základě této tabulky: od inverze v závislosti na typu indikátoru až po bitovou výměnu na různých portech. Zdrojový kód programu dynamické indikace přitom zůstává vždy nezměněn a konfigurační tabulku si sestavuje koncový uživatel podle svých preferencí. Metoda je skutečně univerzální a flexibilní, je však spojena se zvýšenou spotřebou programové paměti.


3 Napsáno ARV, v 06:48 25.08.2010
Míša Být tebou, nedával bych taková rázná prohlášení „to nedokážeš“, „nikdo nenapsal“ nebo „autorská práva“, protože za prvé to není zdvořilé a za druhé:
1. Na matrici 10x16 jsem kdysi dávno udělal plíživou čáru (co to bylo) - video z její práce najdete v této poznámce http://site/content/view/160/38/
2. Napsal jsem článek (najdete ho v aktualitách - pro dnešek poslední), jak udělat ticker na LCD. pokud trochu namáháte mozek, pak předělat algoritmus pro výstup do matice je maličkost.
3. na mém webu není ani jeden článek odněkud zkopírovaný (copy-paste není autorské právo, máte to zapečetěno), všechny materiály jsou zcela originální. mnoho stránek má kopie těchto materiálů s mým svolením (nebo svolením autorů materiálů, kteří mají plné právo publikovat své materiály najednou na mnoha místech).

Komentáře mohou zanechat pouze registrovaní uživatelé.
Zaregistrujte se nebo se přihlaste ke svému účtu.

Indikátory jsou obvykle umístěny na místech vhodných pro prohlížení informací na nich zobrazených. Zbytek digitálního obvodu může být umístěn na jiných deskách plošných spojů. S nárůstem počtu indikátorů se zvyšuje počet vodičů mezi indikátorovou deskou a digitální tabulí. To vede k určitým nepříjemnostem při vývoji konstrukce a provozu zařízení. Stejný důvod vede ke zvýšení jeho nákladů.

Počet propojovacích vodičů lze snížit tím, že indikátory budou pracovat v pulzním režimu. Lidské oko má setrvačnost, a pokud jsou indikátory nuceny zobrazovat informace střídavě dostatečně vysokou rychlostí, pak se člověku bude zdát, že všechny indikátory zobrazují své informace nepřetržitě. Díky tomu je možné střídavě přenášet zobrazované informace na stejných vodičích. Obvykle stačí obnovovací frekvence 50 Hz, ale je lepší tuto frekvenci zvýšit na 100 Hz.

Podívejme se na blokové schéma zahrnutí sedmisegmentových LED indikátorů, znázorněné na obrázku 1. Tento obvod může poskytovat dynamickou indikaci výstupní digitální informace.


Obrázek 1. Strukturní diagram dynamické indikace

Obvod zobrazený na obrázku 1 zobrazuje čtyři digitální číslice. Každý bit je krátce připojen ke svému vstupu přepínače. Generátor slouží k nastavení rychlosti aktualizace informací na indikátorech. Binární čítač postupně generuje čtyři stavy obvodu a prostřednictvím tlačítek poskytuje alternativní napájení sedmisegmentových indikátorů.

Výsledkem je, že když spínač dodává BCD kód ze vstupu A na vstupy sedmisegmentového dekodéru, tento kód se zobrazí na indikátoru HL1. Když spínač dodá BCD kód ze vstupu B na vstupy sedmisegmentového dekodéru, tento kód se v cyklu zobrazí na indikátoru HL2 a tak dále.

Rychlost aktualizace informací v uvažovaném obvodu bude čtyřikrát nižší než frekvence generátoru. To znamená, že pro získání frekvence blikání indikátoru 100 Hz je zapotřebí frekvence oscilátoru 400 Hz.

Kolikrát jsme tím snížili počet propojovacích vodičů? Záleží na tom, kde nakreslíme průřez obvodu. Ponecháme-li na desce displeje pouze indikátory, pak bude jejich provoz vyžadovat 7 informačních signálů pro segmenty a čtyři spínací signály. Celkem je zde 11 vodičů. Ve statickém indikačním obvodu bychom potřebovali 7 × 4 = 28 vodičů. Jak vidíte, je výhra. Při implementaci 8bitové zobrazovací jednotky bude zisk ještě větší.

Ještě větší zisk bude, pokud je průřez obvodu nakreslen podél vstupů indikátorů. V tomto případě bude čtyřmístná zobrazovací jednotka vyžadovat pouze šest signálních vodičů a dva napájecí vodiče obvodu. Takový bod průřezu dynamického indikačního obvodu se však používá velmi zřídka.

Nyní spočítejme proud protékající každým segmentem LED, když svítí. K tomu používáme ekvivalentní obvod průtoku proudu jedním ze segmentů indikátoru. Toto schéma je znázorněno na obrázku 2.


Jak již bylo zmíněno dříve, LED vyžaduje pro správnou funkci proud 3 až 10 mA. Nastavíme minimální proud LED na 3 mA. V pulzním režimu provozu se však jas svitu indikátoru Nkrát sníží, přičemž koeficient N se rovná pracovnímu cyklu proudových impulsů dodávaných do tohoto indikátoru.

Chceme-li zachovat stejný jas žhavení, pak musíme N-krát zvýšit hodnotu pulzního proudu protékajícího segmentem. U osmimístného ukazatele je koeficient N roven osmi. Předpokládejme, že jsme zpočátku zvolili statický proud přes LED rovný 3 mA. Poté, aby byl zachován stejný jas LED v osmimístném indikátoru, je vyžadován pulzní proud:

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

Jen některé řady digitálních mikroobvodů mohou stěží poskytnout takový proud. Pro většinu sérií mikroobvodů budou vyžadovány zesilovače vyrobené na tranzistorových spínačích.

Nyní určíme proud, který bude protékat klíčem a přepneme tak napájení na jednotlivé bity osmibitové zobrazovací jednotky. Jak je patrné z obvodu znázorněného na obrázku 2, proud kteréhokoli segmentu indikátoru může protékat klíčem. Když se zobrazí číslo 8, bude nutné rozsvítit všech sedm segmentů indikátoru, což znamená, že pulzní proud protékající klíčem v tomto okamžiku lze určit následovně:

I cl \u003d I segrámus× N seg= 24 mA × 7 = 168 mA.

Jak se vám líbí tento proud?! V radioamatérských obvodech se často setkávám s řešením, kdy je spínací proud odebírán přímo z výstupu dekodéru, který nedokáže dodat proud větší než 20 mA a kladu si otázku - kde takový indikátor vidím? V úplné tmě? Ukazuje se „zařízení pro noční vidění“, tedy zařízení, jehož hodnoty jsou viditelné pouze v úplné tmě.

A nyní se podívejme na schematický diagram výsledné zobrazovací jednotky. Je to znázorněno na obrázku 3.



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

Nyní, když jsme obdrželi dynamický indikační obvod, můžeme diskutovat o jeho výhodách a nevýhodách. Nepochybnou výhodou dynamické indikace je malý počet propojovacích vodičů, což ji činí v některých případech nepostradatelnou, např. při práci s maticovými indikátory.

Jako nevýhodu je třeba uvést přítomnost velkých pulzních proudů, a protože jakýkoli vodič je anténa, slouží dynamická indikace jako silný zdroj rušení. Další cestou rušení je napájení.

Všimněte si, že čela spínacích impulsů jsou velmi krátká, takže jejich harmonické složky pokrývají rádiový frekvenční rozsah až po ultrakrátké vlny.

Použití dynamické indikace tedy umožňuje minimalizovat počet propojovacích vodičů mezi digitálním zařízením a indikátorem, ale zároveň je silným zdrojem rušení, takže jeho použití v rádiových přijímačích je nežádoucí.

Pokud z nějakého důvodu, například pro potřebu použití maticových indikátorů, musíte použít dynamickou indikaci, pak musíte přijmout všechna opatření k potlačení rušení.

Jako opatření k potlačení rušení od dynamické indikace lze uvést stínění jednotky, propojovací kabel a desky. Použití minimální délky propojovacích vodičů, použití výkonových filtrů. Při stínění bloku může být nutné odstínit samotné indikátory. V tomto případě se obvykle používá kovová síť. Tato mřížka může současně zvýšit kontrast zobrazených znaků.

Literatura:

Spolu s článkem "Dynamická indikace" čte:

Indikátory jsou navrženy tak, aby zobrazovaly různé typy informací o osobě. Nejjednodušší druh informací je...
http://website/digital/Indic.php

Indikátory vybití se používají jak k indikaci bitových informací, tak k zobrazení desetinných informací. Při konstrukci desetinných indikátorů katody...
http://website/digital/GazIndic/

V současné době se LED diody používají téměř všude k zobrazení binárních informací. To je způsobeno...
http://webové stránky/digital/LED.php

Principy činnosti indikátorů z tekutých krystalů ... Způsoby činnosti indikátorů z tekutých krystalů ... Tvorba barevného obrazu ...
http://website/digital/LCD.php

DAby se na indikátoru zobrazilo vícemístné číslo, musíte s ním nejprve provést záludnou manipulaci, která spočívá v rozbití čísla na jeho součásti. Jako příklad uvedu zobrazení čísla 1234 na quad sedmisegmentovém ukazateli se společnou anodou.


Chcete-li zobrazit čtyřmístné číslo, musíte vytvořit jednu společnou proměnnou, ve které bude ležet číslo, které chcete zobrazit (proměnná W), čtyři proměnné, které budou ukládat data pro každý znak (N) a další čtyři proměnné pro přechodné transformace (M), abyste se nedotkli hlavní proměnné. Proměnná musí odpovídat hodnotě, která v ní bude uložena.já Tedy pro proměnnouWtyp bude stačitcelé číslo , protože proměnná tohoto typu je schopna xpAnimovat hodnoty od -32768 do +32767 (neboslovo pokud neplánujete používat záporná čísla). V proměnnýchNbudou ležet čísla od 0 do 9, takže postačí použít proměnnou typubyte
. A v proměnnýchM budestejné hodnoty jako v proměnnéW, takže nastavíme typ celé číslo .

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


Po deklaraci proměnných nastavíme porty pro výstupkterý bude použit pro připojení indikátoru:

DDRC = &B11111111
DDRD = &B11111111


DDRC=&B 00001111 a DDRD=&B 01111111 (čtyři první větve portu Cpro anody a šest prvních portů D dílčí segmenty).

Poté přiřaďte k proměnné W hodnota, kterou budeme zobrazovat na indikátoru:

W=1234

"Arial","sans serif""> V hlavní smyčce programu přiřadíme proměnným M hodnotu proměnnéW, dělám toto:

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


"Arial","sans serif""> To není paranoia)), děje se tak s cílem, aby ve všech proměnných M bylo stejné číslo, protože během operace přiřazení může snadno vniknout přerušení (pokud nějaké existuje a není zakázáno), v jehož handleru proměnnáW může změnit. A pokud by zadání vypadalo takto: М1= W, M2= W, M3= W, M4= W v proměnných M bude ležet různé významy což povede k nepořádku ve čteních.

Po zadání proměnné hodnoty začít pracovat s
každý z nich se převede takovým způsobem, že na proměnnou N dostal hodnotu, která bude
zobrazeno na indikátoru: v proměnné
N 1 by měla být "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

břišní svaly – funkce, která vrací celé číslo proměnné N 1 zasáhla jednotku, což bylo skutečně požadováno.

Chcete-li přiřadit dvojku proměnné N 2 operace bude trochu složitější:

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""> Chcete-li začít s funkcíMod vracíme první tři
číslice čísla (zbytek dělení 1000) a pak je vše jako v prvním případě.

S posledními dvěma číslicemi téměř to samé:

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

M4 = M4 Mod 10
N4= Abs (m4)


Nyní naše proměnné obsahují hodnoty, které chceme zobrazit, je čas, aby mikrokontrolér vykopl nohy a zobrazil tyto hodnoty na indikátoru, proto nazýváme podprogram pro zpracování zobrazení:

"Arial","sans serif"">

Gosub Led

"Arial","sans serif""> Procesor přejde na podprogram označenýVedený:

Vedený:

Portc = &B00001000

"Arial","sans serif""> Zde sloužíme na vysoké úrovniPORTC .3 jsme k této noze připojili anodu první kategorie. Poté zvolíme, které segmenty rozsvítíme, abychom zobrazili hodnotu první proměnné. Je jednou z nás, takže nula bude na nohou Portd .1 a Portd .2, což odpovídá segmentům Indikátor B a C.

Vyberte případ N1









Konec Vyberte
Čeká 5

"Arial","sans serif""> Po rozsvícení potřebných segmentů počkáme 5 ms a přistoupíme k zobrazení následujících čísel:

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

Čeká 5

Portc = &B00000010

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

Čeká 5

Portc = &B00000001

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

Čeká 5

"Arial","sans serif""> Po zobrazení informací na indikátoru se musíte vrátit do hlavní programové smyčky, kde je potřeba smyčku dokončit a označit konec programu.

"Arial","sans serif""> Zde je to, co nakonec dostaneme:

"Arial","sans serif"">

"Arial","sans serif""> Kvůli malému zpoždění nebude přepínání pro lidské oko viditelné a uvidíme celé číslo 1234.

Níže si můžete stáhnout zdrojový kód a projekt v Proteus:"Arial","sans serif"">