namai - Interneto sąranka
Dinaminis septynių segmentų ekranas AVR. Trumpa teorinė informacija

Baterijomis maitinamoje įrangoje paprastai manoma, kad geriau naudoti LCD indikatorius nei šviesos diodų (LED) indikatorius, nes pastarieji sunaudoja daug srovės. Šis postulatas man atrodo visiškai neaiškus dėl šių priežasčių: 1) šiuolaikiniuose LCD indikatoriuose yra apšvietimas, kuris suvartoja iki 100 mA; 2) jie yra gana trapūs ir bijo tiesioginių saulės spindulių; 3) šiuolaikiniai LED indikatoriai (ypač superRED ir ultraRED) turi pakankamą ryškumą net esant 1 mA srovei per juos, o greitai reguliuojant ryškumą priklausomai nuo apšvietimo sąlygų, vidutinė 4 skaitmenų indikatoriaus srovės suvartojimas yra ne didesnis kaip 30 mA net lauke, o tai yra mažiau nei sunaudoja LCD foninis apšvietimas.

Nepaisant daugybės dinaminių ekrano grandinių internete, PIC16 nemačiau grandinės su programinės įrangos ryškumo valdymu. Šis straipsnis parodo mano nuolankų požiūrį į tokios užduoties įgyvendinimą. Jis daugiausia skirtas radijo mėgėjams, žengiantiems pirmuosius žingsnius nuo dizaino kartojimo iki savaiminio programavimo mikrovaldiklių.

Straipsnyje aptariama, kaip valdyti LED matricą su vidutinio nuotolio PIC mikrovaldikliu naudojant pertraukimus iš laikmačių TMR0 ir TMR2. Laikmatis TMR2 naudojamas PWM valdyti vidutinę srovę per įjungtus segmentus. Darbo organizavimo algoritmas yra toks:

1. Inicializavimas. Mikrovaldiklio prievadus konfigūruojame pagal indikatoriaus prijungimo schemą. 1 ir 2 laikmačiams įjungtas vidinio laikrodžio režimas su išankstiniu skalės reguliatoriumi, lygiu 16. Periferiniai pertraukimai įjungti.

2. Sukuriame simbolių generatoriaus lentelę, kad indikatoriuje būtų rodomi skaičiai ir kai kurios (dažniausiai lotyniškos) raidės ir simboliai.

3. Mes rezervuojame du keturių bitų kintamuosius. Viename įvedame nuoseklų skaitmeninį kodą (skaičiams - tik skaičių) ženklo, reikalingo išvesti, pagal lentelę iš 2 punkto. Konvertuotos vertės iš lentelės perkeliamos į kitą kintamąjį, kad būtų rodomas nuolatinis indikatorius.

4. Pertraukime iš TMR0 simbolių bitai rodomi nuosekliai pagal lentelę. Prieš keičiant skaičius, indikatorius užgęsta. Kiekvienas pertraukimas rodo vieną skaitmenį. Po to iš naujo nustatomas TMR2 laikmatis, iš naujo nustatoma pertraukimo vėliavėlė iš TMR2 ir įjungiami pertraukimai iš jo.

5. TMR2 pertraukimo metu indikatorius užgęsta ir TMR2 pertraukimas yra išjungtas.

6. Pagrindinėje programoje pertraukimo laikotarpis nuo TMR2, taigi ir indikatoriaus įjungimo laikas, koreguojamas į PR2 registrą įvedant skaičius nuo 7 iki 255 dešimtainiu skaičiumi pagal formulę X(n+1)=2* X(n)+1. Dėl to gaunamos šešios ryškumo gradacijos, kurių skirtumas yra 2 kartus. Kai PR2 = 255, trukmė yra maksimali (4 ms iš 4 ms), kai PR2 = 7, trukmė yra maždaug 0,25 ms.

Norėdami parodyti šį valdymo principą, žemiau yra nebrangaus PIC16F628A grandinė ir testavimo programa surinkimo kalba, kurios indikatoriuje rodomas žodis „testas“. Paspaudus mygtuką, indikatoriuje rodomas ryškumas (paprastai skaičiai nuo 0 iki 5). Vėlesniais paspaudimais ryškumas keičiasi ratu ir tai iškart matoma indikatoriuje. Iš karto noriu perspėti pradedančiuosius: modeliuojant grandinę tokiu treniruokliu kaip „Proteus“ neleis matyti ryškumo pokyčio dėl šios programos („Proteus“) ypatybių. Bandymui ir eksperimentams skirtos grandinės prototipas turės būti surinktas techninėje įrangoje. Tačiau norint stebėti tikrąją dinaminio ekrano struktūrą (išskyrus ryškumo pokyčius), pridedamas Proteus modelis.

Grandinės suvartojimas esant minimaliam ryškumui yra mažesnis nei 4 mA, didžiausias - apie 80 mA.

Archyve yra bandomoji programa MPASM assembler.

Norint supaprastinti grandinę ir atlaisvinti „kojas“ įvairiems veiksmams, naudojama konfigūracija su vidiniu generatoriumi ir vidiniu atstatymu. Tuo pačiu metu tiems, kurie naudoja naminį programuotoją, negalėdami siųsti MCLR signalo prieš Upp, gali kilti problemų dėl tolesnio patikrinimo, skaitymo ir ištrynimo. Tiems, kurie nepasitiki savo programuotoju, taip pat jei reikalingas didelis osciliatoriaus stabilumas, galite įdiegti 4 MHz kvarcą pagal standartinę schemą, pasirinkę „OSC_XT“ konfigūraciją. Jei galutinei grandinei reikalingi pertraukimai iš INT0 (RB0) kaiščio, kablelį galima valdyti per RA4 kaištį; indikatoriui su OA indikatorius prijungiamas tiesiai prie šio kaiščio, nepaisant to, kad jis yra atviras. Atlaisvintas kaištis RB0 gali būti naudojamas pagal paskirtį. Programoje, pertraukime iš TMR0, šiuo atveju kodas pridedamas po „movwf PORTB“:

Andlw b"00000001" bsf PORTA,4 nuslopinkite kablelį btfsc STATUS,Z atsižvelkite į tai, kad W yra atvirkštinė reikšmė. bcf PORTA,4 jei 0 bitas = 0, šviesus kablelis

Maži paaiškinimai apie programą:

Išvesties numeris dedamas į kintamuosius OUT_ - OUT+3 pagal skaitmenį, o iš jo out__ paprogramėje po konvertavimo į OUT_LED. Žinoma, galite apsieiti be kintamojo OUT_ ir rašyti visur, kad būtų išvestas:

Movlw X skambutis Table_s movwf OUT_LED

Tačiau pradine forma viskas daug paprasčiau ir aiškiau (įdėjau į OUT_ ir pamiršau), o taip pat su daugybe išėjimų iš skirtingų programos vietų gaunamas kodo taupymas (4 žodžiai 1 išvestis) - manau, kad tai yra gera kompensacija už papildomus 4 baitus RAM.

Tas pats pasakytina ir apie kablelio išvedimą per comma_ kintamąjį.

Lentelės paprogramėje Table_s buvo imtasi priemonių, kad jos tinkamai veiktų, kai jos yra bet kurioje programos atminties vietoje be apribojimų 256 baitų blokų sankirtai.

Kintamasis pause_ TMR0 pertraukime naudojamas nustatyti laiko intervalus iki 4 ms.

Visa kita, manau, aišku iš algoritmo ir komentarų.

P.S. Dėl 2 ar 3 skaitmenų programoje reikia atlikti minimalius pakeitimus, kurie, manau, yra įmanomi net pradedantiesiems. Norint valdyti indikatorių su skaitmenų skaičiumi nuo 5 iki 8, reikia naudoti valdiklį su daugybe kaiščių arba valdyti skaitmenis, kad būtų naudojamas 3 x 8 dekoderis.

Pirmuoju atveju programos pakeitimai taip pat minimalūs (naudojant kitą prievadą vietoj A prievado ir pan.). Jei naudojamas dekoderis, programa dėl TMR0 pertraukimo pasikeis gana rimtai.

Radioelementų sąrašas

Paskyrimas Tipas Denominacija Kiekis PastabaParduotuvėMano užrašų knygelė
U1 MK PIC 8 bitų

PIC16F628A

1 Į užrašų knygelę
H1 Rodiklis4x7 FIQ-3641A1 Į užrašų knygelę
Q1-Q4 Bipolinis tranzistorius

KT361E

4 Į užrašų knygelę
C3 Kondensatorius22 nF1 Į užrašų knygelę
R1-R7, R14 Rezistorius

150 omų

8 Į užrašų knygelę
R8 Rezistorius

