0,00 €

V košarici ni izdelkov.

0,00 €

V košarici ni izdelkov.

More
    DomovLiteraturaArhiv literatureLCD prikazovalnik s PIC

    Morda se vam zdi to precej zapleteno, ampak videli boste, da ni nič kaj posebnega. Inicializacijo je potrebno izvesti le ob vklopu vezja, kasneje pa je delo z LCD-jem veliko enostavnejše. LCD deluje takoj po vklopu napajanja v 8-bitnem načinu. Prav zaradi tega ima prvi ukaz inicializacije, ki določa način delovanja, vse štiri spodnje bite enake 0. Ko je LCD priključen samo preko pinov D7 – D4, so pini D3 – D0 avtomatsko postavljeni na stanje logične 0. Tako lahko prvi ukaz izvedemo ne glede na način priključitve. Ko preklopimo na 4-bitni način, pošiljamo podatke po postopku iz prejšnjega poglavja. Zakasnitve med posameznimi ukazi so lahko daljše, napisal sem le minimalne (nekatere so v HD44780 dokumentaciji še malenkost manjše, vendar je bolje postaviti mejo malo višje). Po inicializaciji moramo videti prazen zaslon, v zgornjem levem kotu pa mora utripati kurzor v obliki črnega pravokotnika. Kot primer si oglejte naslednji program, ki inicializira LCD zaslon z 2×16 znaki.

    Program init.asm se nahaja na downloadu.

    Program je napisan za tako priključitev LCD-ja, kot jo lahko vidite na shemi iz slike 6. Seveda lahko LCD priključite tudi na kake druge pine, vendar pazite, da bodo pini D7 – D4 vezani na sosednje pine istih vrat mikrokontrolerja v pravem vrstnem redu, sicer boste morali krepko premetavati bite pri programiranju (kot sem že napisal: D7 je zgornji bit, D4 pa spodnji bit 4-bitnega podatka). V programu smo srečali novo direktivo #define. Vse, kar ta direktiva naredi, je, da tekst v prvem parametru zamenja s tekstom v drugem parametru. V našem primeru smo si tako skrajšali pisanje in naredili program bolj pregleden: kadarkoli se npr. v programu pojavi beseda RS, jo prevajalnik zamenja s tekstom PORTB,1, kar je tudi lokacija pina RS (torej pin RB1 na mikrokontrolerju). Če želimo RS pin postaviti na 0, lahko sedaj to napravimo krajše in pregledneje kar z BCF RS namesto z BCF PORTB,1. V glavnem programu smo najprej nastavili mikrokontroler na ustrezen način delovanja. Timerju smo dodelili preddelilnik 1:4, tako da potrebuje za štetje od 0 do prekoračenja TMR0 1,024 ms. To nato uporabimo v podprogramu za milisekundne zakasnitve CakajMs. Tam namreč izbrišemo TMR0 in čakamo, da prekorači svoj obseg in se zopet vrne na 0. Ko se to zgodi, se postavi zastavica T0IF na 1 in nam to prekoračenje sporoči. Podprogram čaka toliko časa, dokler se zastavica ne vklopi, nato pa ta cikel dolžine 1,024 ms ponovi tolikokrat, kolikor je vrednost v registru W pred klicem podprograma. Da bi preprečili klicanje prekinitev ob prekoračitvi TMR0, smo v glavnem programu izklopili bit GIE in tako onemogočili prekinitve. Prav tako moramo paziti, da vedno po prekoračenju vrednosti TMR0 izklopimo bit T0IF, saj tega PIC ne stori sam. Podprogram Cakaj119us napravi 119 µs zakasnitve na dobro poznani način z zanko. Podprogram LCD_init poskrbi za inicializacijo po že opisanem postopku. V tem podprogramu večkrat uporabimo drug podprogram z imenom LCD_pisi. Ta v LCD vpiše neko 8-bitno vrednost v 4-bitnem načinu po postopku, ki smo ga že opisali. Podprogram je tako narejen, da podatek za vpis prebere iz registra W, ki ga moramo tja seveda sami vpisati pred klicem podprograma. V tem delu najdemo tudi 3 nove instrukcije: ANDLW, ANDWF in IORWF. ANDLW (AND Literal with W – napravi logični AND med W in konstanto) napravi logično operacijo AND (IN) med posameznimi istoležnimi biti registra W in števila, ki ga podamo v edinem parametru te instrukcije. Rezultat se vpiše nazaj v register W. Poglejmo si pravilnostno tabelo za operacijo AND in primer operacije med dvema številoma, , tabela 4.

    Slike niOperacijo AND uporabljamo kar pogosto, saj je zelo uporabna za izklapljanje poljubnih bitov v bajtu. Kot lahko vidite iz pravilnostne tabele, AND med 1 in nekim bitom ohrani vrednost tega bita, če pa izvedemo isto operacijo med 0 in nekim bitom, se bo ta bit vedno postavil na 0. Če želimo npr. hkrati izklopiti pina RB1 in RB3, lahko izvedemo operacijo AND med registrom PORTB in številom b’11110101′ (temu številu pravimo maska). Vsi pini, ki imajo v maski vrednost 1, bodo ostali nespremenjeni, RB1 in RB3 pa se bosta postavila na 0, ker imata v maski vrednost 0. Tako smo namesto dveh instrukcij BCF problem rešili le z eno. Prav tako vlogo ima ta instrukcija tudi v našem podprogramu za izpis podatka na LCD: pine RB7 – RB4 pobriše, da se lahko nanje vpiše nov podatek, hkrati pa ohrani vrednosti pinov RB3 – RB0, ki so priključeni na pine RS, R/W in E in se zato ne smejo spreminjati. Podobna instrukciji ANDLW je tudi ANDWF (AND W with File – napravi logični AND med W in registrom), ki ravno tako izvaja logični AND, vendar med registrom W in registrom, katerega naslov podamo v prvem parametru. Kam se rezultat shrani, je odvisno od drugega parametra: če je ta f, se rezultat vpiše nazaj v register, če pa je w, se rezultat shrani v delovni register W. Instrukcija IORLW (Inclusive OR Literal with W – napravi logični OR med W in konstanto) napravi logično operacijo OR (ALI) med posameznimi istoležnimi biti registra W in konstanto, podano v prvem parametru. Rezultat se shrani v register W. Zelo podobna ji je instrukcija IORWF (Inclusive OR W with File – napravi logični OR med W in registrom), ki ravno tako izvaja logično operacijo OR (ALI), vendar med registrom W in drugim registrom, katerega naslov je podan v prvem parametru. Rezultat operacije se shrani v W, če je drugi parameter W, ali pa nazaj v register iz prvega parametra, če je drugi parameter f. Pravilnostna tabela za operacijo OR je taka, , tabela 5.

    Slike niIz pravilnostne tabele lahko vidimo, da dobimo pri operaciji OR med 0 in nekim bitom vedno nespremenjeno vrednost bita, pri logičnemu OR med 1 in nekim bitom pa postane ta bit vedno enak 1. OR je torej zelo pripraven za vklapljanje poljubnih bitov v bajtu, če pri tem ne želimo spreminjati ostalih bitov. Vse, kar moramo storiti, je, da izvedemo OR med bajtom, v katerem želimo vklapljati bite in masko, v kateri so biti, ki jih želimo vklopiti, enaki 1, vsi ostali pa enaki 0. Če želimo npr. postaviti RB1 in RB4 hkrati na 1 in pustiti ostale pine nespremenjene, izvedemo logični OR med registrom PORTB in masko b’00010010′. Na tak način smo uporabili OR tudi v našem podprogramu, saj smo z njim vpisali podatek na pine RB7 – RB4 (torej D7 – D4). Če bi podatek vpisali direktno, bi lahko spremenili tudi pine RB3 – RB0, ki imajo druge funkcije. Vse štiri nove instrukcije, ki smo jih spoznali, se izvedejo v 1 strojnem ciklu. Da bi lahko poslali enkrat zgornje 4 bite podatka in drugič spodnje 4 bite, smo uporabili instrukcijo SWAPF, ki smo jo že spoznali v prejšnjem poglavju. Z njo spravimo spodnje 4 bite podatka (spodnji nibble) na mesto zgornjih 4 bitov (zgornji nibble). Preden nadaljujemo še eno opozorilo: pri vklopu in izklopu pina E je pomembno, da je pin dovolj dolgo na stanju logične 1. V našem primeru je v tem stanju 1 µs, ker je vklopljen le eno instrukcijo. V dokumentaciji kontrolerja HD44780 piše, da je minimalna širina tega impulza 450 ns. V našem primeru je torej PIC 16F84 prepočasen, da bi naredil impulz krajši od 450 ns, pri hitrejših PIC-ih (npr. s taktom 20MHz), kjer se izvedejo instrukcije v 250 ns, pa bi lahko nastopile težave zaradi prekratkega impulza. Če se pojavi ta težava, jo rešimo preprosto tako, da med instrukcijama za vklop in izklop pina E dopišemo še eno NOP instrukcijo, ki ne stori ničesar, razen da zapravi 1 strojni cikel časa.

    Ukazi LCD prikazovalnika

    LCD upravljamo s pomočjo ukazov. Vsak ukaz je koda dolžine enega bajta, ki jo pošljemo v LCD po že poznanem postopku (za 4-bitni način smo že napisali podprogram LCD_pisi, ki zna to storiti. Kodo ukaza moramo pred klicem podprograma vpisati v register W.). Na LCD zaslonu vedno vidimo kurzor, ki ima enako funkcijo kot tisti na zaslonu vašega računalnika. Kurzor lahko tudi izključimo, če pa je vključen, mu lahko določimo dve različni obliki: lahko je tanka črtica ali pa utripajoč temen pravokotnik. Kurzor se vedno nahaja na znaku, ki je na trenutnem naslovu DDRAM-a. Če je trenuten DDRAM naslov izven vidnega polja zaslona, tudi kurzorja ne bomo videli. Kadar v LCD vpišemo nov znak, se bo vedno izpisal tam, kjer se je predhodno nahajal kurzor. Poglejmo si sedaj, katere ukaze pozna LCD.

    Clear display (pobriši zaslon)

    Okoli tega ukaza ni potrebno dosti razpravljati: vse, kar stori, je, da pobriše LCD zaslon in postavi naslov DDRAM-a na 0x00 (torej postavi kurzor na naslov 0x00). Koda ukaza je 0x01, pina RS in R/W morata biti izključena, po izvedbi ukaza pa moramo počakati več kot 2 ms. Brisanje zaslona poteka tako, da se na vse naslove DDRAM-a vpiše presledek, ki ima ASCII kodo 32 (decimalno). Izbriše se celoten DDRAM, torej tudi tisti del, ki trenutno ni viden na zaslonu.

    Return home (postavi zaslon v začetno pozicijo)

    Ta ukaz nastavi trenuten naslov DDRAM-a na 0x00, torej pomakne kurzor v zgornji levi rob zaslona, in pomakne vidni del zaslona na začetno pozicijo, torej tako, da ima zgornji levi znak naslov 0x00. Vsebine DDRAM-a ne spremeni, torej ostanejo v njem vsi predhodno vpisani znaki nespremenjeni. Koda ukaza je 0x02, pina RS in R/W morata biti izključena, po izvedbi ukaza pa moramo počakati več kot 2 ms.