0,00 €

V košarici ni izdelkov.

0,00 €

V košarici ni izdelkov.

More
    DomovRevijaProgramiranjeShield-A, prikazovanje na alfanumeričnem displeju

    Shield-A, prikazovanje na alfanumeričnem displeju

    Svet elektronike colorAlfanumerični displej, postavljen na ploščico razvojnega sistema Shield-A, daje mikrokontrolerju možnost izpisa smiselnih sporočil tudi brez povezanosti z osebnim računalnikom: če mu zagotovimo ustrezno napajanje, bo komplet Arduino Uno + Shield-A + LCD postal avtonomni komplet, in za komunikacijo z uporabnikom osebni računalnik ni več potreben. Zato je alfanumerični displej zelo koristen dodatek mikrokontrolerskega kompleta. Zato se bomo v tem nadaljevanju bolj podrobno spoznali z njegovimi možnostmi. Poglejmo najprej, katere vse ukaze programska jezika Bascom-AVR in Arduino imata predvidene za delo z LCD-jem (tabeli 1 in 2).

    Shield-A, učni pripomoček za programiranje mikrokontrolerjev (8)

    Tabela 1. Spisek osnovnih Bascom-AVR ukazov za delo s AN displejem

    ukaz opis
    CLS Briše obstoječi izpis na displeju, postavlja kurzor na naslov 1, 1 (začetek prve vrstice)
    HOME V Postavlja kurzor na naslov 1, 1 (začetek prve vrstice)
    HOME L Postavlja kurzor na naslov 2, 1 (začetek druge vrstice)
    HOME T Postavlja kurzor na naslov 3, 1 (začetek tretje vrstice)
    HOME F Postavlja kurzor na naslov 4, 1 (začetek četrte vrstice)
    LOCATE y , x Postavlja kurzor na naslov y, x (y = vrstica, x = pozicija znotraj vrstice)
    CURSOR ON/OFF Vklopi/izklopi prikaz kurzorja
    DISPLAY ON/OFF Vklopi/izklopi prikaz na displeju
    LCD x Izpiše vsebino konstante ali spremenljivke “x”začenši od trenutne pozicije kurzorja
    SHIFTLCD LEFT/RIGHT Premika vsebino displeja eno pozicijo v levo/v desno

    Tabela 2. Spisek osnovnih funkcij klase LiquidCrystal za delo z AN displejem iz Arduino IDE

    ukaz opis
    begin()
    clear() Briše obstoječi izpis na displeju, postavlja kurzor na naslov 0, 0 (začetek prve vrstice)
    home() Postavlja kurzor na naslov 0, 0 (začetek prve vrstice)
    setCursor(x,y) Postavlja kurzor na naslov y, x (y = vrstica, x = pozicija znotraj vrstice)
    print() Izpiše vsebino na displeju
    display() Vklopi prikaz na displeju po izklopu z ukazom noDisplay()
    noDisplay() Izklopi prikaz na displeju
    cursor() Vklopi prikaz kurzorja
    noCursor() Izklopi prikaz kurzorja
    scrollDisplayLeft() Premika vsebino displeja eno pozicijo v levo
    scrollDispplayRight() Premika vsebino displeja eno pozicijo v desno

    Za uspešno rešitev 11. in 12. programske naloge bomo potrebovali alfanumerični displej ter tipki SW1 in SW2 na razvojnem sistemu Shield-A. Shema na sliki 32 prikazuje, kako je vse to povezano s priključki Arduino Uno ploščice, oziroma s priključki mikrokontrolerja ATmega328P.

    Slika 32: Shema vezja, ki ga bomo uporabili v programih Shield-A_11 in Shield-A_12

    11. programska naloga: v spominu alfanumeričnega displeja je definiranih 192 znakov. Poleg velikih in malih črk angleške abecede, številk in drugih znakov, katere običajno najdemo na tipkovnici osebnega računalnika. V spominu displeja se nahajajo tudi znaki kitajske abecede in nekaj črk grške abecede. Del teh znakov lahko izpišemo direktno, z uporabo znakov s tipkovnice osebnega računalnika, drugi del pa posredno, z uporabo ustrezne funkcije. Program mora izpisati vse znake, ki so vpisani v spominu alfanumeričnega displeja. Izpisovali jih bomo v blokih po 16 znakov v spodnji vrstici displeja, medtem ko se v zgornji vrstici izpisujejo parametri Bascom-AVR funkcije Chr(), oziroma Arduino funkcije lcd.write(), potrebni za izpis posameznega znaka.

    Bascom-AVR rešitev (program Shield-A_11.bas)

    V programu moramo najprej definirati kateri tip AN displeja uporabljamo, opisati kako so njegovi priključki povezani s priključki mikrokontrolerja in vključiti osvetlitev ozadja; ta del programa smo opisali v predhodnem članku. Nato bomo konfigurirati priključke PC1 in PC2 kov vhodne, zato, da bi z njimi lahko brali stanja tipk SW1 in SW2:

    Config Portc.1 = Input
    Portc.1 = 1
    Config Portc.2 = Input
    Portc.2 = 1

    Tipki bomo uporabili za izpis naslednjega oziroma predhodnega bloka znakov. V programu bomo potrebovali te tri spremenljivke:

    Dim Znak As Byte
    Dim Od_znaka As Byte
    Dim Do_znaka As Byte

    Spremenljivko Znak bomo uporabili kot kazalo na en znak iz tabele znakov definiranih v spominu displeja. Ti znaki se nahajajo na naslovih 32-127 in 160-255, pri čemer naslovi 32-127 vsebujejo definicije znakov, katere običajno srečujemo na tipkovnici osebnega računalnika in njihov položaj v tabeli ustreza njihovi ASCII kodi. Npr., ASCII koda črke “A” je &B01000001, kar ustreza desetiški številki 65, in zato se bo definicija znaka “A” nahajala na naslovu 65. Zaradi te skladnosti”znake s tipkovnice” lahko izpisujemo na displeju direktno, npr.

    Lcd “ABC”

    vendar tudi posredno, z uporabo funkcije Chr():

    Lcd Chr(65); Chr(66); Chr(67)

    Oba primera bi na displeju izpisala tekst ABC. V drugem bloku se nahajajo znaki kitajske abecede, grške abecede in nekateri specialni znaki. Te znake lahko izpišemo samo posredno, z uporabo funkcije Chr(). Npr, znake definirane na naslovih 200 in 201, kar koli bi že bili, bomo izpisali tako:

    Lcd Chr(200); Chr(201)

    Spremenljivki Od_znaka in Do_znaka bomo uporabili v podprogramu Ispis kot mejne vrednosti bloka znakov, kateri se trenutno prikazujejo. V zgornji vrstici izpisujemo kateri razpon znakov pokrivamo s tem prikazom:

    Ispis:
    Do_znaka = Od_znaka + 15
    Home V
    Lcd “Chr(” ; Od_znaka ;
    Lcd “-” ; Do_znaka ; “) ”

    in nato jih znak po znak, v For-Next zanki, izpisujemo v spodnji vrstici:

    Home L
    For Znak = Od_znaka To Do_znaka
    Lcd Chr(znak)
    Next
    Return

    V glavni zanki preverjamo ali je bila pritisnjena katera od tipk in ko se to dogodi, kličemo podprograme Nazad ali Naprijed:

    Do
    Debounce Pinc.1 , 0 , Nazad , Sub
    Debounce Pinc.2 , 0 , Naprijed , Sub
    Loop

    V njih se pripravljamo za prikaz predhodnega ali naslednjega bloka znakov:

    Nazad:
    If Od_znaka > 32 Then
    Od_znaka = Od_znaka – 16
    End If
    Gosub Ispis
    Return

    Naprijed:
    If Od_znaka < 240 Then
    Od_znaka = Od_znaka + 16
    End If
    Gosub Ispis
    Return

    Slika 33: Prikaz sporočil iz programa Shield-A_11

    Fotografije na Sliki 33 prikazujejo, kako to izgleda v praksi. Vsebina gornje vrstice displeja tolmačimo na naslednji način: znaki v spodnji vrstici dobimo z uporabo Chr(48) do Chr(63), oziroma, Chr(224) do Chr(239).

     

    Arduino rešitev (program Shield-A_11.ino)

    V programu moramo najprej definirati knjižnico funkcij, ki nam omogoča enostavnejše delo z displejem, nato definiramo kateri tip AN displeja uporabljamo, opišemo kako so njegovi priključki povezani s priključki mikrokontrolerja in vključimo osvetlitev ozadja; ta del programa smo opisali v predhodnem članku. Nato bomo konfigurirali priključke PC1 in PC2 kot vhodne zato, da bi z njimi lahko brali stanje tipk SW1 in SW2:

    pinMode(A1, INPUT_PULLUP);
    pinMode(A2, INPUT_PULLUP);

    Tipki bomo uporabili za izpis naslednjega oziroma predhodnega bloka znakov. V programu bomo potrebovali te tri spremenljivke na nivoju celotnega programa:

    byte znak;
    byte Od_znaka = 32;
    byte Do_znaka;

    Spremenljivko znak bomo uporabili kot kazalo na en znak iz tabele znakov definiranih v spominu displeja. Znake lahko izpisujemo na displeju direktno, npr.

    Lcd.print(“ABC”);

    pa tudi posredno, z uporabo funkcije lcd.write():

    lcd.write(65);
    lcd.write(66);
    lcd.write(67);

    Oba primera bi na displeju izpisala tekst ABC. V drugem bloku se nahajajo znaki kitajske abecede, grške abecede in nekateri specialni znaki. Te znake lahko izpisujemo samo posredno, z uporabo funkcije lcd.write(). Npr, znake definirane na naslovih 200 in 201, kar koli so že, izpisat jih bomo tako:

    lcd.write(200);
    lcd.write(201);

    Spremenljivke od_znaka in do_znaka bomo uporabili v funkciji izpis() kot mejne vrednosti bloka znakov, kateri se trenutno prikazujejo. V zgornji vrstici izpisujemo kateri razpon znakov pokrivamo s tem prikazom:

    void izpis(){
    do_znaka = od_znaka + 32;
    lcd.setCursor(0,0);
    lcd.print(“Chr(“);
    lcd.print(od_znaka);
    lcd.print(“-“);
    lcd.print(do_znaka);
    lcd.print(“) “);

    in nato jih znak po znak, v for zanki, izpisujemo v spodnji vrstici:

    lcd.setCursor(0,1);
    for (znak = od_znaka; znak <= do_znaka; znak++){
    lcd.write(znak);
    }
    }

    V funkciji loop() preverjamo ali je bila pritisnjena katera od tipk in ko se to dogodi, kličemo funkciji nazad() ali naprijed(). V primeru Shield-A_6b smo pojasnili kako ta algoritem dela:

    void loop() {
    if (digitalRead(A1) == 0) {
    delay(25);
    if (digitalRead(A1) == 0) {
    nazad();
    while (digitalRead(A1) == 0){
    }
    }
    }
    if (digitalRead(A2) == 0) {
    delay(25);
    if (digitalRead(A2) == 0) {
    naprijed();
    while (digitalRead(A2) == 0){
    }
    }
    }
    }

    V njem se pripravljamo za prikaz predhodnega ali naslednjega bloka znakov:

    void nazad(){
    if ( od_znaka > 32) {
    od_znaka = od_znaka – 16;
    }
    izpis();
    }

    void naprijed(){
    if (od_znaka < 240) {
    od_znaka = od_znaka + 16;
    }
    izpis();
    }

    ***

    12. programska naloga: Poleg znakov katerih definicija je trdno vpisana v spomin alfanumeričnega displeja, ima uporabnik možnost definirati osem lastnih znakov. Te znaki se namestijo v RAM displeja na naslovne lokacije 0-7 in se lahko izpišejo s pomočjo funkcij Chr(), oziroma lcd.write (). Naša naloga je definirati posebne znake in napisati sporočilo “Mačak Tom i mišić Jerry”.

    Bascom-AVR rešitev (program Shield-A_12.bas)

    Za definiranje lastnih znakov v Bascom-AVRu bomo uporabili orodje “LCD designer” iz menija “Tools” (Slika 34).

    Slika 34: Definiranje lastnih znakov s pomočjo orodja LCD designer

    V mreži, ki jo nariše LCD designer, kliknemo v polja, ki jih želimo počrniti in tako, točko za točko, oblikujemo želeni znak. Ko zaključimo oblikovanje s klikom na gumb “OK”, se bo v programu pojavila vrstica, ki je na sliki 34 izpisana na modri podlagi. Tukaj moramo zamenjati “[x]” s številko med 0 in 7 (0 v primeru na sliki) in ukaz Deflcdchar bo črko “č” shranil v RAM displeja na naslov 0! Na isti način bomo definirali tudi črki “ć” in “š”:

    Deflcdchar 0, 10, 4, 14, 16, 16, 17, 14, 32 ‘ č
    Deflcdchar 1, 2, 4, 14, 16, 16, 17, 14, 32 ‘ ć
    Deflcdchar 2, 10, 4, 14, 16, 14, 1, 30, 32 ‘ š
    Cls

    Definiranje lastnih znakov obvezno zaključimo z ukazom Cls, nakar nam bodo postali dostopni v programu. V glavni zanki bomo izmenično izpisovali sporočila z lastnimi znaki:

    Do
    Lcd “ma” ; Chr(0) ; “ak Tom i”
    Home L
    Lcd “mi” ; Chr(2) ; “i” ; Chr(1) ; ” Jerry”
    Wait 2
    Cls

    in sporočila s “črkami iz tipkovnice”

    Lcd “mačak Tom i”
    Home L
    Lcd “mišić Jerry”
    Wait 2
    Cls
    Loop

    Slika 35: Sporočilo s “črkami iz tipkovnice” (zgoraj) in sporočilo s lastnimi znaki (spodaj)

    zato, da bi poudarili razliko: če uporabljamo črke kot č, ć, đ, š in ž s tipkovnice, se bodo na displeju prikazale kot “čudni znaki” (slika 35).

     

    Arduino rešitev (program Shield-A_12.ino)

    Adruino IDE nima LCD designerja, zato bomo uporabili tekstualno vizualizacijo znakov v programski kodi. Glede na to, da se vsaka vključena točka znaka opisuje s številko 1, vsaka izključena pa s številko 0, bomo definirati za vsak znak posebej enodimenzionalno polje vrste byte velikosti 8 bajtov. Za črko č bomo definirati polje imena ch:

    byte ch[8] = {
    B01010,
    B00100,
    B01110,
    B10000,
    B10000,
    B10001,
    B01110,
    B00000}; // č

    Opazili boste, da smo za vsakega člana polja vpisali številko v binarni obliki, ki predstavlja eno vrstico “slike” znaka. Ko se navadimo gledati to “matrico” velikosti 8×5 točk, bomo videli, da so obrisi, ki jih tvorijo številke 1 pravzaprav enaki obrisu male črke č.

    Polja za črk ć in š definiramo na isti način:

    byte cc[8] = {
    B00010,
    B00100,
    B01110,
    B10000,
    B10000,
    B10001,
    B01110,
    B00000}; // ć

    byte sh[8] = {
    B01010,
    B00100,
    B01110,
    B10000,
    B01110,
    B00001,
    B11110,
    B00000}; // š

    Ko smo definirali kako bodo izgledali znaki, je potrebno v funkcijo setup() dodati tudi ukaz lcd.createChar(), s katero definiramo znake za izpis. Ukaz prejema dve informaciji: spominski naslov in polje s definicijo izgleda znaka:

    lcd.createChar(0, ch);
    lcd.createChar(1, cc);
    lcd.createChar(2, sh);

    Za izpis definiranega znaka uporabljamo funkcijo lcd.write(), v kateri kot vhodni parameter vpisujemo spominski naslov kot vrsto byte. Primer izpisa znaka č:

    lcd.write(byte(0));

    V primeru, da smo pozabili definirati, da je številka nič vrste byte, bo prevajalnik javil napako pri prevajanju programa.

    V funkciji loop() bomo izmenično izpisovali sporočila z lastnimi znaki

    void loop() {
    lcd.print(“ma”);
    lcd.write(byte(0));
    lcd.print(“ak Tom i”);
    lcd.setCursor(0,1);
    lcd.print(“mi”);
    lcd.write(byte(2));
    lcd.print(“i”);
    lcd.write(byte(1));
    lcd.print(” Jerry”);
    delay(2000);
    lcd.clear();

    in sporočila s “črkami s tipkovnice”

    lcd.print(“mačak Tom i”);
    lcd.setCursor(0,1);
    lcd.print(“mišić Jerry”);
    delay(2000);
    lcd.clear();
    }

    Opomba: Programi Shield-A_11.bas, Shield-A_12.bas, Shield-A_11.ino in Shield-A_12.ino se lahko brezplačno dobijo od uredništva revije Svet elektronike.

    Avtorja: Vladimir Mitrović in Robert Sedak
    email: vmitrovic12@gmail.com