Tęsdami pamoką, pažvelkime į dinaminį ekraną. Jei atidžiai išstudijavote statinę indikaciją, žinote, kad segmento indikatorius yra šviesos diodų rinkinys. Norint prijungti indikatorių, reikia 7 mikrovaldiklio kaiščių. Bet staiga mums reikėjo naudoti kelis rodiklius, pavyzdžiui, 2, 3, 4...

Tada mums reikės 14, 21, 28 kojų, o kojelių neužtenka... Čia mums į pagalbą ateina dinaminis ekranas. Pagrindinis dinaminio ekrano tikslas – sumažinti naudojamų mikrovaldiklio kontaktų skaičių. Atkreipkite dėmesį, kad diagramoje yra 9, o ne 14 kojų. Visos valdymo kojos yra sujungtos lygiagrečiai.

Bendrąja prasme šis dizainas veikia taip: pirma, pirmojo numerio konfigūracija išvedama į bendrą magistralę ir įjungiame PB1. Užsidega pirmasis indikatorius su norimu numeriu. Tada išjungiame, išvedame antrojo numerio konfigūraciją į duomenų magistralę, užsidegame antrąjį indikatorių ir išjungiame.

Išsamiau. Pirmą akimirką viskas išjungiama PORTB=0x00; PORTD=0xFF; kadangi grandinė yra su bendru „+“ anodu. Tada pirmojo numerio konfigūracija, pavyzdžiui, „0“, siunčiama į PORTD. Iš statinio ekrano prisimename:

0 atvejis: (PORTD= 0xC0; pertrauka;)

0 atvejis: ( PORTD = 0xC0; pertrauka; )

Bet atkreipkite dėmesį, kad „+“ yra prijungtas prie PORTB.1, t.y. norint apšviesti segmentą reikia įjungti PORTB.1=1 koją;

Antrą akimirką vėl viską išjungiame, išsiunčiame antrojo numerio konfigūraciją ir įjungiame, šį kartą, antrąjį indikatorių. Toliau kartojame.

Esant aukštiems dažniams, žmogaus akis nepajėgia atskirti šių jungiklių, o indikatorius nuolat dega. Nerekomenduojama naudoti 50 Hz kartotinių dažnių. Savo bandymo projekte naudojau 120 Hz. Laikmatis nustatytas 1 MHz dažniu. Kodas apdorojamas per 1 laikmačio pertraukimą. Pertraukimas iškviečiamas 240 kartų per sekundę, nes yra du rodikliai, todėl į palyginimo registrą įstumiame 1000 000/240=4166 arba 0x1046. Nebuvo įmanoma suporuoti Proteus su dinaminiu indikatoriumi, tačiau jis iškart veikė aparatinėje įrangoje.

Pastaba!!! Jungiant indikatorių, rekomenduojama prie kiekvieno segmento pritvirtinti srovę ribojantį rezistorių, o ne vieną bendrą. Taip pat rekomenduoju bendrą indikatoriaus laidą prijungti per tranzistorių, kitaip galite nudeginti koją.

Grandinei su bendru anodu

Bendrai katodo grandinei

Kaip bandomąją programinę įrangą naudojau laikmatį iš ankstesnio projekto.

Vaizdo įrašas apie programinės įrangos veikimą

Rodikliai dažniausiai yra išdėstyti vietose, kuriose patogu peržiūrėti juose rodomą informaciją. Likusi skaitmeninės grandinės dalis gali būti kitose spausdintinėse plokštėse. Didėjant indikatorių skaičiui, didėja laidininkų skaičius tarp indikatoriaus plokštės ir skaitmeninės plokštės. Tai sukelia tam tikrų nepatogumų kuriant įrangos dizainą ir eksploatavimą. Ta pati priežastis lemia jo sąnaudų padidėjimą.

Jungiamųjų laidininkų skaičių galima sumažinti, kai indikatoriai veikia impulsiniu režimu. Žmogaus akis turi inerciją, ir jei priversite indikatorius pakankamai dideliu greičiu rodyti informaciją po vieną, tada žmogui atrodys, kad visi indikatoriai nuolat rodo savo informaciją. Dėl to galima pakaitomis perduoti rodomą informaciją tais pačiais laidininkais. Paprastai pakanka 50 Hz atnaujinimo dažnio, tačiau geriau šį dažnį padidinti iki 100 Hz.

Pažiūrėkime į septynių segmentų LED indikatorių blokinę schemą, parodytą 1 paveiksle. Ši grandinė gali pateikti dinaminę išėjimo skaitmeninės informacijos indikaciją.


1 pav. Dinaminės indikacijos blokinė schema

1 paveiksle pavaizduotoje diagramoje rodomi keturi skaitmeniniai skaitmenys. Kiekvienas bitas trumpam prijungiamas prie savo jungiklio įvesties. Generatorius naudojamas indikatorių informacijos atnaujinimo greičiui nustatyti. Dvejetainis skaitiklis nuosekliai generuoja keturias grandinės būsenas ir per klavišus tiekia alternatyvų maitinimą septynių segmentų indikatoriams.

Dėl to, kai jungiklis pateikia dvejetainį dešimtainį kodą iš įvesties A į septynių segmentų dekoderio įvestis, šis kodas rodomas HL1 indikatoriuje. Kai jungiklis tiekia dvejetainį dešimtainį kodą iš įvesties B į septynių segmentų dekoderio įvestis, šis kodas ciklo metu rodomas HL2 indikatoriuje ir pan.

Informacijos atnaujinimo greitis nagrinėjamoje schemoje bus keturis kartus mažesnis už generatoriaus dažnį. Tai yra, norint gauti 100 Hz indikatoriaus mirgėjimo dažnį, reikalingas 400 Hz generatoriaus dažnis.

Kiek kartų dėl to sumažinome jungiamųjų laidininkų skaičių? Tai priklauso nuo to, kur nubrėžiame grandinės skerspjūvį. Jei indikacijų lentoje paliksime tik indikatorius, tai jų veikimui reikės 7 informacinių signalų segmentams ir keturių perjungimo signalų. Iš viso yra 11 laidininkų. Statinėje ekrano grandinėje mums reikės 7 × 4 = 28 laidininkų. Kaip matote, laimėjimai yra akivaizdūs. Įdiegus 8 bitų ekraną, pelnas bus dar didesnis.

Dar didesnis pelnas bus, jei grandinės skerspjūvis bus nubrėžtas išilgai indikatorių įvesties. Šiuo atveju keturių skaitmenų ekrano blokui reikės tik šešių signalų laidų ir dviejų grandinės maitinimo laidų. Tačiau toks dinaminio ekrano grandinės skerspjūvio taškas naudojamas labai retai.

Dabar apskaičiuokime srovę, tekančią per kiekvieną LED segmentą, kai jis užsidega. Norėdami tai padaryti, naudosime lygiavertę srovės srauto grandinę per vieną iš indikatoriaus segmentų. Ši diagrama parodyta 2 paveiksle.


Kaip minėta anksčiau, normaliam šviesos diodo veikimui reikalinga 3–10 mA srovė. Nustatykime minimalią LED srovę iki 3 mA. Tačiau veikiant impulsiniu režimu indikatoriaus ryškumas sumažėja N kartų, kur koeficientas N yra lygus šiam indikatoriui tiekiamų srovės impulsų darbo ciklui.

Jei ketiname išlaikyti tą patį švytėjimo ryškumą, turime N kartų padidinti impulsinės srovės, tekančios per segmentą, dydį. Aštuonių skaitmenų rodiklio koeficientas N yra lygus aštuoniems. Iš pradžių parinkkime statinę srovę per šviesos diodą, lygią 3 mA. Tada, norint išlaikyti tą patį šviesos diodo ryškumą aštuonių skaitmenų indikatoriuje, reikės impulsinės srovės:

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

Tik kai kurios skaitmeninių mikroschemų serijos vargu ar gali užtikrinti tokią srovę. Daugeliui mikroschemų serijų reikės stiprintuvų, pagamintų ant tranzistorių jungiklių.

Dabar nustatykime srovę, kuri tekės per jungiklį, kuris perjungia maitinimą į atskirus aštuonių bitų ekrano bloko bitus. Kaip matyti iš diagramos, parodytos 2 paveiksle, srovė iš bet kurio indikatoriaus segmento gali tekėti per raktą. Kai rodomas skaičius 8, visi septyni indikatoriaus segmentai turės užsidegti, o tai reiškia, kad šiuo metu mygtuku tekančią impulsinę srovę galima nustatyti taip:

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

