Programarea Microcontrollerului

Cuprins

Introducere

Capitolul 1 – Considerente Teoretice

1.1 Interfața cu utilizatorul

Capitolul 2 – Microcontrolerul

2.1 Diferențele dintre Microcontroler și Microprocesor

2.2 Memoria

2.2.1 Diferitele tipuri de memorii RAM

2.2.2 Diferitele tipuri de memorii ROM

2.2.3 Memoriile Hibrid

2.3 Regiștri prezenți în microcontrolerul PIC16F887

2.3.1 Registrul STATUS

2.3.2 Registrul OSCCON (Oscillator Control)

2.3.3 Registrul ANSELH

2.3.4 Registrul TRISB

2.3.5 Registrul PORTB

2.3.6 Registrul IOCB (Interrupt-on-change

2.3.7 Registrul ANSEL

2.3.8 Registrul TRISA

2.3.9 Registrul PORTA

Capitolul 3 – Programarea Microcontrolerului

3.1 MPLAB IDE

3.1.1 Comenzi de manipulare a biților

3.2 PICKit 2

3.2.1 Programarea ICSP

Capitolul 4 – Componentele de intrare/ieșire

4.1 LCD display AC-162B

4.2 Keypad 4×4

Capitolul 5 – Realizarea practică a unei interfețe utilizator

5.1 Configurarea Microcontrolerului

5.2 Configurarea afișajului AC-162B

5.2.1 Algoritmul de scriere a unui caracter

5.2.2 Timpii de execuție ai afișajului AC-162B

5.3 Configurarea tastaturii – Secvența de validare a unei taste

5.3.1 Algoritmul de executare a comenzilor pentru tastele 2 și 8

5.3.2 Algoritmul de executare a comenzilor pentru tastele 4 și 6

5.4 Posibile îmbunătățiri

Concluzii

Bibliografie

Anexe

Introducere

Lucrarea, in sine, este împărțita in trei părți. În prima parte se va prezenta importanța apariției și evoluției interfețelor utilizator, care funcționeaza pe baza unor componente electronice, unele simple altele complexe, care cu ajutorul unor senzori de interfațare cu mediul înconjurator realizeaza afișarea, monitorizarea, stocarea, manipularea și gestionarea informațiilor analogice prezente în mediul înconjurator.

Apoi, în cea de-a doua parte, se face detalierea fiecărei componete atât individual cât și ca un sistem. Tot aici va fi realizata schema electronica, diferitele componente periferice folosite pentru funcționarea corecta a sistemului, limbajul de programare folosit, platforma de programare folosita, se va alege programatorul adecvat și bineînțeles microcontrolerul care are toate resursele interne necesare realizarii interfeței: memorie, porturi de intrare/ieșire, convertoare, porturi seriale, etc. toatea acestea detaliate și exemplificate.

Iar în partea treia, vom realiza, practic, o interfața între utilizator și microcontroler cu ajutorul unui display 2×16 hexazecimal folosind limbajul de programare în asamblare, iar ca mijloc de comunicare cu utilizatorul vom folosi o tastatura 4×4.

Această lucrare are ca scop familiarizarea cititorului cu funcțiile și capacitățile componentelor electronice exemplificate mai în sus. Vom detalia diferitele funcții pe care atât microcontrolerul PIC16F887 le posedă cât și componentele de input și output, afișajul AC-162B respectiv tastatura 4×4. Vom realiza o aplicație folosind aceste componente electronice și vom finaliza cu posibile îmbunătățiri ale sistemului.

Capitolul 1 – Considerente Teoretice

Aici vom studia apariția și evoluția interfețelor utilizator iar mai departe vom explora diferitele componente folosite în realizarea acestui proiect cat și un scurt istoric despre cum au fost ele concepute, cum au evoluat și cateva exemple de sisteme electronice populare din ziua de azi care au la bază una sau mai multe dintre aceste componente electronice, de o calitate și o complexitate mult mai ridicata, dar în același timp ele funcționeaza după aceleași principii de funcționare și realizeaza aceleași funcții ca și stramoși săi.

De exemplu in cazul microcontrolerelor principiile și modul de funcționare sunt aceleași cu modelele clasice doar că versiunile actuale conțin diferite îmbunătățiri la nivelul arhitecturi, conține un numar mai mare de locații de memorie, un numar mai mare de porturi de intrare ieșire, convertoare analog/digital sau digital/analog mai performante și mai numeroase, consum de putere mai scazuta, porturi de comunicare mai numeroase si mai convenabile, posibilitatea de integrare mai eficienta, etc.

1.1 Interfața cu utilizatorul:

Cand se vorbește de interacțiunea dintre om și sisteme electronice sau mecanice, interfața utilizator stă la bază, ea făcând posibilă interacționarea dintre om și sistem.

Scopul acestei comunicații este de a oferi utilizatorului control asupra proceselor hardware sau software care au loc intr-un sistem, iar in același timp de ai oferi acestuia feedback în legatura cu starea sistemului. Interfețele utilizator sunt folosite in diverse sisteme electronice sau mecanice de exemplu: sistemul de operare a unui calculator, computerul de bord a unei mașini, panoul de control a unei mașinari industriale, sisteme de aer condiționat și altele.

Interfața utilizator include componente fizice (hardware) și virtuale/logice (software) care oferă utilizatorului mijloace de:

Intrare (input), oferindu-i utilizatorului mijloace de a manipula sistemul.

Ieșire (output), sistemul oferindu-i informații utilizatorului despre efectele interacțiuni sale cu sistemul.

Scopul acestor interfețe este de a minimiza și simplifica procesul de interacționare cu sistemul, oferind utilizatorului o experiența mai placută și eficienta de comunicare cu sistemul. Pe scurt utilizatorul oferă interacțiune minimalista la intrare pentru a primi rezultatul dorit la ieșire cu un numar minim de erori sau rezultate nedorite.

Datorită avansurilor în dispozitive de tip electronic entertainment (calculatoare, telefoane smart, televizoare smart,etc) termenul de interfața utilizator, in general, se refera la interfața grafica (meniul) unui sistem de operare prezent în aceste dispozitive. În timp ce panouri de control industriale și mașinarii de control se refera la interfețe om-mașina. Alte denumiri includ interfață om-computer (human-computer interface HCI) și interfață om-mașina (man-machine interface MMI).

În procesul de proiectare a unei interfețe utilizator trebuie luat in considerare efortul pe care utilizatorul trebuie sa îl exercite pentru a realiza o operație și în același timp felul în care sistemul afișeaza rezultatele acestei operați.

Uzabilitatea este un lucru foarte important cand vine vorba de a proiecta un astfel de sistem. Uzabilitatea este o caractristica a unei interfețe utilizator prin care se arata gradul de eficientă și satisfacție pe care o astfel de interfața o prezintă utilizatorului. Pe scurt cu cat uzabilitatea unei interfețe utilizator este mai mare cresțe, de la sine, calitatea acesteia, utilizatorul reușind să opereze și să i se afișeze informația dorită într-un mod placut și eficient.

Capitolul 2 – Microcontrolerul

Microcontrolerul este unu dintre cele mai folosite dispozitive electronice de azi. Acesta fiind folosit în toate aplicațiile care au în compoziție un circuit electronic.Microcontrolerul este folosit în diverse aplicații în care este nevoie de un "creier" care are abilitatea de a gestiona și manipula informații provenite fie din mediul extern, aceasta formă de informație fiind denumita informație analogică, fie din interiorul circuitelor electronice, așa numita informație digitala.

În ciuda faptului ca acesta poate fi folosit la aproape orice, microcontrolerul este, de obicei, limitat la o singura sarcină specifica și bine definită.În același timp exista un alt dispozitiv electronic care este foarte asemanator microcontrolerului, în denumire și în funcționalitate, microprocesorul. Multă lume face confuzie între aceste doua dispozitive, ambi sunt facuți pentru aplicații în timp reali și au multe caracteritici asemanătoare dar în același timp sunt și foarte diferiți.Microcontrolerul și microprocesorul sunt circuite integrate și la prima vedere nu poți face distincția între aceștea pe plan vizual, ambi sunt disponibili în versiuni diferite începând de la versiuni cu 6 pini până la cele mai noi care au între 80 și 100 pini.

Arhitectura von Neumann:

Marea majoritate de microcontrolere sunt realizate pe baza acestei arhitecturi. Această arhitectură prezintă o unitate centrală de procesare sau CPU care are un singur spațiu de memorie comun folosit la memorarea atât codului instrucțiunilor cât și a variabilelor, datelor cu care vrem să lucrăm. În același timp magistrala internă este comună și este folosită la preluarea instrucțiunilor și a datelor; aceast mod de operare secvențial, are ca efect, încetinirea operațiilor. Această arhitectură este foarte des întâlnită și la microprocesoarele de uz general, doar că datorită vitezei lor de procesare superioare aceste microprocesoare produce iluzia numită multiprocesare.

Arhitectura Harvard:

Spre deosebire de arhitectura precedentă la aceasta există spații separate de memorie pentru codul program și date. Datorită acestui fapt și magistrala este multiplicată (o magistrală de adrese și una de date) pentru instrucțiuni și respectiv date. Astfel se poate realiza execuția în paralel a celor două operații. Instrucțiunile pot fi preluate din memorie în timp ce se execută operațiile cu datele instrucțiunii anterioare. Acest mod de lucru are ca rezultat mărirea (cel puțin teoretic) vitezei de execuție. Această arhitectură este folosită exclusiv de procesoarele de semnal. Deoarece costul mare, la microcontrolere se folosește o arhitectură Harvard modificată, cu spații separate de memorie pentru program și date, dar cu magistralele pentru adrese și date comune.

Conceptul CISC:

Conceptul CISC (Complex Instruction Set Computer) stă la baza realizării majoritatea CPU-urilor folosite de către microcontrolere. Acesta are la bază un set de peste 80 de instrucțiuni, multe dintre acestea foarte puternice și specializate. Aceste instrucțiuni sunt multe foarte diferite: unele pot lucra doar cu un anumit spațiu de memorie, pe când altele permit numai anumite moduri de adresare.

Conceptul RISC:

Aceste concept RISC (Reduced Instruction Set Computer) este conceptul de realizare a CPU-ului care a început recent timp să fie realizat cu succes și la realizarea microcontrolerelor. Acesta implică implementarea unui set redus de instrucțiuni având o execuție foarte rapidă și eficientă, datorită acestui fapt complexitatea microcircuitului este redusă.

2.1 Diferențele dintre Microcontroler și Microprocesor:

Microprocesorul este un circuit integrat în care este prezenta doar unitatea de procesare a datelor adică doar puterea brută de calcul.Amintim microprocesoare gen Intel Pentium 1,2,3,4, Core 2 duo, i3 , i5.Acestea nu au memorie RAM, ROM, sau alte elemente periferice.Ele trebuiesc adaugate într-un circuit și facută legatura cu unitatea de procesare.Aplicațiile pentru aceste dispozitive sunt în numar mic ele fiind folosite doar în calculatoare, laptopuri, smartphone, tablete, etc

În cazul microcontrolerelor situația este diferita, microcontrolerul are în interiorul circuitului integrat o unitate de procesare, sau CPU, o memorie RAM și ROM fixa și, dupa caz, diferite circuite periferice.Se poate spune că un microcontroler este un mini computer. Multe companii în ziua de azi produce microcontrolere cu diferite caracteristici, funcții și design. Câteva dintre aceștia sunt ATMEL, Microchip, TI, Motorola, etc.

Microcontrolerele sunt concepute pentru a îndeplini o singura sarcina bine definita, aici informația care este prezentă la intrarea sau ieșirea sistemului se afla între anumiți parametri. De exemplu dipozitive gen: tastaturi, mouse-uri, mașini de spălat, cuptoare cu microunde, autovehicule cu computer de bord, biciclete, telefoane, etc. toate aceste aplicații nu au nevoie de resurse vaste de memorie RAM, ROM sau porturi de intrare/ieșire (I/O), valoarea acestora rămânând aceași pe parcursul vieți produsului, acest lucru face posibil integrarea tuturor acestor funcții intr-un singur chip, scăzând prețul, dimensiunea și consumul de putere. Pe lânga toate acetea microcontrolerele opereaza la o frecvență de lucru relativ scazută de ordinul zecilor de MHz.

Microprocesoarele pe de alta parte sunt unitați centrale der în calculatoare, laptopuri, smartphone, tablete, etc

În cazul microcontrolerelor situația este diferita, microcontrolerul are în interiorul circuitului integrat o unitate de procesare, sau CPU, o memorie RAM și ROM fixa și, dupa caz, diferite circuite periferice.Se poate spune că un microcontroler este un mini computer. Multe companii în ziua de azi produce microcontrolere cu diferite caracteristici, funcții și design. Câteva dintre aceștia sunt ATMEL, Microchip, TI, Motorola, etc.

Microcontrolerele sunt concepute pentru a îndeplini o singura sarcina bine definita, aici informația care este prezentă la intrarea sau ieșirea sistemului se afla între anumiți parametri. De exemplu dipozitive gen: tastaturi, mouse-uri, mașini de spălat, cuptoare cu microunde, autovehicule cu computer de bord, biciclete, telefoane, etc. toate aceste aplicații nu au nevoie de resurse vaste de memorie RAM, ROM sau porturi de intrare/ieșire (I/O), valoarea acestora rămânând aceași pe parcursul vieți produsului, acest lucru face posibil integrarea tuturor acestor funcții intr-un singur chip, scăzând prețul, dimensiunea și consumul de putere. Pe lânga toate acetea microcontrolerele opereaza la o frecvență de lucru relativ scazută de ordinul zecilor de MHz.

Microprocesoarele pe de alta parte sunt unitați centrale de calcul (CPU) cu o putere de procesare mult mai mare și frecvențe de ordinul GHz și datorită aplicațiilor în care sunt folosite microprocesoarele gen: dezvoltare de aplicații software, jocuri video, creerea și editarea paginilor web, editarea video-audio, editare photo, scrierea diferitelor tipuri de documente, etc. acestea necesită și o cantitate mare de memorie RAM, ROM, porturi I/O, etc. Dacă luăm în considerare doar microprocesorul fără celelalte componente periferice dimensiunea acestuia în comparație cu cel al unui microprocesor este mai scazut.

Nu este corect să-i comparăm pe aceștia la nivel de preț. Bineînțeles că microcontrolerul este cu mult mai ieftin decat un microprocesor. Dar un microcontroler nu poate fi foloisit în locul unui microprocesor și daca folosim un microprocesor în locul unui microcontroler este nefiabil, crescând costul aplicației explonențial și se risipesc resurse de calcul și memorie. Microprocesorul nu poate funcționa în lipsa componentelor periferice gen: memorii RAM, ROM, porturi I/O, etc. deci un astfel de sistem construit în jurul unui microprocesor este foarte costisitor.

O altă diferentă între acestea este limbajul de programare folosit pentru instruirea comenzilor pe aceste dispozitive. Limbajul de programare cel mai des foloit la programarea instructiunilor unui microprocesor este C++ acesta este folosit și înteles de catre orice microprocesor și mai nou este folosit la programarea microcontrolerelor. Acest limbaj este simplu de înteles și folosit de catre un programator și nu necesita cunoașterea arhitecturi internă a integratului.

Dezavantajul acestuia constă în creerea unor programe mari care necesită o cantitate de memorie semnificativă. Un alt dezavantaj mare este folosirea diferitelor librarii și funcții generale care nu sunt optimizate pentru o aplicație specifică, acest fapt duce la nevoia de o putere mai mare de calcul. De aceea acest limbaj este folosit la programarea microproceoarelor, acestea avand o putere de procesare și o cantitate de memorie mai mare.

În cazul micontrolerelor, de multe ori, este preferat să se folosească limbajul de asamblare, acesta fiind un limbaj care folosește manipularea directă a informației la nivel de bit. Acest limbaj de programare este mult mai eficient, instrucțiunile fiind directe și simple pentru microcontroler, iar acest lucru duce la o reducere a dimensiuni și a puteri de calcul necesară rulări instrucțiunilor.

Dezavantajul acestui limbaj constă în dificultatea întelegerii limbajului de catre programator și flexibilitatea redusă. Intrucțiunile acestui limbaj nu sunt aceleași pentru fiecare microcontroler, acestea sunt dependente de arhitectectura aleasă de catre producător. De exemplu un microcontroler din familia 16FXXX va avea dificultăți în a înțelege un program realizat pe baza arhitecturi unui microcontroler din familia 12FXXX. Deci chiar daca instrucțiunile sunt aceleași, locațiile de memorie, porturile de I/O, convertori analog/digital sau digital/analog, oscilatorul inter sau extern, generatorul PWM, locațiile de memorie RAM, ROM, etc. sunt așezați diferit în fiecare microcontroler așa că programatorul are nevoie de o cunoaștere detaliată a arhitecturi interne, pe care o poate afla studiind foile de catalog (datasheet) a microcontrolerului.

2.2 Memoria:

În lumea dispozitivelor electronice există două feluri de memorii:

RAM – Random access memory

ROM – Read-only memory

Memoria ROM este o forma de memorie folosită în computere și alte dispozitive electronice care nu poate fii alterată sau reprogramată ușor. Aceasta este o memorie nevolatilă, adică informația stocată în această formă nu se pierde la întreruperea alimentării cu curent electric a dispozitivului, acest tip de memorie se mai numește memorie permanenta.

Această memorie are o viteză relativ mică comparativ cu cea RAM iar cantitatea folosită la conceperea unui dispozitiv este scazută, deoarece ea este folosită doar pentru a stoca informația necesară în momentul inițializării dispozitivului și când vine vorba de preț de producție este și mai costisitoare ca cea RAM. Memoriile ROM sunt, în esență, circuite integrate preprogramate care conțin informația de boot a dispozitivului și este dificil, chiar imposibil în unele cazuri, să fie alterate. Principalele tipuri de memorii ROM sunt: Masked ROM, PROM, EPROM, EEPROM, Flash și NVRAM.

Memoria RAM este o formă de stocare a datelor care poate fi accesată în mod aleator, oricând, în orice ordine și independent de locația fizică la un moment dat spre deosebire de alte dispozitive de stocare, gen hard disk-uri, unde locația fizică a informației stocate determină timpul de recuperare a informației. Aceast tip de memorie este volatilă, adică la momentul întreruperii alimentării dispozitivului, informația stocată în memoria RAM este pierdută, se mai numește și memorie temporară.

Această memorie are o viteză superioară față de ROM, dimensiunile sunt de ordinul megabytes pâna la câtiva gigabytes la computerele din ziua de azi, iar viteza de acessare este masurată în nanosecunde. Cantitatea mare de memorie RAM este necesară deoarece este folosită la rularea multor aplicații, în același timp, acest lucru necesitând o cantitate de memorie și o viteză de citire ridicată. Spre deosebire de memoria ROM, memoria RAM are doar două tipuri: Static RAM (SRAM) și Dynamic RAM (DRAM).

2.2.1 Diferitele tipuri de memorii RAM:

Memoria de tip RAM este de două feluri: static RAM (SRAM) și dynamic RAM (DRAM). În essență cele două tipuri se deosebesc din punct de vedere a duratei de viață a informației stocate pe ele. Memoria statică își reține informația stocată pe aceasta până la întreruperea alimentării, dacă alimentarea dispozitivului este întreruptă chiar și pentru o clipă informația este pierdută. DRAM, pe de altă parte, are o durată de viață extrem de scurtă, în jur de patru milisecunde, acest lucru chiar și în cazul în care alimentarea nu este întreruptă.

Pe scurt, SRAM are toate caracteristicile memoriei RAM, pe când DRAM este nefolositoare de una singură, dar, un dispozitiv hardware numit DRAM controller poate fi folosit în concordanță cu memoria DRAM pentru a funcționa ca și o memorie SRAM. Acest lucru se realizeaza prin reîmprospătarea informației înainte ca aceasta să expire, astfel informația este stocată în memoria DRAM cât timp este nevoie.

Când se alege tipul de RAM folosit, trebuie luat în considerare timpul de acces și costul. SRAM este extrem de rapid (aproximativ de patru ori mai rapid decât DRAM) dar viteza impresionată duce și la un cost ridicat. De obicei, SRAM este foloit în cantități mici și numai în aplicațiile care necesită o viteză de acces rapidă. Datorită costului pe byte scăzut al memoriei DRAM, această memorie este foarte atrăgătoare când avem nevoie de cantități mari de memorie dar viteză de acces moderată. Astfel multe sisteme folosesc ambele tipuri de memorii: un block mic de memorie statică (de ordinul kilobytes) pentru a servii aplicații critice care au nevoie de o viteză cât mai mare și un bloc de memorie dinamică, mult mai mare (megabytes) pentru toate celelalte aplicații.

2.2.2 Diferitele tipuri de memorii ROM:

Memoriile ROM se deosebesc între ele dupa metodele folosite pentru a scrie date pe acestea, alftel spus metodele de programare, și după numarul de rescrieri posibile. Această descriere arată evoluția memoriilor ROM de la dispozitive preprogramate hard la programabile cu ajutorul unor dispozitive electronice la memorii care pot fi șterse apoi reprogramate. Dar, toate acestea au un factor comun între ele, abilitatea de a reține informația permanent, chiar și la o întrerupere a alimentării.

Printre primele memorii de tip ROM au fost cele preprogramate hard, unde un set de instrucțiuni, specifice chipului respectiv, trebuia știut chiar înainte de procesul de producție a circuitului pentru ca tranzistorii din interiorul memorie să poată fii aranjați într-o anumită ordine. Acest tip de memorii se mai folosesc și azi, doar că pentru a se putea face o deosebire între acestea și alte memorii ROM ele au luat denumirea de Masked ROM. Motivul pentru care aceste memorii sunt încă folosite azi este prețul scazut de producție când este produs în cantități mari.

Urmând evoluția acestor memorii se trece de la Masked ROM la o memorie programabilă numită PROM (programmable ROM). Memoria PROM, după producție, este într-o stare neprogramată, toate locațiile de memorie fiind setate pe 1 logic. Procesul de programare a acestui chip este făcut cu ajutorul unui echipament special numit programator. Programatorul scrie informația pe chip cuvânt cu cuvânt prin aplicarea unei tensiuni electrice la pini de intrea a integratului. Memoria odată programată nu mai poate fi modificată. Dacă este nevoie de a se modifica informația stocată pe o memorie PROM singura cale este de a se înlocui cu una nouă. Aceste memorii se mai numesc și one-time programmable devices.

Mai târziu apare memoria EPROM (erasable-and-programmable ROM). Acest tip de memorie este programată la fel ca și cea PROM, doar că aceasta odată scrisă are și proprietatea de a se modifica informația stocată, fără a fi nevoie de a se înlocui. Dispozitivul prezintă o mică deschizatură în partea de sus a chipului prin care lumina poate să ajungă la silicon, prin expunerea acestuia la un impuls puternic cu raze ultraviolete informația stocată este readusă în starea initială de după producție. Chiar dacă prețul acestora este mult mai ridicat decât cel al predecesorii lor, abilitatea de a fi reprogramate face ca memoriile EPROM să fie o parte esențială a proceselor de testare și dezvoltare software.

2.2.3 Memoriile Hibrid:

Cu trecerea timpului și evoluția firească a tehnologiei, linia dintre memoria RAM si ROM a devenit din ce în ce mai ștearsă. Acum, există memorii care încorporează trăsături prezente în ambele tipuri de memorii discutate.

Acestea, chiar dacă au caracteristici aparținând ambelor grupuri ele nu se încadrează în nici una, ele fiind cunoscute drept memorii hibrid. Memoriile hibrid pot fi scrise și cititte, ca și cele RAM, dar își mențin informația stocată și în lipsa alimentări cu curent electric, trăsătura specifică memoriilor ROM. Două dintre aceste memorii hibride, EEPROM și flash, sunt descendenți ai memoriilor ROM, acestea fiind folosite pentru a stoca memoria program.

EEPROM vine de la electrically-erasable-and-programmable ROM. În interior acestea sunt asemănătoare cu arhitectura memoriilor EPROM, doar că procesul de resetare, sau ștergere, a informației stocate este realizată electric. Orice octet din interiorul memoriei EEPROM poate fi șters și rescris, iar acesta odată scris rămâne în această stare definitiv, sau până se dorește modificarea acestuia de către programator.

Această abilitate de a putea șterge și rescrie memoria aduce cu ea și costul mult mai ridicat, iar odată cu acesta și un ciclu de scirere mai lent, astfel nu este recomandat să se folosească acest tip de memorie ca și memoria principală a unui sistem.

Memoria Flash combină cele mai bune caracteristici ale memoriilor prezentate până acum. Aceste memorii au o densitate mare, cost scăzut, sunt nevolatile, viteza de citire este superioară și sunt reprogramabile electronic.

Aceste avantaje impresionate au ca rezultat o creștere dramatică în sisteme integrate care folosec memorii de tip flash ca memorie de program a sistemului. Din punct de vedere software acestea sunt foarte asemănătoare cu cele EEPROM, singura diferentă este că informația scrisă în memoriile flash nu poate fi ștearșa la nivel de octet, ștergerea informației se realizează prin sectoare de octeți.

Un astfel de sector, de obicei, are dimensiunea de la 256 de octeți până la 16 kilo-octeți. În ciuda acestui dezavantaj memoriile de tip flash sunt mult mai populare ca cele EEPROM iar datorită nenumeratelor funcții pe care acestea le livrează multe dintre dispozitivele care folosesc memoriile precedente sunt scos din uz.

Cel de-al treilea membru al familiei hibride este memoria NVRAM (non-volatile RAM). După denumire se observă caracteristica nevolatilă care după cum știm este o caracteristică memoriilor ROM. Doar că NVRAM este, în esență, o memorie SRAM cu o baterie. Când aceasta este alimentată, memoria NVRAM operează în același fel ca și o memorie SRAM. Dar când alimentarea este întreruptă, aceasta se alimentează de la baterie iar astfel poate reține informația stocată.

Aceste memorii sunt destul de comune în sistemele integrate, dar din cauza bateriei acestea sunt foarte scumpe. Din acest motiv ele sunt folosite la stocarea câtorva sute de octeți de informație critică sistemului, informație care nu se poate stoca altfel.

În tabelul 2.2.1 se prezintă o comparație, pe scurt, al caracteristicilor și al funcțiilor prezente în memoriile discutate mai în sus. Trebuie luat aminte că diferite tipuri de memorii servesc diferite sarcini, în momentul conceperii unui sistem un proiectant trebuie să i-a în considerare nu doar viteza sau dimensiunea unei memorii, ci și costul și flexibilitatea acesteia cât și rolul pe care aceasta trebuie s-ăl îndeplinească în sistem.

Tabel 2.2.1 Caracteristici și funcții ale diferitelor tipuri de memorii

În trecut am facut referință la două tipuri de memorii folosite într-un microcontroler și anume: memoria program și memoria de date.

În memoria program sunt stocate instrucțiunile și funcțiile preprogramate de producător.

Această memorie se poate doar citi, de către programator deoarece prezintă un mecanism de protecție la citire, deci face parte din familia memoriilor ROM, este nevolatilă și dificil, chiar imposibil în unele cazuri de a fi modificat. În memoria program nu se pot stoca variabile sau alte informații care se pot modifica în timp, în unele cazuri se pot stoca constante.

Memoria program are dimensiuni mici și conține instrucțiuni bine gândite și optimizate pentru arhitectura sistemului.

Datorită naturii schimbătoare ale variabilelor prezența acestora în memoria program ar duce la eronarea aplicației, motiv pentru care acestea sunt stocate în memoria de date.

Memoria de date este memoria de uz general, ea conține variabile și informații cu privire la configurarea dispozitivelor periferice, al oscilatorilor interni și externi, al porturilor de intrare/ieșire, etc. Această memorie este de tip RAM, este volatilă și se poate scrie și citi cu ușurință.

Datorită acestor aspecte stocarea informațiilor instabile, supuse schimbări este de preferat pe memoria de date. În această memorie este prezent un numar mare de registre de uz general pe care se pot stoca date gen variabile, constante, etc. și de asemenea sunt prezenți și câtiva regitri cu funcții speciale, care sunt folosiți pentru a configura microcontrolerul și modulele sale specializate și pentru a seta modul lor de funcționare.

Arhitectura acestor memorii este prezentată în figura 2.2.1 de mai jos

0x000 0x0000

0x001F

0x0020

0x005F

0x0060

0x025F

0x0260

0xFFF 0xFFFF

Figura 2.2.1 Arhitectura memoriei program și a memoriei de date

Atât memoria program cât și memoria de date comunică cu circuitele periferice printr-o magistrală de date.

Spre deosebire de circuitele de procesare a semnalelor DSP (Digital Signal Processor) care au câte o magistrală pentru fiecare memorie, la microcontrolere este prezentă doar o singură magistrală prin care comunică atât memoria program cât și memoria de date.

Această arhitectură este cunoscută drept arhitectura Harvard modificată și este preferată deoarece costul implementării acestei arhitecturi este mai scăzut față de cel al arhitecturii Harvart folosită la DSP-uri.

2.3 Regiștri prezenți în microcontrolerul PIC16F887:

Memoria de date este organizată în patru bancuri de registre. Fiecare banc de registre conține 127 de locații de memorie. Doar un singur banc de registre poate fi activ la un moment dat.

Figura 2.3.1 Structura regiștrilor speciali ale microcontrolerului PIC16F887 [4]

2.3.1 Registrul STATUS:

Registrul STATUS conține informații referitoare la starea unității aritmetice și logice ALU (Z, DC, C, etc.). Acest registru mai conține și o serie de biți cu care se poate face selectarea fie directă, prin setarea sau resetarea biților RP0 și RP1, fie indirect prin setarea sau resetarea bitului IRP al registrului.

Registrul STATUS este umpic diferit față de alți regiștri, deoarece conține biți Z, DC și C. De exemplu dacă se folosește comanda CLRF STATUS pentru a se reseta toți biți registrului, primi trei biți vor fi resetați și bitul Z va fi setat, registrul STATUS va avea astfel valoarea în binar '000uu1uu' (u = neschimbat). De aceea atunci când se face setarea respectiv resetarea biților registrului STATUS este recomandat să se folosească comenzi care modifică valoarea individuală a biților gen: BCF, BSF, SWAPF, MOVWF.

Structura acestui registru arată astfel:

Figura 2.3.2 Structura registrului STATUS al microcontrolerului PIC16F887 [4]

IRP: registrul de selectare indirectă a bancurilor. Odată cu setarea sau resetarea acestui bit se face selectarea a două bancuri de registre:

1 – Bancurile 2, 3 sunt selectați

0 – Bancurile 0, 1 sunt selectați

Selectarea individuală a bancurilor se face prin setarea sau resetarea biților RP0 și RP1 ai registrului status. Selectarea bancurilor cu ajutorul acestora se face astfel:

Tabelul 2.3.1 Selectarea bancurilor de regiștri cu ajutorul biților RP0 și RP1 [4]

– Bitul de time-out.

– Bitul de power-down

Z – Bitul de zero:

1 – Rezultatul unei operații aritmetice sau logice este zero.

0 – Rezultatul unei operații aritmetice sau logice este diferit de zero.

DC – Bitul de Carry respectiv Borrow Digit

C – Bitul de Carry/ . Deoarece microcontrolerul are arhitectura bazată pe 8 biți un cuvânt mai mare de 8 biți normal nu ar putea fi stocat și informația s-ar pierde. Astfel când rezultatul unei operații aritmetice sau logice depășește 8 biți rezultatul va fi transmis pe 8 biți mai departe, iar bitul în plus va fi stocat în bitul Carry/:

1 – Un bit în plus a rezultat dintr-o operație aritmetică sau logică.

0 – Nu a apărut un bit în plus după o operație aritmetică sau logică

2.3.2 Registrul OSCCON (Oscillator Control):

Acest registru este folosit pentru a seta oscilatorul și frecvența de clock a microcontrolerului. Microcontrolerul are un oscilator intern care poate fi setat să opereze la frecvențe între 31 kHZ și 8 MHz, sau se poate folosi un oscilator extern cu cristal de cuarț dacă se dorește frecvențe mai ridicate. Structura biților acestui registru arată astfel:

Structura acestui registru arată astfel:

Figura 2.3.3 Structura registrului OSCCON al microcontrolerului PIC16F887 [4]

IRCF<2:0> : Biți de selectare a frecvenței oscilatorului intern

Tabelul 2.3.2 Selectarea frecvenței de oscilație a oscilatorului intern [4]

OSTS: Bitul de status al oscilatorului:

1 – Microcontrolerul operează pe baza biților FOSC<2:0> ai registrului CONFIG1.

0 – Microcontrolerul funcționeaza la frecvența oscilatorului intern.

HTS: Bitul de status al oscilatorului intern când acesta funcționează la frecventă înaltă sau HFINTOSC ( între 8 MHz și 125 kHz):

1 – HFINTOSC este stabil.

0 – HFINTOSC nu este stabil.

LTS: Bitul de status al oscilatorului intern când acesta funcționează la frecventă joasă sau LFINTOSC ( 31 kHz):

1 – LFINTOSC este stabil.

0 – LFINTOSC nu este stabil.

SCS: Bitul de selectare al frecvenței de clock:

1 – Oscilatorul intern este folosit pentru a defini frecvența de clock a sistemului.

0 – Frecvența de clock este definită după starea biților FOSC<2:0> ai registrului CONFIG1.

2.3.3 Registrul ANSELH:

Registrul ANSELH este un registru de configurare a porților din grupa B. Prin setarea sau resetare acestui registru se face trecerea de la un pin de intrare/ieșire digital la operarea acestuia în mod analog. Dacă setăm unul din biți registrului ANSELH atunci pinul care corespunde acelui bit va opera ca un pin analogic. Dacă resetăm unul din biți, atunci pinul corespunzător va funcționa ca un pin de intrare/ieșire.

Trebuie menționat faptul că, dacă un pin are bitul TRIS resetat și bitul ANSELH setat acesta va funcționa ca un pin de ieșire digitală, dar daca este folosit ca pin de intrare va fi funcționa în mod analog. Acest lucru poate cauza erori la scrierea sau citirea instrucțiunilor. Structura acestui registru arată astfel:

Figura 2.3.4 Structura registrului ANSELH al microcontrolerului PIC16F887 [4]

ANS<13:8> Biți de setare a modului de funcționare analog:

1 – Pini funcționează ca intrări analogice.

0 – Pini funcționează ca pini de intrare/ieșire digitali

Observație: setarea unui pin ca intrare analogică va dezactiva automat circuitul de intrare digital, modul de funcționare cu intrerupere la schimbare și funcția de weak pull-up.

2.3.4 Registrul TRISB:

Registrul TRISB configurează directivitatea pinilor din grupa B. Astfel dacă un bit ai registrului TRISB este setat atunci pinul corespunzător registrului PORTB devine pin de intrare (adică driver-ul său de ieșire este în impedanță înaltă), iar resetarea unui bit va face ca pinul corespunzător să funcționeze ca pin de ieșire.

Registrul TRISB controlează driverele pinilor de ieșire ai registrului PORTB chiar și în cazul în care pini sunt folosiți ca pini de intrare analogice. Este foarte important ca biți registrului TRISB să fie setați când aceștia sunt folosiți ca pini de intrare analogice, deoarece la citire acesta va arăta tot timpu '0'.

Structura acestui registru arată astfel:

Figura 2.3.5 Structura registrului TRISB al microcontrolerului PIC16F887 [4]

TRISB<7:0> Biți de control a directivități portului B:

1 – Pini PORTB sunt intrări.

0 – Pini PORTB sunt ieșiri.

2.3.5 Registrul PORTB:

PortB este un port bidirecțional pe 8 biți. Adică poate fi configurat ca port de intrare sau de ieșire. Când se face citirea unui bit din registrul PORTB se citește chiar valoarea de pe pinul corespunzător. Scrierea se realizează mai întâi prin citirea valorii pinului, apoi se modifică valoarea acesteia. Astfel toate operațiile de scriere sunt de tip citire-modificare-scriere.

Pini PORTB mai are câteva funcții speciale, fiecare funcție având și ea un registru special de configurare. Funcțiile speciale ale acestora sunt: funcția de întrerupere la schimbare și optiunea de weak pull-up.

Structura acestui registru arată astfel:

Figura 2.3.6 Structura registrului PORTB al microcontrolerului PIC16F887 [4]

PORTB<7:0> Biți de configurare a pinilor de intrare/ieșire ale lui PORTB

1 – Pinul este în 1 logic

0 – Pinul este în 0 logic

2.3.6 Registrul IOCB (Interrupt-on-change):

Pini de la PORTB se pot configura fiecare independent unul de altul pentru a funcționa ca un pin cu întrerupere-la-schimbare. Biți de control IOCB<7:0> poate activa sau dezactiva această funcție.

Această funcție se realizează prin compararea valorii prezente la un moment dat cu o valoare citită ultima dată al pinului respectiv. Apoi se face o operație logică ȘI între această valoare și valoarea unui bit special de întrerupere la schimbare RBIF ai registrului INTCON.

Dacă operația ȘI are ca rezultat final 1 logic se realizează o întrerupere. Această întrerupere se poate programa să fie: o funcție, o trezire a dispozitivului, o subrutină, un delay, etc.

Structura acestui registru arată astfel:

Figura 2.3.7 Structura registrului IOCB al microcontrolerului PIC16F887 [4]

IOCB<7:0> Biți de configurare a funcției de întrerupere-la-schimbare al lui PORTB

1 – Funcția de întrerupere-la-schimbare este activată.

0 – Funcția de întrerupere-la-schimbare este dezactivată.

2.3.7 Registrul ANSEL:

Registrul ANSEL este un registru de configurare a porților din grupa A. În același fel ca și la registrul ANSELH setarea sau resetare acestui registru face trecerea de la un pin de intrare/ieșire digital la operarea pinului respectiv în mod analog.

Structura acestui registru arată astfel:

Figura 2.3.8 Structura registrului ANSEL al microcontrolerului PIC16F887 [4]

ANS<13:8> Biți de setare a modului de funcționare analog:

1 – Pini funcționează ca intrări analogice.

0 – Pini funcționează ca pini de intrare/ieșire digitali

2.3.8 Registrul TRISA:

Registrul TRISA configurează directivitatea pinilor din grupa A. La fel ca și la registrul TRISB dacă un bit ai registrului TRISA este setat atunci pinul corespunzător registrului PORTA devine pin de intrare, iar resetarea unui bit va face ca pinul corespunzător să funcționeze ca pin de ieșire.

Structura acestui registru arată astfel:

Figura 2.3.9 Structura registrului TRISA al microcontrolerului PIC16F887 [4]

TRISA<7:0> Biți de control a directivități portului A:

1 – Pini PORTA sunt intrări.

0 – Pini PORTA sunt ieșiri.

2.3.9 Registrul PORTA:

PORTA este un port bidirecțional pe 8 biți. În același fel ca și la PORTB rezultatul citiri unuia din biți portului este chiar valoarea logică de pe acel pin.

Structura acestui registru arată astfel:

Figura 2.3.10 Structura registrului PORTA al microcontrolerului PIC16F887 [4]

PORTA<7:0> Biți de configurare a pinilor de intrare/ieșire ale lui PORTA

1 – Pinul este în 1 logic.

0 – Pinul este în 0 logic.

Capitolul 3 – Programarea Microcontrolerului

3.1 MPLAB IDE:

MPLAB IDE este un software de editare, gestionare, compilare și programare a instrucțiunilor unui microcontroler. Acest software are un editor de text unde se poate scrie instrucțiuni în diferite limbaje de programare gen C++, limbaj de asamblare,etc. ca apoi aceste instrucțiuni să poată fi compilate și programate într-un microcontroler printr-un dispozitiv special numit programator.

Programul conține și o înterfață simplă bazată pe un spațiu de lucru (workspace) unde utilizatorul poate gestiona diferite fișiere sursă și poate face legătura între ele într-un mod ușor și logic.Apelarea acestor fișiere sursă se face cu instrucțiunea:

#include <numele fișierului.inc>

La întâlnirea acestei comenzi programul va executa instrucțiunile prezente în interiorul fișierului, iar apoi va continua programul principal de unde a rămas.

Această comandă este folosită cand vrem să reținem un spațiu de memorie pentru o variabilă pe care o denumim noi. În cazul de mai sus numele variabilei este D1 iar cu comanda RES 1 vom reserva o locație de memorie. Funcția UDATA_SHR indică faptul ca această variabilă va fi stocată într-un spațiu de memorie comun, putând fi accesat mai ușor la nevoie.

3.1.1 Comenzi de manipulare a biților:

Comanda BANKSEL

Aceasă comandă face selecția bancului corespunzător registrului pe care vrem să il accesăm, un lucru care normal necesită configurarea biților RP1 și RP0 ai registrului STATUS.

Comanda MOVLW și MOVWF:

Comanda MOVLW mută valoarea unei constante predefinite L, care în cazul de sus este B'11110000', în registrul de lucru W.

Comanda MOVWF mută valoarea prezentă în registrul de lucru W în registrul F care este definit de utilizator, în cazul de sus acesta este TRISD.

Comanda CLRF și COMF:

Comanda CLRF este folosită pentru a seta toți biți unui registru pe 0 logic.

Comanda COMF este folosită pentru a inversa valoare tuturor biților registrului. Dacă biți unui registru sunt în 1 logic comanda va trece biți respectivi în 0 logic.

Comanda ORG:

Această comanda este folosită pentru a organiza memoria. Prin această comandă instruim microcontrolerul că vrem ca funcția START să fie stocată începând de la locația de memorie 0x05.

Comanda GOTO și CALL:

Comanda GOTO este folosită pentru a sări de la o funcție la alta. Mai în jos avem un exemplu de un salt folosind comanda GOTO la o funcție de întârziere.

Comanda CALL face aproximativ același lucru ca și comanda GOTO doar că după ce funcția este executată se face întoarcerea înapoi la momentul saltului prin comanda RETURN. Această întoarcere este necesară pentru a evita posibile erori

Comenzile DECF, INCF, DECFSZ, INCFSZ:

Comanda DECF i-a valoarea stocată în spațiul de memorie D1 o decrementează cu 1 iar apoi valoarea noua o salvează înapoi în D1.

Comanda INCF face același lucru ca și comada DECF doar că aceasta face o incrementare cu 1 a valorii prezente în D1.

Comanda DECFSZ face o decrementare al lui D1, salvează valoare în spațiul de memorie D1, iar apoi verifică daca valoarea este 0. Dacă valoarea este 0 se trece peste următoarea instrucțiune.

Comanda INCFSZ este echivalentă cu comanda DECFSZ doar că în loc de o decrementare se realizează o incrementare.

Comenzile BCF, BSF, BTFSC, BTFSS:

Comanda BCF schimbă valoarea bitului unui registru, în cazul nostru pinul RB5 de pe portul B, în valoarea 0.

Comanda BSF face același lucru doar că valoare pinului va fi setat ca 1 logic.

Comanda BTFSC verifică valoarea pinului, în cazul figurii de mai jos este vorba de portul RD6 ai portului D. Dacă valoarea este 0 atunci programul va sării peste următoarea instrucțiune.

Comanda BTFSS face același lucru ca și cea precedentă doar că saltul se realizează doar dacă valoarea pinului este în 1 logic.

3.2 PICKit 2:

PicKit 2 este un programator simplu și la un cost redus. Este capabil de a programa o mare parte din microcontrolerele de la firma Microchip, cât și o serie largă de dispozitive seriale EEPROM.

Un programator este necesar pentru a putea face legătura dintre calculator și microcontroler. Acesta trimite informația scrisă și convertită în limbajul de bază folosit de microcontroler către memoria program a microcontrolerului.

Acest dispozitiv poate nu doar să scrie un program în memorie, ci să și steargă sau să citească instrucțiunile scrise în memoria microcontrolerului.

Legătura cu calculatorul este făcut printr-un cablu USB și un software specializat pentru realizarea diferitelor operații.

În figura următoare avem prezentați pini dispozitivului:

Figura 3.2.1 Diagrama pinilor programatorului PICkit 2 [5]

Pinul 4 este pinul prin care se realizează transferul de date dintre dispozitiv și microcontroler.

Pinul 5 este pinul de clock prin care se realizează sincronizarea frecvenței de clock a dispozitivului cu cea a microcontrolerului.

3.2.1 Programarea ICSP:

Pentru a seta dispozitivul în modul de programare/verificare, mai întâi se face o resetare prin trecerea pinilor ICSPCLK și ICSPDAT în 0 logic și pinul în 1 logic. După resetare se trimite o comandă pe 6-biți urmată de 14 biți de date de program. Dacă comanda a fost de tip Load atunci cei 14 biți vor fi trimiși de la Pickit la microcontroler, dacă comanda a fost de tip Read atunci 14 biți de date de program vor fi transferați de la microcontroler la Pickit.

Această facilitate le permite utilizatorilor să construiască un circuit cu un microcontroler neprogramat, iar apoi să il programeze, putând oricând să modifice programul.

Software-ul care vine odată cu acest dispozitiv poate realiza o multitudine de operații cum ar fi:

Read Device – citește memoria program, datele prezente în memoria EEPROM, biți de configurare și locația adreselor.

Write Device – realizează scrierea memoriei program, a datelor memoriei EEPROM, a biților de configurare și locația adreselor.

Verify – citește și compara instrucțiunile prezente în memoria program, cu cele scrise de către utilizator care sunt prezente în softwarul de programare ales de către utilizator.

Erase – șterge instrucțiunile prezente în memoria microcontrolerului.

Blank Check – verifică dacă memoria microcontrolerului este goală.

Verify on Write – dacă activat programatorul va face o verificare automață a datelor după orice scriere.

Write on PICkit Button – odață activat, la apăsarea butonului roșu de pe dispozitiv se va realiza operația de scriere.

Capitolul 4 – Componentele de intrare/ieșire

4.1 LCD display AC-162B:

Unul dintre cele mai importante lucruri în ziua de azi când este vorba de creerea unui dispozitiv electronic este feedback-ul circuitului. Circuitele electronice au o parte ascunsă care numai proiectantul o știe și o parte vizibilă utilizatorului. Această parte poate fi realizată prin diferite metode: sonor prin sunete de avertizare, tactil prin vibrații sau vizual prin folosirea unor dispozitive numite display sau afișaj.

Aceste dispozitive informează utilizatorul despre ce se întâmplă în interiorul circuitului. Complexitatea unui display variază de la un simplu led, care se aprinde când un buton este apăsat, până la afișaje cu touch-screen care poate să ne informeze despre zeci de evenimente care se întâmplă nu doar în dispozitiv ci și în lumea reală.

Figura 4.1.1 Diagrama bloc a afișajului AC-162B [6]

Un exemplu de afișaj îl avem în figura de mai sus, acesta este un afișaj cu 2 lini și 16 coloane (2×16). În figură sunt prezentați controlerele pentru gestionarea impulsurilor aflate la pini, ecranul afișajului, circuitul de backlight cât și liniile de legătură prin care trec datele.

În tabelul de mai jos avem prezentați pini afișajului împreună cu funcția și valorile pe care acestea le poate lua, cât și simbolul asociat acestora.

Tabel 4.1.1 Semnificația pinilor afișajului AC-162B [6]

Pini 1, 2 (VSS, VDD) respectiv 15, 16 (A, K) sunt folosiți pentru alimentarea afișajului și a led-ului de backlight. Pinul 3 (V0) este folosit pentru ajustarea contrastului, aici se recomandă folosirea unui potențiometru sau se poate pur și simplu lega la masă pentru un contrast maxim.

Pini <7:14> (DB0:DB7) sunt pini prin care se transmite comenzile sau caracterele de 8-biți. Fiecare pin reprezentând unul din cei 8-biți ai unei comenzi. DB0 fiind cel mai puțin semnificativ bit, iar DB7 cel mai semnificativ bit al comenzi.

Pinul 4 (RS) este bitul de selectare a registrului care face tranziția dintre comandă și caracter. Dacă acest bit este în 0 logic atunci afișajul va executa o comanda, iar daca este în 1 logic atunci afișajul va afișa un caracter.

Pinul 5 (R/W) este bitul de Read/Write. Cu ajutorul acestui pin afișajul poate să treacă din modul de scriere în modul de citire și invers. Dacă valoarea acestuia este 0 atunci afișajul este în modul de scriere, iar la valoarea 1 logic afișajul va trece în modul de citire.

Pinul 6 (E) este bitul de validare a unei comenzi. La momentul treceri acesteia în 1 logic afișajul va executa comanda sau va afișa caracterul echivalent cu valoarea prezentă la pini de date (DB0:DB7).

În tabelul de mai jos avem toate comenzile pe care afișajul nostru poate să le execute cât și combinația de biți necesari efectuării unei instrucțiuni specifice.

Un lucru important de menținut este că aceste comenzi sunt valabile doar când afișajul folosește toți cei 8 pini de date.

Tabel 4.1.2 Tabelul cu instrucțiunile afișajului AC-162B [6]

Instrucțiunea Clear Display: șterge toate caracterele prezente pe ecran și setează atât poziția ecranului cât și cursorul pe poziția inițială de pe randul 1 coloana 1.

Instrucțiunea Return Home: face practic același lucru ca și comanda precedentă doar că, caracterele de pe ecranul afișajului rămân neschimbate.

Intrucțiunea Entry Mode Set: setează direcția de deplasare a cursorului și activează sau dezactivează funcția de deplasare a ecranului.

I/D – este variabila prin care se setează direcția de deplasare a cursorului.

0 – modul de decrementare ( direcția stânga).

1 – modul de incrementare (direcția dreapta).

SH – este variabila care activează și dezactivează funcția de deplasare a ecranului.

Instrucțiunea D/C/B On/Off: pornește sau oprește afișajul, cursorul sau funcția de clipire a cursorului.

Instrucțiunea C/D Shift: activează sau dezactivează funcția de mișcare automată a cursorului respectiv ecranului.

Instrucțiunea Function Set: are trei variabile:

DL (data lenght) aceasta setează modul de lucru al afișajului la 8 respectiv 4 biți.

N (number of lines) – cu această variabilă alegem câte linii ale afișajului vom folosi.

F (display font) – cu aceasta selectăm grosimea caracterelor (5×11 sau 5×8).

Instrucțiunea Set CGRAM: cu această instrucțiune putem seta poziția cursorului pe ecran.

Instrucțiunea Set DDRAM: similar cu instrucțiunea precedentă aceasta ne permite să schimbăm poziția ecranului.

Instrucțiunea Read Busy Flag: această instrucțiune este folosită ca o alternativă la o funcție de întârziere, afișajul citește valoarea de la bitul BF (DB7) și asteaptă ca acesta să primească un impuls, apoi trece la următoarea instrucțiune.

Instrucțiunea Write Data to RAM: cu această instrucțiune se face scrierea caracterelor pe ecranul afișajului. Caracterul este diferențiat prin codul unic format din cei 8 biți de date ale ecranului (DB0:DB7).

Instrucțiunea Read Data from RAM: după denumire cu această instrucțiune se face citirea informației stocate în memoria RAM a afișajului.

4.2 Keypad 4×4 :

Pentru realizarea interacțiunii dintre utilizator și microcontroler vom folosi o tastatură cu 16 butoane sau altfel spus 4×4.

Această tastatură funcționează ca o matrice de întrerupătoare, fiecare având o intrare, prin care vom trimite un semnal +5V constant, și respectiv o ieșire, căruia îi vom testa valoarea. Acest test se fa efectua într-o buclă infinită, iar la începutul buclei vom reseta valoarea intrărilor să nu apară erori la citire.

Figura 4.2.1 Schema bloc respectiv schema internă a tastaturii 4×4

Acest test va avea următori pași:

Resetarea intrărilor.

Setarea unei intrări.

Citirea volori prezente la pinul corespunzător.

Dacă microcontrolerul va citi 0 logic se va trece mai departe.

Dacă microcontrolerul va citi 1 logic atunci butonul a fost apăsat.

După testarea tuturor ieșirilor programul se va întoarce la punctul 1.

Observație: între fiecare testare a unui buton este indicat adăugarea unui delay. De altfel testul se va executa prea repede rezultând ca, la apăsarea unui buton microcontrolerul va valida o multitudine de apăsări.

Capitolul 5 – Realizarea practică a unei interfețe utilizator

În această parte vom realiza, practic, o interfață utilizator comandată cu microcontroler.

Vom folosi ca microcontroler un PIC16F887, ca afișaj un LCD 2×16 hexadecimal AC-162B, iar ca un mediu de comunicare cu exteriorul o tastatura 4×4.

Schema de principiu este ilustrată în figura de mai jos:

Figura 5.1. Schema de principiu

Această schemă conține: un microcontroler PIC16F887, un afișaj hexazecimal 2×16 AC-162B, o tastatură 4×4, un potențiometru pentru reglarea luminozității afișajului și alte componente secundare. Pe lângă aceste componente mai este prezentă o diagramă reprezentativă a pinilor unui programator PicKit 2 cât și pini corespunzători conectării acesteia la microcontroler.

Pini afișajului sunt conectați la portul A respectiv B al microcontrolerului. Portul B este folosit la transmiterea datelor, 4 câte 4 biți vor fi transmiși la un moment dat. Asemănător la portul A al microcontrolerului avem pini RS și E ai afișajului cu ajutorul cărora vom trece din modul de comandă în cel de printare a caracterelor, iar cu bitul E vom valida datele prezente la celelalte porturi.

Observație: fără a valida datele de fiecare dată, afișajul va ignora pur și simplu biți prezenți la ceilalți pini.

Pentru controlul contrastului vom folosi un potențiometru simplu de 10kΩ, iar pinul R/W va fi conectat la masă deoarece vom folosi doar operații de scriere.

Portul D al microcontrolerului este rezervat tastaturii. Pini RD <3:0> sunt setați ca pini de ieșire, aceștea vor trimite 1 logic în permanență către tastatură. Pini RD <7:4> vor fi setați ca pini de intrare, aceștea vor fi verificați în permanență de către microcontroler, iar la apăsarea unei taste va apărea un 1 logic pe aceștia care va indica execuția unei subrutine.

În continuare vom realiza programul cu care vom comanda afișajul și tastatura.

5.1 Configurarea Microcontrolerului:

Mai întâi trebuie să configurăm regiștri microcontrolerului, cât și porturile și pini pe care vrem să îi folosim.

Mai în jos este prezentat secvențele de cod folosiți pentru configurarea microcontrolerului. Printre configurările prezente se numără: setarea oscilatorului intern ai microcontrolerului la 4MHz, dezactivarea funcțiilor speciale ale porturilor A și B cât și setarea directivității pinilor.

Figura 5.1.1 Secvența de cod pentru configurarea microcontrolerului PIC16F887 [7]

Mai departe trebuie făcută o inițializare a afișajului. Normal, în modul de lucru pe 8 biți comenzile pot fi transmise direct de la pornirea afișajului, deoarece modul de lucru pe 8 biți este cel implicit.

5.2 Configurarea afișajului AC-162B:

Figura 5.2.1 Diagrama logică de inițializare a afișajului AC-162B pentru modul de lucru pe 4 biți.

În cazul nostru vom avea nevoie de a trecea din modul de lucru implicit pe 8 biți la cel pe 4 biți. Apoi vom face setările dorite, acestea includ:

Setarea grosimi caracterelor și setarea numărului de linii pe care dorim să le utilizăm; acest lucru putem să îl facem cu ajutorul comenzii Function Set, această comanda, pe lângă faptul că face trecerea din modul de lucru pe 8 biți în cel pe 4 biți, are și 2 biți care setează numărul de randuri (bitul 3) respectiv fontul sau grosimea caracterelor (bitul 2), biți 0 și 1 fiind setați ca „n” (don't care).

Următoarea comandă pe care trebuie să o executăm la inițializarea afișajului este comanda de pornirea a afișajului, a cursorului și după caz, funcția de clipirea a cursorului. Aceasta se face cu comanda Display, Cursor, Blinking ON/OFF, comanda în sine are 4 biți, biți de la <0:2> sunt folosiți la pornirea sau oprirea: ecranului, cursorului și activarea funcției de clipirea cursorului. Iar al bitul 3 este folosit la identificarea comenzii. Astfel afișajul poate face distincția dintre comenzi.

În final trebuie specificată direcția de deplasare a cursorului cu ajutorul comenzii Cursor/Display Shift. Cu această comandă putem alege direcția de scriere (bitul 2), iar cu ajutorul bitului 3 putem seta ca doar cursorul să se deplaseze în timp ce ecranul rămâne fix, sau putem alege ca ambi să se deplaseze pe direcția de scriere.

După inițializare este recomandat să se execute o comndă suplimentare (Display Clear) pentru a șterge orice informație rămansă în memoria afișajului și pentru a aduce cursorul pe poziția de start.

5.2.1 Algoritmul de scriere a unui caracter:

Mai întâi trebuie adăugat un delay de 100 us. Acest delay este adăugat înainte de fiecare instrucțiune.

Trebuie pe urmă setat bitul RS ai afișajului prin instrucțiunea BSF PORTA,0. După setarea acestui bit afișajul va trece din modul de comandă în modul de scriere a caracterelor. Un alt delay de 100us este necesare pentru a face această trecere.

Apoi trebuie trimiși spre afișaj biti de date pentru caracterul dorit, în grupuri de câte patru biți numiți și nibleți. Cu comanda MOVLW B'0100' vom încărca în registrul de lucru „W” valoarea binară 0100.

Apoi valoarea din registrul „W” trebuie trimis spre afișaj cu comanda MOVWF PORTB.

După trimiterea acestui niblet trebuie setat și apoi resetat pinul E ai afișajului. Instrucțiunea BSF PORTA,1 face mai întâi setarea apoi BCF PORTA,1 face resetare.

Același procedeu se urmărește și la trimiterea celui de al doilea niblet.

După trimiterea ambilor nibleți mai trebuie să resetăm pinul RS al afișajului pentru al scoate din modul de scriere a caracterelor.

5.2.2 Timpii de execuție ai afișajului AC-162B:

Datorită faptului că microcontrolerul execută instrucțiunile într-un timp extrem de scurt, trebuie să adăugăm un timp de așteptare între fiecare instrucțiune.

Acest timp de așteptare este dependent de afișaj și viteza sa de executare a comenzilor, astfel fiecare operație are un anumit timp de procesare. Astfel:

Figura 5.2.3 Diagrama caracteristici de timp la operațiile de scriere al afișajului AC-162B [6]

Diagrama de mai sus trebuie respectată când facem o adresare la nivelul afișajului. Mai în jos avem un tabel care arată mai precis timpul necesar executării unei operații.

Tabel 5.2.1 Tabelul cu caracteristica de timp al afșajului AC-162B [6]

5.3 Configurarea tastaturii – Secvența de validare a unei taste:

Secvența de inițializare a unei taste este dată în figura alăturată. Această diagramă este construită pe baza algoritmului folosit în lucrarea practică.

În cazul nostru avem algoritmul de validare a tastei 2. Acest algoritm se desfașoară într-o buclă infinită numită „Key Check Loop”.

Prima dată trebuie să resetăm valorile de la intrările tastelor pentru a nu apărea erori la citire.

Apoi se execută algoritmul „Key 2” pentru validarea tastei 2. Se începe cu un delay de 50 ms pentru ca să nu se înregistreze apăsări multiple.

Pe urmă trebuie să setăm bitul 0 al portului D, bitul corespunzător intrării butonului 2 ai tastaturii. După setarea intrari vom testa valoarea bitului 5 de la portul D, bitul corespunzător ieșirii butonului 2 ai tastaturi.

Dacă valoarea acestuia este „0” atunci rezultă că butonul nu este apăsat și se intoarce la începutul buclei.

Dacă valoarea ieșiri este „1” atunci rezultă că butonul este apăsat iar microcontrolerul trece la o altă subrutina.

Deoarece aceast test se desfăsoară într-o buclă infinită este inevitabil faptul că, după executarea subrutinei, microcontrolerul se va întoarce din nou să testeze tastele.

5.3.1 Algoritmul de executare a comenzilor pentru tastele 2 și 8:

Aici vom observa algoritmul de executare a comenzilor pentru tastele 2 și 8. Și vom analiza pas cu pas logica din spatele executării comenzilor.

Diagrama logică de mai sus are următorii pași:

Setăm variabila RAND2 pentru a specifica programului că, cursorul este poziționat pe rândul 2.

Se inițializează bucla infinită pentru testare a butoanelor „Key Check Loop”.

Se realizează testul pentru tastele 2 și 8.

După validarea uneia dintre taste se va trece la una din două subrutine care va testa poziția cursorului folosind variabilele RAND1,2,3,4.

Aceste două subrutine funcționează pe baza aceleași logici de executare doar că, comanda care va fi executată va fi diferită.

Dacă tasta 2 este apăsată atunci se va executa subrutina „Check Rand Up” care va trece cursorul cu o poziție mai în sus.

Dacă tasta 8 este apăsată atunci se va executa subrutina „Check Rand Down” care va trece cursorul cu o poziție mai în jos.

Vom explica doar una din aceste două subrutine deoarece ambele funcționează la fel, doar comanda care rezultă în urma sa este diferită.

În interiorul subrutinei „Check Rand Up” vom testa cele patru variabile corespunzătoare rândului pe care cursorul este la un moment dat.

Dacă, de exemplu, cursorul se află pe randul trei, adică variabila RAND3 este în „1”, atunci la apăsarea tastei 2 pe ecran se va realiza o ștergere a întregului ecran, apoi se va printa caracterele corespunzătoare rândului 2 și 3 cu cursorul poziționat pe randul 2, astfel se realizează trecerea cursorului de pe rândul 3 pe rândul 2.

După printarea caracterelor corespunzătoare microcontrolerul se va întoarce la bucla infinită „Key Check Loop”.

5.3.2 Algoritmul de executare a comenzilor pentru tastele 4 și 6:

În diagrama de jos avem algoritmul de executare a comenzilor pentru tastele 4 și 6.

Diagrama logică de mai sus are aceeași logică ca și cea precedentă și prezintă următorii pași:

Setăm variabila RAND2 pentru a specifica programului că, cursorul este poziționat pe rândul 2.

Se inițializează bucla infinită pentru testare a butoanelor „Key Check Loop”.

Se realizează testul pentru tastele 2 și 8 folosind algoritmul explicat mai devreme.

Se realizează testul pentru tastele 4 și 6.

După validarea uneia dintre taste se va trece la una din două subrutine care va testa poziția cursorului folosind variabilele RAND1,2,3,4.

Dacă tasta 2 este apăsată atunci se va executa subrutina „Check Rand Left” care va stinge led-ul corespunzător rândului pe care cursorul se află.

Dacă tasta 8 este apăsată atunci se va executa subrutina „Check Rand Right” care va aprinde led-ul corespunzător rândului pe care cursorul se află.

Vom explica doar una din aceste două subrutine deoarece ambele funcționează la fel, doar comanda care rezultă în urma sa este diferită.

În interiorul subrutinei „Check Rand Right” vom testa cele patru variabile corespunzătoare rândului pe care cursorul este la un moment dat.

Dacă, de exemplu, cursorul se află pe rândul patru, adică variabila RAND4 este în „1”, atunci la apăsarea tastei 6 al patrulea led se va aprinde. Dacă, în același caz, am fi apăsat butonul 4 și led-ul respectiv ar fi fost aprins atunci acesta s-ar fi stins.

După aprinderea/stingerea led-ului dorit microcontrolerul se va întoarce la bucla infinită „Key Check Loop”.

Observații:

Dacă un led este, de exemplu, aprins și după ce îl selectăm îi dăm comanda de a se aprinde atuci nu se va întâmpla nimic.

Aceste aprinder/stingeri rămân valabile și la modificarea poziției cursorului, led-urile sunt astfel independente unele de altele.

5.4 Posibile îmbunătățiri:

Acest proiect, ca și orice lucru în lumea reală nu este perfect, el având numeroase îmbunătățiri posibile pentru ai crește performanțele sau chiar de ai schimba funcționalitatea.

Printre aceste îmbunătățiri se numără:

Din imaginea de mai sus se observă nevoia de câte un rezistor pentru fiecare ieșire a tastaturii. O îmbunătățire ar fi mutarea acestora pe portul B deoarece acesta are opțiunea de Week Pull-up rezistor. Astfel nu am mai avea nevoie de acești rezistori scăzând astfel complexitatea montajului.

Se mai poate înlocuirea afișajului și al tastaturi cu un touch-screen. Astfel numărul de conexiuni spre microcontroler ar fi mai mic.

Altă îmbunătățire ar fi creerea unei baze de date pentru toate caracterele afișajului. Astfel nu mai ar fi nevoie rescrierea fiecărui caracter individual ci doar apelarea sa din baza de date.

Acest circuit poate fi adăugat la un sistem de achiziție și folosit pentru afișarea și modificarea setărilor.

Se poate adăuga diferiți senzori pentru a transforma acest circuit într-un temporizator folosind un senzor de temperatură, un sistem de alarmă folosind un senzor de mișcare.

Se poate adăuga un afișaj cu mai multe rânduri pentru o mai bună vizualizare a informației.

Concluzii

În concluzie aceste sisteme de informare și interacționare cu utilizatorul sunt printre cele mai necesare sisteme când este vorba de proiectarea unui dispozitiv electronic.

Acest sistem ii oferă utilizatorului informații cu privire la anumite evenimente care au loc în interiorul circuitului și folosind dispozitive de intrare ca și tastatura prezentată aici, utilizatorul poate modifica în timp real informația prezentă pe afișaj sau combinația led-urilor.

Cu câteva din îmbunătățirile de mai sus posibilitățile sunt teoretic infinite, mai multă memorie mai multe dispozitive de intrare/ieșire, mai mulți senzori, mai multe mini-sisteme de microcontrolere care comunică împreună doar imaginația proiectantului există ca limită.

După realizarea acestui proiect am învățat multe despre dispozitivele folosite și despre limbajul de programare utilizat, dar mai mult de atât am realizat importanța creativități în creerea unui sistem de genul acesta și poate și mai important necesitatea unui scop bine definit.

Bibliografie:

[1] http://en.wikipedia.org/wiki/User_interface – Consultat la data 25.feb.2014

[2] http://194.81.104.27/~brian/microprocessor/Memory_Types_Used_in_Microcontrollers.htm – Consultat la data de 24.mar.2014

[4] Datasheet PIC16F887 – http://ww1.microchip.com/downloads/en/DeviceDoc/41291G.pdf

[5] Datasheet PICKit 2 – http://ww1.microchip.com/downloads/en/DeviceDoc/51553E.pdf

[6] Datasheet LCD – AC-162B – http://pdf.datasheetcatalog.com/datasheets2/38/387814_1.pdf

[7] MPLAB User Guide – http://ww1.microchip.com/downloads/en/DeviceDoc/33014J.pdf

Anexe

Anexa nr.1 Imaginea montajului final cu PicKit conectat

Anexa nr.2 Inițializarea proiectului

Anexa nr.3 Primele două rânduri cu led-urile 1 și 2 aprinse

Anexa nr.4 Celelalte rânduri 3 și 4 cu led-urile respective aprinse

Bibliografie:

[1] http://en.wikipedia.org/wiki/User_interface – Consultat la data 25.feb.2014

[2] http://194.81.104.27/~brian/microprocessor/Memory_Types_Used_in_Microcontrollers.htm – Consultat la data de 24.mar.2014

[4] Datasheet PIC16F887 – http://ww1.microchip.com/downloads/en/DeviceDoc/41291G.pdf

[5] Datasheet PICKit 2 – http://ww1.microchip.com/downloads/en/DeviceDoc/51553E.pdf

[6] Datasheet LCD – AC-162B – http://pdf.datasheetcatalog.com/datasheets2/38/387814_1.pdf

[7] MPLAB User Guide – http://ww1.microchip.com/downloads/en/DeviceDoc/33014J.pdf

Anexe

Anexa nr.1 Imaginea montajului final cu PicKit conectat

Anexa nr.2 Inițializarea proiectului

Anexa nr.3 Primele două rânduri cu led-urile 1 și 2 aprinse

Anexa nr.4 Celelalte rânduri 3 și 4 cu led-urile respective aprinse

Similar Posts