Ovládanie (nielen) 7-mi segmentového displeja pomocou 74HC595
Náš čtenář, Ing. Miroslav Tesař, nám poslal článek o ovládání sedmisegmentových displejů pomocí obvodu 74HC595. Děkujeme.
Často sa v schémach na ovládanie 7-mi segmentových displejov používa buď priame prepojenie segmentov s Arduinom, alebo dynamické zobrazovanie displejov pomocou tranzistorov.
V prvom prípade priameho prepojenia Arduina so segmentami potrebujeme na každý displej 7 či 8 výstupov (prvé dva obrázky) . Tento variant spotrebováva veľa digitálnych výstupov, čo predurčuje na realizáciu projektu minimálne Arduino UNO. Prakticky je nemožné ovládať viacmiestny 7-mi segmentový displej pomocou tohto zapojenia.
Určité vylepšenie sa ponúka v dynamickom riadení viacmiestneho 7-mi segmentového displeja. V tomto prípade potrebujeme 8 spoločných výstupov pre všetky segmenty displeja a po jednom riadiacom výstupu na každú pozíciu displeja. Pri viac miestom displeji a nízkej frekvencii zobrazovania pozícií môže dochádzať k stroboskopickému efektu, kedy je možné vidieť ako jednotlivé displeje blikajú. Horšie však je, že na zobrazenie informácie spotrebuje Arduino veľa strojového času. Ako náhle program vykonáva inú činnosť, prejaví sa to zlým zobrazením číslic.
O to horšie by bolo ovládanie napr. maticového displeja.
Podstatne lepšie riešenie riadenia výstupov pre ovládanie LED, 7-mi či viac segmentových displejov je použitie obvodu 74HC595. Ide o 8-bitový posuvný register s paralelným výstupom. Funkcia 74HC595 je popísaná v datasheetu a netreba ju v tomto článku rozoberať.
Vstup SHCP je taktovací, ktorý posúva bity prichádzajúci na vstup DS naprieč sériovým posuvným registrom, alebo registrami. Pomocou výstupu Q7S, ktorý pripájame na vstup DS ďalšieho obvodu 74HC595 zaistíme, že sériové dáta potečú cez všetky pripojené posuvné registre. Z uvedeného vyplýva, že prvý vyslaný bit sa po ukončení prenosu dostane na 8-mi bit posledného posuvného registra (ako keď tečie voda v rúre). Tento posun sa deje „na pozadí“ a nenarušuje stav paralelného výstupného registra s výstupmi Q0..Q7 – nedochádza k rušivému blikaniu displeja. Informácia sa dostane na výstup obvodu iba v prípade, že táto bude prepísaná na výstup pomocou vstupu STCP. Prepísanie sa deje naraz pre všetky obvody 75HC595. Vstup OE môže poslúžiť pre prípad, kedy chceme výstupy Q0..Q7 odpojiť od displeja. Ak túto možnosť nepotrebujeme, ušetríme jeden výstupný pin Arduina a na vstup OE privedieme mínus pól napájania. Vstup MR resetuje posuvný register (v našom prípade nepoužitý a pripojený na kladný pól napájania).
Pri použití viac LED diód (záťaže) na každom výstupe je vhodné použiť budič ULN2803. Obvod ULN2803 pracuje na výstupoch s napätím až 50V a každý výstup je možné zaťažiť prúdom až 500mA. V takom prípade však odporúčam použiť chladič. Treba ešte podotknúť, že ak použijete ULN2803, na jeho výstupe je inverzné napätia oproti výstupu z 74HC595. Taktiež výstupné LED diódy zapájame tak, že majú spoločnú anódu. Schéma zapojenia je na obrázku.
Ako je vidno na obrázku, na ovládanie n- zobrazovacích obvodov potrebujeme štyri, prípadne iba tri výstupné piny Arduina.
Programové riešenie
/******************************************************* * PIN - KONSTANTY PRE 74HC595 *******************************************************/ #define clockPin 17 // Vyber vhodnych pinou je na #define latchPin 16 // riesitelovi #define oePin 15 // #define dataPin 14 // #define dlzkaFronty 14 // Celkovy pocet prenasanych byte /******************************************************* * STRUKTURA FRONTY PRE 7-SEGMENTY *******************************************************/ union display_Struct1 { struct { byte Displ01; // 1. 7-segment byte Displ02; // 2. 7-segment byte Displ03; // 3. 7-segment byte Displ04; // 4. 7-segment byte Displ05; // 5. 7-segment byte Displ06; // 6. 7-segment byte Displ07; // 7. 7-segment byte Displ08; // 8. 7-segment byte Displ09; // 9. 7-segment byte Displ10; // 10. 7-segment byte Displ11; // 11. 7-segment byte Displ12; // 12. 7-segment byte Displ13; // 13. 7-segment byte Displ14; // 14. 7-segment }; byte Fronta[dlzkaFronty]; }; /******************************************************* * PREMENNE *******************************************************/ byte Export = 0;
Union štruktúra má tú vlastnosť, že Displ01..Displ14 obsadzuje ten istý pamäťový priestor ako pole Fronta (počet byte musí zodpovedať dĺžke poľa Fronta). Takže s výhodou zapíšeme informáciu pre každú pozíciu displeja a Fronta nám poslúži pre výstup do posuvného registra. Treba však rátať s tým, že (v našom príkladu) začína Fronta s pamäťovým priestorom vymedzeným pre Displ14 a končí Displ01.
Ak potrebujeme na displejoch zobraziť aj iné údaje (napr. ich pomocou prepínača zobrazovať bez toho, aby sa prepísali pôvodné dáta v štruktúre), môžeme takých štruktúr vytvoriť viac. Len dávajte pozor, aby bola dĺžka fronty stále rovnaká.
V prípade, že použijeme viac štruktúr, deklarujeme premennú, ktorá určí tú štruktúru, ktorá sa odošle do displejov.
/******************************************************* * INSTANCIE *******************************************************/ union display_Struct1 display1; // union display_Struct2 display2; // Pripad, kedy pouzijeme // union display_Struct3 display3; // dalsie struktury /******************************************************* * SAVE FRONTA * ----------------------------------------------------- * Fyzicke odoslanie dat do obvodov 74HCT595 * Parameter *pole ziskava adresu prvej zlozky Fronta * a pomocou shiftout posiela data z adries Fronta *******************************************************/
Pre vysielanie dát na obvody 74HC595 použijeme procedúru:
void saveFronta(byte *pole) { for (byte i=0;i<dlzkaFronty;i++) { shiftOut(dataPin,clockPin,LSBFIRST,*(pole+i)); } digitalWrite(latchPin,HIGH); // Prepis do displejov po digitalWrite(latchPin,LOW ); // zapisu celej fronty }
A to je všetko! Uvedená procedúra má výhodu, že môže posielať dáta aj z iných štruktúr. Stačí len v daných procedúrach zapísať dáta do štruktúry union a nastaviť premennú Export.
V prípade, že máme len jednu štruktúru union, v hlavnom programe vytvoríme podmienku, za ktorú sa má uskutočniť zápis do posuvných registrov:
void loop(){ // variant s jednou strukturou union if (Export == 1){ // pripadne pouzijeme typ bool saveFronta(&display1.Fronta[0]); Export = 0; } }
V prípade, že máme viac štruktúr union, upravíme hlavný program pre tento variant:
void loop(){ // variant s viacerymi strukturami union switch (Export) { case 1: saveFronta(&display1.Fronta[0]); break; case 2: saveFronta(&display2.Fronta[0]); break; case 3: saveFronta(&display3.Fronta[0]); break; } Export = 0; }
K aktualizácii displejov príde len vtedy, keď zapíšeme príslušné číslo do premennej Export. Tým šetríme strojový čas Arduina, lebo dáta sa odošlú iba raz za danú udalosť. Celý kód zde.
Riešenie DPS
V DPS som použil smd súčastky. Upozorňujem na to, že keby ste privádzali signál DS, SHCP a STCP pomocou vodičov (Arduino by bolo mimo túto DPS), tak je potrebné vodiče tieniť. Vyhnete sa tým rušeniu a zlým dátam odosielaným do posuvných registrov. Na DPS je dobré si všimnúť, že napájanie ULN2803 je z oboch strán, aby sa predišlo prúdovému preťaženiu vodivej cesty pri veľkom odbere. Prívod napájania pre 74HC595 a Arduino je tiež riešený osobitne, aby prúdové nárazy neovplyvnili činnosť týchto obvodov. Ďalej si všimnite, že na funkciu 14-miestneho displeja postačí najlacnejší variant s Arduino NANO. Samozrejme že Arduino NANO zvládne aj oveľa väčšiu frontu.
Schéma ve formátu lay6 – zde.
Autor: Ing. Miroslav Tesař, tesar@imt.eu.sk
Děkujeme za zajímavý článek a přejeme spoustu úspěchů.
Máte zajímavý projekt, se kterým se chcete pochlubit? Přečtěte si tento článek a dejte nám o něm vědět.
- Sledovač slunce s Arduinem - 23.3.2022
- Programovatelný kytarový pedál s Arduinem - 26.2.2020
- Arduino infračervený teploměr vytištěný na 3D tiskárně - 11.2.2020
One Comment on “Ovládanie (nielen) 7-mi segmentového displeja pomocou 74HC595”
Napsat komentář
Pro přidávání komentářů se musíte nejdříve přihlásit.
poprad
5.4.2017 at 22:07Pozorný čitateľ si isto všimol. že v zdrojovom textu chýba časť „setup“. Ak je niekto úplný začiatočník, tak túto časť radšej doplním:
void setup() {
pinMode (clockPin, OUTPUT);
pinMode (latchPin, OUTPUT);
pinMode (oePin, OUTPUT);
pinMode (dataPin, OUTPUT);
}