Kaip tau patinka ši srovė?! Mėgėjiškose radijo grandinėse dažnai susiduriu su sprendimais, kai perjungimo srovė imama tiesiai iš dekoderio išvesties, kuri negali sukurti didesnės nei 20 mA srovės, ir užduodu sau klausimą - kur ieškoti tokio indikatoriaus? Visiškoje tamsoje? Rezultatas yra „naktinio matymo prietaisas“, tai yra prietaisas, kurio rodmenys matomi tik visiškoje tamsoje.

Dabar pažvelkime į gauto ekrano bloko schemą. Tai parodyta 3 paveiksle.



3 pav. Dinaminio ekrano bloko schema

Dabar, kai gavome dinaminę ekrano grandinę, galime aptarti jos pranašumus ir trūkumus. Neabejotinas dinaminio ekrano pranašumas yra mažas jungiamųjų laidų skaičius, todėl kai kuriais atvejais jis yra būtinas, pavyzdžiui, dirbant su matricos indikatoriais.

Trūkumas yra didelių impulsų srovių buvimas, o kadangi bet kuris laidininkas yra antena, dinaminė indikacija yra galingas trikdžių šaltinis. Kitas trukdžių šaltinis yra maitinimo šaltinis.

Atkreipkite dėmesį, kad perjungimo impulsų priekinės briaunos yra labai trumpos, todėl jų harmoniniai komponentai apima radijo dažnių diapazoną iki ultratrumpųjų bangų.

Taigi dinaminės indikacijos naudojimas leidžia sumažinti jungiamųjų laidų skaičių tarp skaitmeninio įrenginio ir indikatoriaus, tačiau kartu tai yra galingas trikdžių šaltinis, todėl jo naudojimas radijo imtuvuose yra nepageidautinas.

Jei dėl kokių nors priežasčių, pavyzdžiui, dėl poreikio naudoti matricinius indikatorius, reikia naudoti dinaminę indikaciją, tuomet reikia imtis visų priemonių trukdžiams slopinti.

Priemonės, skirtos dinaminės indikacijos trikdžiams slopinti, apima įrenginio, jungiamojo kabelio ir plokščių ekranavimą. Naudojant minimalų jungiamųjų laidų ilgį, naudojant maitinimo filtrus. Ekranuojant bloką, gali prireikti ekranuoti pačius indikatorius. Šiuo atveju dažniausiai naudojamas metalinis tinklelis. Šis tinklelis vienu metu gali padidinti rodomų simbolių kontrastą.

Literatūra:

Kartu su straipsniu „Dinaminis ekranas“ skaitykite:

Rodikliai yra skirti parodyti įvairių tipų informaciją asmeniui. Paprasčiausias informacijos tipas yra...
http://site/digital/Indic.php

Dujų išleidimo indikatoriai naudojami tiek bitų informacijai nurodyti, tiek dešimtainei informacijai rodyti. Konstruojant dešimtainius rodiklius katodo...
http://site/digital/GazIndic/

Šiais laikais šviesos diodai beveik visur naudojami dvejetainei informacijai rodyti. Tai yra dėl to...
http://site/digital/LED.php

Skystųjų kristalų indikatorių veikimo principai... Skystųjų kristalų indikatorių darbo režimai... Spalvoto vaizdo formavimas...
http://site/digital/LCD.php

Dinaminis ekranas yra viena iš problemų, su kuriomis susiduria pradedantieji mikrovaldiklių programuotojai. Apie tai daug kalbėta, bet nusprendžiau sukurti atsargines žinias pateikdamas paveikslėlius ir šaltinio kodo pavyzdžius C, kad būtų lengviau įsisavinti šį rodymo metodą.

1 Pagrindai arba įvadas

Visų pirma, apibrėžkime terminiją, kurią naudosime visame straipsnyje.

Jei jums reikia valdyti ekraną, susidedantį iš vieno septynių segmentų pažinimo, tai nesukelia jokių problemų – tai gali būti laikoma 8 nepriklausomais šviesos diodais. Jei reikia rodyti daugiau informacijos nei vienas simbolis, prasideda problemos: 2 pažįstamos vietos sudaro 16 šviesos diodų, trys - 24 ir tt, tai yra, trijų skaitmenų ekranui gali tiesiog neužtekti mikrovaldiklio kaiščių, paminėti 6 ar daugiau skaitmenų ekranus ir ypač matricinius indikatorius.

Paprastumo dėlei sutikime, kad visi mūsų rodikliai turi bendrą katodą. Problemos sprendimas yra gana paprastas: sujunkite visų indikatorių segmentų gnybtus vienas su kitu. Dabar, jei norite išvesti informaciją į pirmąją pažįstamą vietą, turėtumėte taikyti reikiamus lygius segmentų linijoms ir prijungti bendrą pirmojo indikatoriaus išvestį prie bendro grandinės laido. Žinoma, aukšti lygiai turi būti bendruose visų kitų rodiklių katoduose. Akivaizdu, kad užsidegs būtini pirmojo indikatoriaus segmentai. Išvesties į antrą, trečią ir kt. rodikliai turėtų daryti tą patį, t.y. Vienam iš bendrų katodų pritaikę loginį nulį, pasirenkame dabartinį rodomą skaitmenį, o segmentų linijų būsena nustato matomą simbolį.

Kad visas ekranas būtų suvokiamas kaip nuolat šviečiantis, skaitmenis reikėtų perjungti greitai – daugiau nei 25 kartus per sekundę. Kaip matote, visų išėjimų lygiai (kurie, beje, tapo ženkliai mažesni nei taikant įprastą požiūrį) nuolat kinta, t.y. turi ne statinius, o dinaminius lygius, todėl indikacijos metodo pavadinimas – dinaminis.

Dinaminis ekrano vaizdas

2 Techninės įrangos diegimo tipai

2.1 Plokščios matricos

Jei abstrahuosime nuo septynių segmentų indikatorių, mūsų ekranas gali būti pavaizduotas kaip atskirų šviesos diodų matrica, kurių anodai yra sujungti į matricos eilutes, o katodai - į stulpelius. Tiesą sakant, būtent taip yra.

Akivaizdu, kad tiekdami reikiamus lygius į mūsų matricos eilutes ir stulpelius, galime apšviesti bet kurį elementarų LED segmentą (dar žinomas kaip pikselis - tai labiau tradicinis terminas, susijęs su matricos ekranais). Atsižvelgiant į tai, kaip tiksliai keičiame eilučių ir stulpelių lygius, galime gauti kelių tipų dinaminį vaizdą:

  • pagal linijas;
  • pagal stulpelius;
  • segmentas po segmento (vienam pikseliui);
  • mišriu būdu.

Ankstesniame skyriuje pažvelgėme į stulpelio parinktį. Eilutės parinktis nuo jos skiriasi tik tuo, kad mūsų matricos eilutės ir stulpeliai yra sukeisti vietomis. Segmentinis metodas reiškia, kad bet kuriuo metu tik vienoje eilutėje ir viename stulpelyje yra šviesos diodui įžiebti reikalingas lygis. Tai yra, bet kuriuo metu gali užsidegti tik vienas visos matricos šviesos diodas (skirtingai nuo ankstesnių parinkčių, kai tuo pačiu metu gali užsidegti visa eilutė arba visas stulpelis). Šis būdas primena televizoriaus skenavimą, kai spindulys apibėga visą ekraną, apšviesdamas fosforą tinkamose vietose. Mišri parinktis, kaip rodo pavadinimas, yra ta, kad vienu metu „aktyvūs“ lygiai gali būti vienu metu keliose eilutėse ir stulpeliuose.

Pirmąsias dvi parinktis labai lengva įgyvendinti, todėl jos plačiai naudojamos. Trečiasis variantas naudojamas rečiau, nes reikalauja didesnio informacijos atnaujinimo greičio eilutėse ir stulpeliuose, o vidutinė srovė per segmentą (t. y. segmento ryškumas) šiuo atveju yra žymiai mažesnė nei kituose. Paskutinis mišrus metodas yra rečiausias, nors jis turi daug teigiamų savybių. Visų pirma, šis metodas reikalauja, kad eilučių ir stulpelių grandinėse būtų naudojami stabilūs srovės šaltiniai, kitaip šviečiančių segmentų ryškumas neišvengiamai priklausys nuo bendro jų skaičiaus. O suskaičiuoti signalų derinius eilutėse ir stulpeliuose nėra labai lengva.

2.2 Daugiamatės matricos

Mūsų svarstytuose pavyzdžiuose daroma prielaida, kad įgyvendinamas vienspalvis ekranas, t.y. susidedantis iš vienos spalvos šviesos diodų. Ką daryti, jei norite gauti daugiaspalvį ekraną, pavyzdžiui, iš RGB šviesos diodų? Galimi du sprendimai.

Pirmasis yra tiesiog padidinti mūsų matricos eilučių (arba stulpelių) skaičių, kiekvieną RGB šviesos diodą traktuojant kaip 3 nepriklausomus atskirus šviesos diodus. Didelis šio metodo trūkumas yra 3 kartus padidėjęs eilučių (arba stulpelių) skaičius. Paprastas pavyzdys nesunkiai parodo, ką tai reiškia praktiškai: naudojant du aštuonių bitų mikrovaldiklių mikrovaldiklius galime turėti vienspalvę 8x8 segmentų matricą arba 4x4 spalvų matricą. Sutikite, kad antruoju atveju praktiškai neįmanoma parodyti nieko suprantamo...

Antrasis būdas yra pereiti nuo „plokščios“ segmentų matricos prie „daugiamatės“. Jei kiekvienos linijos signalas perduodamas per 1x3 multiplekserį, tai RGB šviesos diodų rodymo sistemą galime įsivaizduoti kaip 3 nepriklausomas pradinio matmens matricas: kiekviena matrica susideda iš tos pačios spalvos šviesos diodų, o norimą matricą pasirenkame naudodami multiplekserį. valdymo signalus. Nuotraukoje paaiškinama, kas buvo pasakyta.

Akivaizdu, kad daugiamatės matricos atveju reikalingas ir papildomas valdymo linijų skaičius, tačiau šis skaičius nėra toks didelis: ant tų pačių dviejų valdiklio prievadų galime gauti 7x7 spalvų ekraną!!!

2.3 Matricų matmenų mažinimo būdai

Jei mikrovaldiklio kaiščių skaičius labai ribotas, teks ieškoti būdų, kaip sumažinti savo matricos eilučių ir stulpelių skaičių. Žinoma, stebuklų nebūna ir tokiu atveju teks mokėti be mikrovaldiklio naudojant papildomas mikroschemas. Kaip jau supratote, čia galite naudoti anksčiau aptartą „daugiamatių“ matricų metodą - juk niekas nedraus vietoj RGB šviesos diodų naudoti trigubą vienspalvių šviesos diodų skaičių? Svarbiausia juos tinkamai sutvarkyti...

Taigi, matricos matmenis galime sumažinti naudodami:

  • dekoderiai arba tankintuvai;
  • pamainų registrai.

Su multiplekseriais jau buvome susitikę anksčiau, dekoderis, kaip galite atspėti, iš esmės nesiskiria nuo multiplekserio. Reikėtų tik pridurti, kad naudojant dekoderius/multiplekserius tiek eilutėms, tiek stulpeliams, galima sumažinti matricos matmenį pagal abu matmenis vienu metu, tačiau tokiu atveju gali tekti naudoti tik segmentinį dinaminį vaizdą, su visais savo trūkumais.

„Shift“ registrai gali padėti daug geriau nei iššifruotojai. Apsvarstykite diagramą žemiau esančiame paveikslėlyje.

Nesunku pastebėti, kad bet koks eilučių ir stulpelių skaičius užteks tik padidinti registrų skaičių, o naudojamų mikrovaldiklio valdymo linijų skaičius išliks toks pat! Nedidelis šio požiūrio trūkumas yra tas, kad grandinėje didėjant registrų skaičiui, teks didinti nuoseklaus informacijos išvedimo į juos greitį, o tai ne visada lengva pasiekti. Pavyzdžiui, bendri šeimos mikrovaldikliai AVR, praktiškai neleidžia viršyti 10 megabitų/sek serijinės išvesties greičio. Kita vertus, jei naudosite kitus valdiklius, galinčius greičiau išvesti signalus, gali kilti kitokios eilės problemų: aukšto dažnio laikrodžio signalo sklidimas ilga linija (o esant dideliam registrų skaičiui tai neišvengiamai bus viena). ) vyksta visiškai kitaip nei žemo dažnio, todėl dėl spausdintinės plokštės ir kitų dalykų, kurių šiame straipsnyje nenagrinėsime, reikės specialių priemonių.

3 Programinės įrangos diegimo metodai

Visų minėtų dinaminio rodymo parinkčių programinės įrangos diegimo nesvarstysime – tai nepagrįstai išpūstų straipsnį. Apsiribosime tik trimis populiariausiais pavyzdžiais: plokščia matrica su tiesioginiu eilučių ir stulpelių valdymu, tas pats naudojant dekoderį ir, galiausiai, variantas, kuriame naudojami poslinkių registrai. Visais atvejais ypatingas dėmesys bus skiriamas visiems programinės įrangos diegimo niuansams, tai yra, prie C kodo bus pateikti paaiškinimai tik tais atvejais, kai tai sutaps su autoriaus ketinimu, o ne su jūsų mokymo lygiu. . Tuo užsimenu, kad turėtumėte žinoti C pagrindus be manęs.

Dėl visų pavyzdžių sutiksime, kad mūsų ekranas yra pastatytas ant septynių segmentų indikatorių su bendru katodu.

3.1 Paprasčiausias būdas

Akivaizdu, kad programoje patogiausia būtų turėti tam tikrą masyvą, kurio turinys vienareikšmiškai nulemtų, kuriuose segmentuose, kuriuose yra apšviestos pažįstamos ekrano sritys – savotiškas ekraninės RAM analogas.

Pateikiame šių konstantų apibrėžimą:

#define SCR_SZ 6 /* rodymo pažinčių skaičius */ #define ROWS PORTB /* rodymo „eilučių“ prievadas, t.y. segmento valdymas */ #define COLS PORTD /* „stulpelio“ valdymo prievadas, t.y. bendrieji katodai */

Dabar paskelbkime ekrano masyvą:

Unsigned char SCR;

Pirmiausia darysime prielaidą, kad kiekvienas masyvo elementas atitinka ekrano žinomumą, o kiekvienas šio elemento bitas atitinka tam tikrą indikatoriaus segmentą. Kuris bitas atitinka kurį segmentą – šiuo atveju nesvarbu, kaip ir nesvarbu, kaip šie bitai nustatyti mūsų masyvo baituose, kol kas tik manysime, kad jie jau yra. Paprastumo dėlei taip pat manysime, kad bendrieji katodai yra prijungti prie prievado kaiščių COLS nuosekliai: mažiausiai reikšmingas bitas yra dešinysis indikatorius, tada antrasis, trečiasis ir tt

Kaip padaryti, kad šis masyvas „rodytų“ ekrane? Parašykime tokį kodą:

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

Ar jis atliks reikiamą funkciją? Taip. Bet tai nėra gerai.

Pirmiausia atminkite, kad mes negalime kontroliuoti, kaip greitai atnaujinamas eilučių ir stulpelių turinys. Antra, atkreipkite dėmesį, kad iki to laiko, kai bus išspausdintas naujas masyvo elementas EILUTĖS linijose COLS Senoji prasmė tebėra! Kur tai veda? Be to, sekundės dalį pažinimo srityje bus rodomi gretimos pažinimo srities segmentai, t.y. kai kurie segmentai bus klaidingai apšviesti.

Šio efekto galite išvengti darydami taip: prieš atnaujindami turinį EILUTĖS, visada užgesinkite pažįstamą vietą, kuri buvo ankstesnė. Kad nesivargintumėte nustatydami ankstesnį pažinimą, galite viską užgesinti iš karto. Taigi mūsų kodas yra tokia forma:

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

Prieš atnaujindami segmentų linijų būseną, pridėjome viso ekrano užtemdymą (išsiųsdami bendruosius katodus aukštai, indikatorių išjungsime nepriklausomai nuo to, kas yra ant anodų) ir įvedėme vėlavimą ciklo pabaigoje. Dabar ekranas veiks daug geriau. Bet ar parašėme gerą programą? Deja, ne.

Faktas yra tai, kad nesibaigiantis rodymo ciklas kol tai tiesiog neleis mums nieko daugiau daryti. Kokią turėsime programą, kuri tik indikatoriuje kažką parodys?! Žinoma, viskas nėra 100% blogai, nes ką nors naudingo galima padaryti naudojant pertraukimus... o vietoj delsimo delsimas() galite atlikti kai kuriuos veiksmus... Bet visa tai labai labai kreiva: pertraukimų tvarkytuvėse nepatartina atlikti kažko sudėtingo ir sudėtingo; kita vertus, jei vietoj delsimo padarysite kažką sudėtingo ir sudėtingo, sunku užtikrinti tą patį skaičiavimo laiką, kitaip paaiškės, kad pažįstamos vietos šviečia skirtingą laiką, o tai vizualiai atrodys kaip jų skirtingo ryškumo švytėjimas ar mirgėjimas.

Apskritai ši galimybė gali būti leidžiama tik kaip išimtis, tik kaip mokymo pavyzdys arba tuo atveju (bet vėlgi, tik kaip išimtis!), kai pagrindinė sprendžiama problema yra labai paprasta (tai gali būti pvz. , matavimo naudojimo problema ADCįtampą ir parodykite ją ekrane).

Ką tu turėtum daryti? Atsakymas, kaip visada, paprastas: visi procesai, kurie turi būti atliekami nepastebimai sprendžiant pagrindinę užduotį (o indikacija, žinoma, yra toks procesas), turi būti atliekami naudojant laikmačio pertraukimus.
Pertraukos įvyks griežtai nustatytais intervalais, o tai užtikrins vienodą pažįstamų ženklų apšvietimą. Fono indikacija leis mums tiesiog reikiamu laiku ką nors įrašyti į masyvą pagrindinėje kilpoje SCR- ir jis akimirksniu pasirodys ekrane! Ir visi kodo pakeitimai susiveda į tai, kad vietoj kilpų naudojame pertraukimų tvarkyklės funkciją:

ISR(TIMER0_OVF_vect)(statinis nepasirašytas simbolis poz. = 0; COLS = 0xFF; ROWS = SCR; COLS = ~(1<< pos); if(++pos == SCR_SZ) pos = 0; }

Keletas komentarų.

Kintamasis poz, nurodydami dabartinio šviečiančio ženklo numerį, padarome jį vietiniu statiniu kintamuoju, kad jis išlaikytų savo vertę nuo pertraukos iki pertraukos. Pasibaigus funkcijai, mes savarankiškai (juk nebeturime kilpos) padidiname pažįstamos vietos skaičių, kol pasiekiame ribą – tokiu atveju vėl einame į pradžią.

Pagrindinėje programoje mums reikės tik inicijuoti prievadus ir laikmatį (šiuo atveju - Laikmatis 0), kad jis persipildytų mums reikalingais intervalais ir leistų trukdyti. Po to jums nereikia galvoti apie indikaciją - ji veiks tyliai ir ramiai. Bet kaip nustatyti norimą laikmačio perpildymo intervalą? Labai paprasta. Žmogaus akis mirgėjimą, kurio dažnis didesnis nei 25 Hz, suvokia kaip nuolatinį švytėjimą. Turime 6 indikatorius, kiekvienas iš jų turėtų mirgėti tokiu dažniu, o tai reiškia, kad informacija ekrane turėtų būti atnaujinama 25 x 6 = 150 Hz ar didesniu dažniu. Dabar apskaičiuokime laikmačio išankstinio skalavimo vertę: padalinkite MK laikrodžio dažnį iš 256 ( Laikmatis 0 kiekvienas turi AVR aštuonių bitų, o tai reiškia, kad jis persipildo suskaičiavus iki 256) - tai bus norima laikmačio išankstinio skalavimo vertė. Žinoma, mažai tikėtina, kad rezultatas sutaps su viena iš standartinių išankstinio skalavimo verčių - tai nėra problema, galite paimti artimiausią mažesnę tinkamą vertę. Ekranas veiks didesniu dažniu, bet tai nepablogins jo kokybės! Šalutinis poveikis bus didelė ekrano MK šerdies apkrova. Jei tai labai trukdo pagrindinei programai, turėsite perjungti ekraną į kitą laikmatį, pavyzdžiui, 16 bitų. 1 laikmatis, arba įveskite praleistų laikmačio perpildymo skaitiklį:

#define SKIP 15 /* praleidžiamų laikmačio pertraukimų skaičius */ ISR(TIMER0_OVF_vect)( statinis nepasirašytas simbolis poz = 0; statinis nepasirašytas simbolis, praleistas = SKIP; jei (--praleisti) grįžti; praleisti = PRAleisti; COLS = 0xFF; ROWS = SCR ; COLS = ~ (1<< pos); if(++pos == SCR_SZ) pos = 0; }

Šiuose supaprastintuose pavyzdžiuose darome prielaidą, kad prie uosto COLS, išskyrus bendruosius indikatorių katodus, daugiau nieko nėra prijungta. Tačiau realiame gyvenime tokia sėkmė pasitaiko nedažnai, o su likusiomis šio uosto linijomis greičiausiai jungiasi kažkas kita. Todėl, organizuojant dinaminį ekraną, visada turėtumėte užtikrinti, kad visų prievadų linijų, kurios nėra tiesiogiai susijusios su ekranu, būsena išliktų nepakitusi. Tai daroma paprastai: užuot tiesiog įrašę naują reikšmę prievadui, turėtumėte naudoti nereikalingų bitų maskavimą:

COLS |= 0x3F; // todėl užgesiname visas pažįstamas vietas COLS &= ~(1<

Abu operatoriai nekeičia prievado reikšmingiausių bitų reikšmės COLS.

3.2 Metodas su dekoderiu

Dekoderis gali būti naudojamas konvertuoti HEX arba BCD kodą į septynių segmentų simbolius arba pasirinkti vieną iš matricos stulpelių. Abi parinktys nuo anksčiau aptarto paprasčiausio metodo skirsis tik tuo, kaip bus organizuojama išvestis į prievadus EILUTĖS ir/arba COLS, prie kurio bus prijungti dekoderio įėjimai.
Galimybė naudoti dekoderį norint gauti septynių segmentų simbolį:

ISR(TIMER0_OVF_vect)(statinis nepasirašyto simbolio poz. = 0; COLS |= 0x3F; EILTELĖS = (EILUS & 0xF0) | (SCR & 0x0F); COLS &= ~(1<< pos); if(++pos == SCR_SZ) pos = 0; }

Kaip matote, pakeitimai yra minimalūs – prieš rodant EILUTĖS simbolio kodas iš masyvo SCR, užmaskuojami reikšmingiausi bitai, po kurių nustatomi mažiausiai reikšmingi bitai pagal simbolio kodą. Tai yra, manome, kad dekoderis yra prijungtas prie 4 mažiausiai reikšmingų prievado bitų EILUTĖS.

Tikiuosi, nėra prasmės pateikti pavyzdį, kaip iššifruoti stulpelius - viskas jau aišku.

3.3 Registracijos būdas

Nors dinaminis rodymas naudojant poslinkių registrus iš esmės nesiskiria nuo anksčiau aptartų metodų, tačiau yra keletas jo įgyvendinimo variantų. Apsvarstysime paprasčiausią - bitų išvedimą grynai programine įranga. Ir įgyvendinant kitus (naudojant USI/USART/SPI/TWI) galite patys išbandyti savo jėgas.

Anksčiau pasirinktam 6 ir septynių segmentų pažįstamų vietų ekrano variantui naudojame 2 tokio tipo pamainų registrus 74HC595. Šis registras valdomas trimis signalais: nuosekliais duomenų įvesties laikrodžio impulsais CLK, patys duomenys DUOMENYS ir registre įrašytos informacijos vienu metu lygiagrečio išvesties impulsą NUSTATYTI. Deklaruojame atitinkamas makrokomandas (paprastumo dėlei visus signalus siųsime į vieną prievadą):

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

Norėdami rašyti į registrą, patogu parašyti atskirą funkciją:

Statinis negaliojimo poslinkis(nežymėtas simbolis d)(nežymėtas simbolis 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; } }

Labai patartina šią funkciją padaryti statine, nes jis bus naudojamas pertraukimų tvarkyklėje. Tikėtina, kad kompiliatorius formoje atliks statines funkcijas eilutę-įterpimai į pertraukimų tvarkyklę, t.y. nebus nereikalingas kamino naudojimas, o tai negarantuojama nestatiškoms funkcijoms.

Dabar mūsų pertraukimų tvarkytuvas atrodys taip:

ISR(TIMER0_OVF_vect)(statinis nepasirašyto simbolio poz. = 0; shift(SCR); shift(~(1)<< pos)); REG_PORT |= SET; // выдаем импульс SET REG_PORT &= ~SET; if(++pos == SCR_SZ) pos = 0; }

Kadangi į registrus įrašyti duomenys jo išvestėse rodomi vienu metu, indikatorių pirmiausia gesinti nereikia. Reikėtų prisiminti, kad programinės įrangos nuoseklioji išvestis yra gana ilgas procesas, ypač didelių matmenų matricoms, todėl ji turėtų būti maksimaliai optimizuota greičiui. Tai geriausiai galima padaryti naudojant nuosekliosios išvesties aparatinę įrangą, esančią MCU.

4 Tiems, kuriems niekada negana

Taigi, jūs susipažinote su dinaminio ekrano diegimo pagrindais. Tačiau, kaip įprasta, klausimų ne mažėja, o daugėja. Numatydamas kai kuriuos iš jų, pasistengsiu nedelsiant pateikti reikiamus atsakymus.

4.1 Anodai, katodai – ką pasirinkti?

Viskas, ką mes svarstėme anksčiau, buvo susiję su indikatoriais su bendrais katodais. Ką daryti, jei norite jį naudoti su įprastais anodais? Apskritai viskas išlieka taip pat, išskyrus tai, kad prieš išvedant duomenis reikės invertuoti - pažinimo išvalymas atliekamas išvedant nulius COLS, uždegimas – atitinkamai vienetai ir segmentai in EILUTĖS bus įtraukti su nuliais, o ne vienetais. Taigi pertraukimų tvarkytuvas atrodytų maždaug taip:

ISR(TIMER0_OVF_vect)(statinis nepasirašytas simbolis poz. = 0; COLS &= 0xC0; ROWS = ~SCR; COLS |= (1)<< pos); if(++pos == SCR_SZ) pos = 0; }

Tai paprasta. Nebent, žinoma, bandysite parašyti universalų kodą, tinkantį ir įprastiems anodams, ir įprastiems katodams. Tai galima padaryti dviem būdais: arba naudojant sąlygines kompiliavimo direktyvas, arba naudojant konvertavimo funkciją. Pirmąjį variantą pademonstruosiu, o apie antrąjį siūlysiu pagalvoti patiems.

#define COMMON_ANODE 1 ISR(TIMER0_OVF_vect)(statinis nepasirašytas simbolis poz = 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; }

Nors tai yra šiek tiek sudėtinga, vieną kartą parašę jį galite naudoti visuose projektuose praktiškai be pakeitimų.

4.2 Mirgėjimas

Daugeliu atvejų ekranas naudojamas ne tik kaip iš įrenginio vidaus gaunamos informacijos rodymo priemonė, bet ir vartotojo įvesties atvaizdavimui. Ir šiuo atveju reikia mokėti ekrane kažkaip atskirti nekeičiamą nuo keičiamo. Lengviausias būdas tai padaryti – priversti atitinkamą pažįstamą vietą (ar kelias pažįstamas vietas) mirgėti.

Tai labai lengva padaryti. Įveskime visuotinį kintamąjį, kurio kiekvienas vieneto bitas žymės mirksintį simbolį:

beženklio simbolio mirksėjimas = 0;

Dabar šiek tiek pakeiskime pertraukimų tvarkyklę:

ISR(TIMER0_OVF_vect)(statinis nepasirašyto simbolio poz. = 0; statinio nepasirašyto simbolio įrašas = 0; COLS |= 0x3F; if(!(mirksi & (1)<

Kaip matote, buvo pridėtas tik vienas statinis kintamasis - pertraukimų tvarkyklės įėjimų skaitiklis įrašas, ir būklės tikrinimo operatorius. Logika paprasta: kito pažinimo išvestis vykdoma tik tuo atveju, jei atitinkamame bite mirksėti nulis arba reikšmingiausias skaitiklio bitas įrašas yra lygus 1. Jei, tarkime, mirksėti yra visi nuliai, tada ši sąlyga visada tenkinama – rodomos visos pažįstamos vietos. Jeigu mirksėti kurio viename iš bitų yra 1, tada atitinkamas ženklas bus apšviestas tik tuo metu, kai reikšmingiausias skaitiklio bitas yra lygus 1. Kadangi skaitiklis didinamas kiekvieną kartą įvedant pertraukimo tvarkyklę, atitinkamas ženklas bus rodomas mirgėjimo dažnis yra 128 kartus mažesnis nei pertraukimo dažnis.

4.3 Segmentų ryškumo reguliavimas

Apie ryškumo reguliavimą rašiau atskirame straipsnyje, kuris taip ir vadinosi.

4.4 Savavališkas kaiščių paskirstymas

Anksčiau buvo sakoma, kad laimė skirti visą MK prievadą demonstravimui yra gana reta. Tačiau dar rečiau gauti patogų spausdintinės plokštės pėdsaką, jei vienas prievadas naudojamas tik eilutėms, o kitas - ekrano matricos stulpeliams. Daug dažniau optimalus sekimas gaunamas tik tada, kai eilutės ir stulpeliai sumaišomi tarp dviejų ar net daugiau mikrovaldiklio prievadų. Jums nereikės aukoti spausdintinės plokštės grožio, jei ekrano metu suorganizuosite programinės įrangos bitų išdėstymą.

Pažvelkime į abstraktų pavyzdį. Tegul geriausias sekimas užtikrinamas tokiu signalų pasiskirstymu pagal MK prievadų linijas:

A segmentas

B segmentas

H segmentas

C segmentas

D segmentas

G segmentas

E segmentas

F segmentas

Kaip matote, matricos linijos yra sumaišytos tarp trijų prievadų, ir visos nepanaudotos šių prievadų eilutės, žinoma, neturėtų keisti savo lygių rodymo proceso metu.

Geriausia pradėti kurti dinaminės indikacijos funkciją šiuo atveju paskirstant segmentus simbolių bitams. Anksčiau mes tuo tikėjome masyve SCR Saugome veikėjų bitų kaukes, t.y. Tie, kurie yra baite, rodo šviečiančius segmentus. Mes negalvojome, kuris bitas atitinka kurį segmentą. Taigi, dabar pats laikas apie tai pagalvoti.

Uosto linijų paskirtį patogu nudažyti trijų plokščių pavidalu:

1

A

0

4

H

3

2

B

F

E

5

G

D

C

Turime surinkti visus segmentus į vieną baitą. Tai turės būti daroma naudojant pamainines operacijas, todėl turėtumėte stengtis jas paskirstyti taip, kad būtų kuo mažiau pamainų. Pakalbėkime.

Jei segmentas bitai FEGDC palikite simbolį, kad jie įkristų PORTD be poslinkių, tada segmentas H taip pat gali likti 6-ame simbolio bite ir jo taip pat nereikia perstumti prieš išvedant PORTC, bet segmentams A Ir IN 7 ir 3 bitai išliks, tai yra greičiausiai segmentas IN turės būti paslinktas 3 pozicijomis prieš išvestį ir segmentą A- iki 6. Sutelksiu dėmesį į šį variantą, o jūs galite toliau ieškoti minimalių pamainų (pamainos keliomis pozicijomis nėra toks greitas veiksmas, todėl patartina jų skaičių sumažinti iki minimumo).

Taigi, mūsų atveju, bitų pasiskirstymas per simbolių baitą buvo toks:

A

H

F

E

B

G

D

C

Pažymime bitų kaukes išvestims į atitinkamus prievadus:

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

Naudodami šias kaukes, mes naudojame operaciją „Bitwise AND“, kad pasirinktume reikiamus bitus išvestims į prievadą.

Paskelbkime kaukės konstantas:

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

Anksčiau simbolį išvesdavome į vieną prievadą EILUTĖS, dabar ši procedūra bus padalinta į tris dalis:

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

Atkreipkite dėmesį, kad norint atsiimti iki PORTC vienas bitas turi būti išvestas be poslinkio, o antrasis – su poslinkiu, taigi vietoj MASKC Teko naudoti atskiras makrokomandas _BV().

Dabar belieka nuspręsti, kaip užgesinti ir apšviesti atitinkamas pažįstamas vietas. Deklaruojame žinomumo valdymo bitus atitinkančias konstantas:

#apibūdinti COM0 _BV(0) #apibrėžti COM1 _BV(3) #apibrėžti COM2 _BV(4) #apibrėžti COM3 _BV(5) #apibrėžti COM4 _BV(7) #apibrėžti COM5 _BV(3) #apibrėžti COM_D (COM5) #apibrėžti COM_C (COM2 | COM3 | COM4) #define COM_B (COM0 | COM1)

Norėdami užgesinti visas pažintis, turite išvesti atitinkamas konstantas į prievadus COM_x:

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

Tačiau norėdami įjungti pažinimą, turėsite būti keblūs (nėra prasmės išvesti į visus tris prievadus, nes konkrečiame prievade bus aktyvus tik vienas bitas, priklausomai nuo reikšmės poz), pavyzdžiui, naudojant operatorių jungiklis:

Jungiklis (poz.) (0 atvejis: PORTB &= ~COM0; pertrauka; 1 atvejis: PORTB &= ~COM1; pertrauka; 2 atvejis: PORTC &= ~COM2; pertrauka; 3 atvejis: PORTC &= ~COM3; pertrauka; dėklas 4: PORTC &= ~COM4; pertrauka; 5 atvejis: PORTD &= ~COM5; pertrauka; )

Tai nėra pats gražiausias būdas, bet jis veikia.

Taigi mūsų pertraukimų tvarkyklės forma yra tokia:

ISR(TIMER0_OVF_vect)(statinis nepasirašyto simbolio poz. = 0; statinio nepasirašyto simbolio įrašas = 0; // išjungti PORTD |= COM_D; PORTC |= COM_C; PORTB |= COM_B; // rodyti PORTD = (PORTD & ~MASKD) | ( SCR & MASKD); PORTB = (PORTB & ~MASKB) | ((SCR & MASKB) >> 6); PORTC = (PORTC & ~MASKC) | ((SCR & _BV(6)) | (((SCR & _BV) (3) >> 3); // mirksėti if(!(mirksi & (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; }

Dabar belieka sugalvoti, kaip patogiau apibūdinti išvesties simbolius... Siūlau daryti taip: apibrėžti segmentų bitus atitinkančias konstantas ir iš šių konstantų „sukonstruoti“ reikiamus simbolius:

// elementarieji segmentai #apibrėžti _A _BV(7) #apibrėžti _B _BV(3) #apibrėžti _C _BV(0) #apibrėžti _D _BV(1) #apibrėžti _E _BV(4) #apibrėžti _F _BV(5) #apibrėžti _G _BV (2) #apibrėžti _H _BV(6) // skaitmenų simboliai #apibūdinti d_0 (_A | _B | _C | _D | _E | _F) #apibūdinti d_1 (_B | _C) #apibrėžti d_2 (_A | _B | _G | _D | _E) // ir pan

Taigi, jei jums reikia rodyti nulį tolimojoje dešinėje ekrano padėtyje, tiesiog turite parašyti tinkamoje vietoje:

SCR = d_0;

Jei kitame projekte reikia kitaip paskirstyti bitus, pakeisite tik skaičius makrokomandose _BV() elementariems segmentams, o visi simboliai bus „perdaryti“ automatiškai. Paprasčiausiais pradžioje aprašytais atvejais jums nereikės nieko daugiau daryti, tačiau norint pasirinkti „bitų pertvarkymą“, jums, žinoma, teks padirbėti.

4.5 Mygtukų palaikymas

Tradiciškai trūkstant MK kaiščių, daugybės mygtukų, be kurių retai kuris įrenginys gali išsiversti, problema yra labai opi. Naudojami įvairūs matriciniai inkliuzai ir kt. gudrybės, tačiau, šiek tiek apsunkinus dinaminio ekrano funkciją, lengva disponuoti tiek mygtukų, kiek yra pažįstamų ekrane, o tokiu atveju papildomai reikės naudoti tik vieną mikrovaldiklio prievadą. Tiesa, ant kiekvieno mygtuko vis tiek turite įdiegti diodą.

Tai schematiškai parodyta paveikslėlyje.

O programa atrodo taip:

#define keypin() (!(PIND & _BV(KEY))) ISR(TIMER0_OVF_vect)( statinis nepasirašytas simbolis poz = 0; statinis nepasirašytas simbolis = 0; statinis nepasirašytas simbolis 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; } }

Čia RAKTAS- tai makrokomanda, kuri nustato pasirinkto prievado bitą, prie kurio „prijungti“ visi mygtukai, makrokomandą klaviatūros segtukas () grąžina loginę reikšmę TRUE, jei pasirinktas kaištis yra logiškai žemas. Pavyzdyje mygtukai yra prijungti prie PORTD.

Kiekvieną kartą, kai įvyksta laikmačio pertraukimas, visi segmentai pirmiausia užgęsta - tai būtina, kad srovė per šviesos diodus nesukeltų klaidingai paspausto mygtuko neaptikimo. Po to mygtuko įvestis yra apklausiama - jei lygis žemas, tai reiškia, kad paspaudžiamas mygtukas, prijungtas prie atitinkamo pozicinio katodo. Kintamuoju tmp_key mygtukų būsenos kaupiamos ir perrašomos į visuotinį kintamąjį Raktas pasibaigus rodymo ciklui. Tereikia karts nuo karto išanalizuoti prasmę Raktas ir apdoroti aptiktus paspaudimus:

Statinis nepasirašytas simbolis get_key())(nepasirašytas simbolis tmp = 0; tmp = raktas; _delay_ms(10); if(key == tmp) return tmp; kitaip grąžina 0; )

Ši paprasta funkcija užtikrina, kad mygtukai neatšoktų, nepaisant to, kad dėl „dinamiško“ mygtukų apklausos pobūdžio atšokimo tikimybė jau yra maža.

5 Kas dar?

Taigi, jūs įvaldėte gana tipiškus dinaminio ekrano diegimo būdus. Manau, kad to tau užteks pirmam kartui, o gal net visam gyvenimui. Galų gale svarbiausia suprasti metodus ir algoritmus, o subtilybių ir niuansų visada galite pridėti patys. Bet kas dar gali laukti „arti“ dinaminiam ekranui?

Kaip jau sakiau anksčiau, galite pridėti, net iki nepriklausomo kiekvieno segmento reguliavimo.

Galite pagalvoti apie pertraukimų tvarkyklės optimalumą - švietimo tikslais parašiau gana grubų kodą, pavyzdžiui, naudojau visur SCR, nors optimaliau būtų vieną kartą perskaityti reikšmę į vietinį kintamąjį ir tada operuoti su jo verte. Nors optimizatorius tikrai padės mano požiūriui, praktikos tikslais verta pabandyti ir optimizuoti save, stebėti save pagal gaunamo kodo dydį ir (arba) programos greitį.

Galite pagalvoti apie įdomią idėją automatiškai reguliuoti ekrano ryškumą, atsižvelgiant į aplinkos apšvietimo lygį. Kaip žinote, LED indikatoriai yra mažiau matomi, kuo tamsesni – jie tiesiog susilieja. Todėl tamsoje tikslinga sumažinti indikatorių ryškumą, padidinant jį šviesiu paros metu. Paprasčiausias dalykas yra naudoti atskirą fotorezistorių arba LED kaip šviesos jutiklį, bet galite tai padaryti kitaip: žinoma, kad šviesos diodas gali veikti ir kaip fotodiodas, todėl, jei indikacijai naudojate prie įvesties prijungtą prievadą ADC, tada, jei norite, galite išmatuoti nešviečiančio indikatoriaus segmento foto-emf ir naudoti šią reikšmę ryškumui reguliuoti...

Galite pagalvoti apie nuosekliosios išvesties aparatūros naudojimą, apie ką jau užsiminiau.

Pasiūlė įdomią visiškai universalaus požiūrio į dinaminį ekraną variantą, su kuriuo taip pat rekomenduoju susipažinti MOLCHEC. Trumpai tariant, esmė: segmentų pasiskirstymas simbolių bitais, indikatoriui valdyti skirtų prievadų priskyrimas ir net indikatoriaus tipas - trumpai tariant, visi, visi, visi parametrai - yra nurodyti konfigūracijos lentelės pavidalu. EEPROM. Remiantis šia lentele, viskas organizuojama programiškai: nuo inversijos, priklausomai nuo indikatoriaus tipo, iki bitų pertvarkymo skirtinguose prievaduose. Tokiu atveju dinaminio rodymo programos šaltinio kodas visada išlieka nepakitęs, o konfigūracijos lentelę sudaro galutinis vartotojas, atsižvelgdamas į jo pageidavimus. Metodas yra tikrai universalus ir lankstus, tačiau yra susijęs su padidėjusiu programos atminties suvartojimu.


3 paskelbtas ARV, 06:48 2010-08-25
Miša, jūsų vietoje nedaryčiau tokių kategoriškų teiginių „tu negali“, „niekas to neparašė“ ar „autorių teisės“, nes pirma, tai nemandagu, o antra:
1. Seniai sukūriau šliaužiančią liniją ant 10x16 matricos (taip ir buvo) – jos veikimo vaizdo įrašą rasite šiame užraše http://site/content/view/160/38/
2. Parašiau straipsnį (rasite naujienose – šiandien paskutinis) apie tai, kaip padaryti stulpelį LCD. Jei šiek tiek įtempiate savo smegenis, tada perdaryti išvesties į matricą algoritmą yra smulkmena.
3. mano svetainėje nėra nei vieno iš kur nors nukopijuoto straipsnio (copy-paste nėra autorinės teisės, padarei klaidą), visa medžiaga visiškai originali. Daugelis svetainių turi šios medžiagos kopijas su mano leidimu (arba gavus medžiagos autorių leidimą, kurie turi visas teises publikuoti savo medžiagą daugelyje vietų vienu metu).

Komentuoti gali tik registruoti vartotojai.
Prašome užsiregistruoti arba prisijungti prie savo paskyros.

DKad indikatoriuje būtų rodomas kelių skaitmenų skaičius, pirmiausia turite su juo atlikti sudėtingą manipuliavimą, kurį sudaro skaičiaus suskaidymas į jo komponentus. Kaip pavyzdį pateiksiu skaičių 1234 ant keturių septynių segmentų indikatoriaus su bendru anodu.


Kad būtų rodomas keturių skaitmenų skaičius, reikia sukurti vieną bendrą kintamąjį, kuriame bus norimas rodyti skaičius (kintamasis W), keturi kintamieji, kuriuose bus saugomi kiekvieno ženklo duomenys (N) ir dar keturi kintamieji tarpinėms transformacijoms (M), kad nepaliestumėte pagrindinio kintamojo. Kintamasis turi atitikti reikšmę, kuri bus jame saugomaaš. Taigi kintamajamWtipo pakakssveikasis skaičius , nes šio tipo kintamasis gali saugotiPakeiskite reikšmes iš -32768 į +32767 (arbažodį nebent planuojate naudoti neigiamus skaičius). KintamuosiuoseNbus skaičiai nuo 0 iki 9, todėl naudojant kintamąjį patinkabaitas
. Ir kintamaisiaisM bustos pačios reikšmės kaip ir kintamajameW, todėl nustatome tipą sveikasis skaičius .

Dim W Kaip sveikasis skaičius
Dim N1 As Byte
Dim N2 As Byte
Dim N3 As Byte
Dim N4 As Byte
Pritemdytas M1 kaip sveikasis skaičius
Pritemdytas M2 kaip sveikasis skaičius
Dim M3 kaip sveikasis skaičius
Dim M4 kaip sveikasis skaičius


Deklaravus kintamuosius, sukonfigūruojame išvesties prievaduskuris bus naudojamas indikatoriui prijungti:

DDRC = &B11111111
DDRD = &B11111111


DDRC =&B 00001111 ir DDRD =&B 01111111 (keturios pirmosios C prievado dalysanodams ir pirmiesiems šešiems prievadams D segmentams).

Tada priskiriame kintamajam W reikšmė, kurią rodysime indikatoriuje:

W=1234

"Arial", "sans-serif""> Pagrindinėje programos kilpoje kintamojo reikšmę priskiriame kintamiesiems MW, aš darau taip:

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


"Arial", "sans-serif""> Tai nėra paranoja)), tai daroma siekiant, kad visi kintamieji M turėtų tą patį skaičių, nes priskyrimo operacijos metu gali lengvai įsilaužti pertraukimas (jei toks yra ir nėra išjungtas), kurio tvarkyklėje kintamasisW gali keistis. O jei užduotis vyko taip: M1= W , M 2 = W , M 3 = W , M 4 = W kintamieji M turės skirtingas reikšmes, todėl rodmenys bus netvarkingi.

Priskyrę kintamiesiems reikšmes, pradedame dirbti
kiekvienas iš jų, transformuojantis taip, kad į kintamąjį N pasiekti vertę, kuri bus
rodomas indikatoriuje: kintamajame
N 1 turėtų būti „1“, in N 2 – „2“, N 3 – „3“, o N 4 – „4“.

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

Abs – funkcija, kuri kintamajam grąžina sveikąjį skaičių.Kintamajam N 1 pataikė vieną, būtent to ir reikėjo.

Kintamajam priskirti du N 2 operacija bus šiek tiek sudėtingesnė:

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""> Pirmiausia – funkcijaMod pirmuosius tris grąžiname į kintamąjį
skaičiaus skaitmenys (likęs dalybos iš 1000), o tada viskas yra kaip pirmuoju atveju.

Tai beveik tas pats su paskutiniais dviem skaitmenimis:

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

M4 = M4 10 modifikacija
N4 = Abs (m4)


Dabar mūsų kintamuosiuose yra reikšmės, kurias norime rodyti, laikas mikrovaldikliui atsispirti kojomis ir parodyti šias reikšmes indikatoriuje, tam mes vadiname ekrano apdorojimo paprogramę:

"Arial", "sans-serif"">

Gosub Led

"Arial", "sans-serif""> Procesorius pereis prie paprogramės su etiketeLed:

Led:

Portc = &B00001000

"Arial", "sans-serif""> Čia mes aptarnaujame aukšto lygioPORTC .3, mes turime pirmos kategorijos anodą, prijungtą prie šios kojos. Tada pasirenkame, kuriuos segmentus reikia apšviesti, kad būtų rodoma pirmojo kintamojo reikšmė. Ji mums viena, tad ant kojų bus nulis Portd .1 ir Portd .2, kuris atitinka segmentus B ir C indikatorius.

Pasirinkite atvejį N1









Pabaigos pasirinkimas
Laukia 5

"Arial", "sans-serif""> Kai užsidegs reikiami segmentai, palaukite 5 ms ir tęskite, kad būtų rodomi šie skaičiai:

Portc = &B00000100
Pasirinkite atvejį N2
0 atvejis: Portd = &B11000000
1 atvejis: Portd = &B11111001
2 atvejis: Portd = &B10100100
3 atvejis: Portd = &B10110000
4 atvejis: Portd = &B10011001
5 atvejis: Portd = &B10010010
6 atvejis: Portd = &B10000010
7 atvejis: Portd = &B11111000
8 atvejis: Portd = &B10000000
9 atvejis: Portd = &B10010000
Pabaigos pasirinkimas

Laukia 5

Portc = &B00000010

Pasirinkite atvejį N3
0 atvejis: Portd = &B11000000
1 atvejis: Portd = &B11111001
2 atvejis: Portd = &B10100100
3 atvejis: Portd = &B10110000
4 atvejis: Portd = &B10011001
5 atvejis: Portd = &B10010010
6 atvejis: Portd = &B10000010
7 atvejis: Portd = &B11111000
8 atvejis: Portd = &B10000000
9 atvejis: Portd = &B10010000
Pabaigos pasirinkimas

Laukia 5

Portc = &B00000001

Pasirinkite Case N4
0 atvejis: Portd = &B11000000
1 atvejis: Portd = &B11111001
2 atvejis: Portd = &B10100100
3 atvejis: Portd = &B10110000
4 atvejis: Portd = &B10011001
5 atvejis: Portd = &B10010010
6 atvejis: Portd = &B10000010
7 atvejis: Portd = &B11111000
8 atvejis: Portd = &B10000000
9 atvejis: Portd = &B10010000
Pabaigos pasirinkimas

Laukia 5

"Arial", "sans-serif""> Rodydami informaciją indikatoriuje, turite grįžti į pagrindinę programos ciklą, kur reikia užbaigti kilpą ir nurodyti programos pabaigą.

"Arial", "sans-serif""> Štai ką mes galiausiai gauname:

"Arial", "sans-serif"">

"Arial", "sans-serif""> Dėl nedidelio perjungimo delsos perjungimas nebus pastebimas žmogaus akiai ir pamatysime sveikąjį skaičių 1234.

Žemiau galite atsisiųsti šaltinį ir projektą „Proteus“:"Arial", "sans-serif"">



 


Skaityti:



Klasės ir vardų erdvės Vardų erdvių naudojimas ir deklaravimas

Klasės ir vardų erdvės Vardų erdvių naudojimas ir deklaravimas

Klasės ir vardų erdvės .NET Framework klasės Galbūt didžiausia valdomo kodo rašymo nauda – bent jau kalbant apie...

Knygelė tema „kompiuteris ir vaikai“ Taisyklinga rankų padėtis

Knygelė šia tema

Atlikite specialius pratimus akims! 1. Intensyvus akių spaudimas ir atmerkimas greitu tempu bei dažnas mirksėjimas akimis. 2. Akių judesiai...

Snieglenčių sportas: kaip viskas prasidėjo?

Snieglenčių sportas: kaip viskas prasidėjo?

Snieglenčių sportas – olimpinė sporto šaka, kurios metu nuo apsnigtų šlaitų ir kalnų leidžiama nusileisti specialia įranga – snieglente. Iš pradžių žiemos...

Nuotrauka, kur ji yra pasaulio žemėlapyje, aprašymas

Nuotrauka, kur ji yra pasaulio žemėlapyje, aprašymas

Nuo seniausių laikų iki šių dienų pasaulyje buvo sukurta daug vandens kelių – dirbtinių kanalų. Pagrindinės tokių dirbtinių užduotys – palengvinti...

tiekimo vaizdas RSS