100% found this document useful (1 vote)
272 views74 pages

Curs 11.2

The document discusses the architecture and programming of microcontrollers. It provides an overview of microcontroller components like the processor, memory types (RAM, ROM, EEPROM), peripherals for input/output, timers, and communication modules. It describes the oscillator, reset, brown out reset, and watch dog timer modules. Examples are given on using outputs, inputs, analog inputs, timers, and displays with a microcontroller. Appendices provide examples of a logic tester and an open source programmer.

Uploaded by

Daniel Asandei
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
272 views74 pages

Curs 11.2

The document discusses the architecture and programming of microcontrollers. It provides an overview of microcontroller components like the processor, memory types (RAM, ROM, EEPROM), peripherals for input/output, timers, and communication modules. It describes the oscillator, reset, brown out reset, and watch dog timer modules. Examples are given on using outputs, inputs, analog inputs, timers, and displays with a microcontroller. Appendices provide examples of a logic tester and an open source programmer.

Uploaded by

Daniel Asandei
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 74

GRUP FORMARE PROFESIONALA

MASTER SRL

UTILIZAREA si PROGRAMAREA
MICROCONTROLERELOR

Autor ing. Martin Stefan


Cuprins:

Capitolul 1: Arhitectura Microcontroler-ului ................................3

Capitolul 2: Notiuni de programare in limbaj C++ .................. 13

Capitolul 3: Definirea schemei de utilizare MCU .......................22

Capitolul 4: Utilizarea compilatorului MikroC PRO for PIC........31

Exemplul 1 : Utilizarea iesirilor logice .......................................33


Exemplul 2 : Utilizarea intrarilor logice......................................37
Exemplul 3 : Utilizarea intrarilor analogice ..............................39

Exemplul 4 : Utilizarea FVR si WDT..........................................42


Exemplul 5 : Utilizarea afisajelor cu 7 segmen.te .................... 47

Exemplul 6 : Utilizarea afisajelor matriciale LCD.......................52

Exemplul 7: Utilizare Timer0 ....................................................55


Anexa1 : Tester logic auto cu voltmetru ...................................60

Anexa 2 : Programator Open Programmer................................70

Utilizarea si programarea microcontrolerelor Pag 2


Capitolul 1: Arhitectura Microcontroler-ului
Deja suntem obisnuiti din viata de zi cu zi sa auzim si sa intilnim tot mai des
notiunea de microprocesor. Microprocesorul nu este altceva decat o unitate logica si
aritmetica , ce este capabila sa faca anumite calcule,rapide si corecte. Pentru a
functiona corect si tot odata sa devina util, el trebuie integrat intr-un sistem, prin care
sa introducem datele de lucru (exemplu: tastatura) ,si care sa ne permita utilizarea
datelor (monitor, imprimanta, etc.).

Fata de microprocesoare , un microcontroler (abreviat cu MCU in lucrare) contine


pe linga un microprocessor, si o serie de module periferice , necesare functionarii lui
ca entitate independenta, destinata de regula sa controleze direct un proces. Astfel
un MCU contine pe langa processor , oscilatorul de lucru, memoria de program
(ROM), memoria de lucru (RAM) si memoria nonvolatila de date (EEPROM); precum
si o serie de module periferice de intrari sau iesiri, numaratoare , module de
comunicare ; etc. O schema bloc simplificata a unui MCU este prezentata in
continuare:

Utilizarea si programarea microcontrolerelor Pag 3


Diversitatea acestor module precum si combinatiile dintre ele fac ca sa avem o
familie bogat diversificata de microcontrolere.
Dupa numarul de biti pe magistrala de date a procesorului, acestea pot fi pe unu;
patru; opt; saisprezece; treizecisidoi sau saizecisipatru biti.
Al doilea criteriu de clasificare al microcontrolerelor o reprezinta lungimea
memoriilor.
Un MCU contine trei tipuri de memorii:
• Random Acces Memory (RAM) – reprezinta memoria de lucru in care se
scriu si se citesc permanent valori ale variabilelor de lucru. Memoria are viteza
mare de scriere si citire, durata de viata nelimitata , dar pierde informatia la
scaderea tensiunii de alimentare sub o valoare minima .
• Read Only Memory (ROM) – reprezinta o zona rapida de memorie folosibila
doar la citire. Continutul nu se altereaza la pierderea tensiunii de alimentare .
Desi este proiectata sa fie doar citita (nelimitata ca durata de viata la numarul de
citiri) , in conditii speciale ea poate fi scrisa de fabricant sau utilizator prin
intermediul unui programator (interfata de programare) speciala.

Utilizarea si programarea microcontrolerelor Pag 4


Scrierea este insa un proces lent dar poate fi repetat de peste 10000 ori, iar
informatia este garantata peste 40 ani. De mentionat ca aceasta memorie are in
general cuvinte cu o lungime nestandardizata de 12 biti, 14 biti sau mai multi
dupa numarul de biti necesar pentru a stoca numarul maxim de instructiuni.
Aceasta memorie denumita si FLASH contine in general programul de lucru ce
urmeaza a fi executat de Microcontroler; precum si setarile de baza initiale.
• Electrically Erasable Programmable Read-Only Memory (EEPROM) .
Acesta reprezinta un spatiu restrans de memorie nealterabila la caderea
tensiunii dar se citeste si scrie relativ incet (si cu numar mare de instructiuni). Cu
toate astea datorita faptului ca procesorul o poate sterge si rescrie in timpul
lucrului, iar durata de viata este de peste 100000 cicluri, este folosita la stocarea
variabilelor de program ce trebuiesc reincarcate la pornirea programului. Citirea
este mai greoaie decat din ROM sau RAM.
In cazul in care se doreste stocarea unor blocuri mai mari de date , sau un
numar de scrieri mai mare de 100000; se pot accesa blocuri de memorie
externa tot de tip EEPROM, dar special dedicate si care au atat viteza mai mare
dar si spatiu si durata de viata inbunatatita.

Descrierea generala a unei structuri minime de Microcontroler, precum si a


blocurilor periferice din componenta sa, este prezentata in paragrafele
urmatoare :

• Oscilatorul reprezinta sursa unui semnal oscilant ce stabileste ritmul de


executie a instructiunilor de program. El poate lucra in regim intern , fara sa
iroseasca din pinii MCU, sau poate folosi componente externe, cum ar fi
rezonatori ceramici sau cristale din quart.
- Intern este ieftin , nu necesita componente si nici pini liberi , dar are o
stabilitate si precizie de circa 1%, destul de buna pentru aplicatii ce nu impun
contorizari in timp real pe termene lungi.
- Extern cu rezonator ceramic – Stabilitate buna (circa 0.1%) destul de ieftin
dar utilizeaza 2 pini.
- Extern cu cristal de quart – Stabilitate foarte buna (circa 0.0001%) nu foarte
scump, dar utilizeaza 2 pini.
- Oscilator de joasa frecventa , folosit fie in procese foarte lente, fie in regim
de “SLEEP” , cand consumul trebuie sa fie foarte redus (de ordinul 20-50nA)
, iar procesorul asteapta anumite evenimente pentru a intra propriuzis in
regim de lucru.

• Modulul de reset
Este un modul necesar functionarii corecte si sigure a procesorului si are ca functie,
stergerea tuturor registrilor si initializarea acestora inainte de inceperea unei sesiuni
de lucru. Unele procesoare contin si un modul atasat de intarziere (configurabil la
cerere) ce intarzie procesul de pornire pentru siguranta intrarii in regim normal de
functionare al tuturor modulelor periferice, cum ar fi stabilizarea frecventei de
oscilatie a oscilatorului, etc.

• Modulul BOR ( Brown Out Reset)

Utilizarea si programarea microcontrolerelor Pag 5


Este un modul programabil ce supravegheaza scaderile lente de Vdd sub limite
minime , unde functionarea unor blocuri poate deveni instabila sau nesigura.
Functie de configurare , acesta poate genera inclusiv semnal de Reset general,
moment in care procesorul poate pierde valorile momentane si isi reia activitatea
numai dupa revenirea la conditii de lucru normale si cu valorile de start din
program.

• Modulul WDT (Watch Dog Timer)

Este un modul paralel si independent de microprocesorul din MCU . El dispune de


un oscilator propriu, de consum mic, si de un contor configurabil ce numara
oscilatiile, in mod direct sau prin intermediul unui divizor numit prescaler. Odata
ajuns la limita superioara de numarare (contorul este plin) , WDT va genera un
semnal de Reset General, moment in care procesorul va pierde valorile
momentane si isi reia activitatea numai dupa revenirea la conditii de lucru normale
si cu valorile de start din program.
Este obligatia programatorului la scrierea programului de lucru al procesorului, sa
prevada in anumite puncte de trecere periodica cate o comanda “ CLRWDT” .
Aceasta comanda permite procesorului sa stearga continutul contorului WDT
(initializarea lui).
Modulul WDT va continua sa numere , dar de la inceput. Daca intervalele de
stergere sunt mai mici decat timpul necesar de “umplere” al contorului, totul va
functiona corect si niciodata WDT nu va ajunge sa genereze RESET. Daca insa din
motive necunoscute, procesorul iese din bucla de program sau se “blocheaza” , el
nu va mai genera semnalele periodice de stergere al registrului WDT, acesta isi va
atinge limita superioara si va genera semnalul de Reset, scotand astfel procesorul
din starea de blocaj. Este adevarat ca se pierd niste valori momentane dar
procesele continua asa cum si-a propus programatorul. Atunci cand aceste
procesoare folosesc variabile predefinite in cadrul functionarii, sau valori
intermediare importante (gen numar total de Kilometri parcursi de un automobil ),
periodic aceste procesoare trebuie sa retina (memoreze) intr-o memorie de tip
EEPROM (interna sau externa), toate valorile variabilelor ce trebuiesc reincarcate
la reluarea activitatii MCU dupa Reset.
Rezulta astfel ca atunci cand MCU gestioneaza procese inportante , cu perioade
lungi de functionare continua, cum ar fi controlul functionarii unei pompe, este
obligatorie folosirea modulului WDT pentru a nu risca sa inceteze nedorit controlul
procesului, caz in care fie pompa n-ar mai porni fie ar merge pana s-ar arde sau ar
exploda rezervorulC

• Circuite de intrare . Asigura accesul la microcontroler a unor valori de


tensiuni sau variabile numerice, ce urmeaza sa fie prelucrate de microprocesor.
Acestea pot fi
- Speciale (vezi specificatia tehnica din Data Sheet-ul aferent fiecarui MCU).
- De uz general – nivele logice (zero sau unu): - normale
- cu trigger SCHMITH (fig1)

- intrari analogice (fig 2 )

Utilizarea si programarea microcontrolerelor Pag 6


• Circuite de iesire -De uz general
– nivele logice - push-pull (GND sau Vdd)
- open Drain (GND sau liber)
- Speciale (vezi specificatia tehnica din Data Sheet-ul aferent )
analogice ca DAC sau digitale ca PWM
Atentie :
- Se interzice aplicarea de tensiuni pe pinii configurati ca iesiri
( cu exceptia consumatorilor ce respecta Imax iesire).
- Se interzice depasirea curentului maxim pe pin, pe port si pe capsula. De
exemplu un MCU cu 40 pini si Pmax=0.8W are 32 iesiri care pot suporta
curenti de 25mA fiecare dar nu mai mult de 300mA pe toata capsula (nu
800mA). Vezi specificatiile tehnice atasate pentru PIC12F629/675 si
PIC16F87x. Uneori difera curentul maxim si functie de capsula.
Pentru tensiunile de intrare ce pot depasi valorile permise pe MCU (<-0.3V sau
>Vdd+0.3v) aveti in capitolul 3, cateva exemple practice de prevenire a acestor
depasiri.

• Blocul de conversie Analog Digital Conversion (ADC)


ADC este folosit ca modul ce “citire” a intrarilor analogice. Din start se alege un
procesor care sa aiba ADC-ul cu o rezolutie corespunzatoare necesitatilor de
masura. De regula rezolutia ADC din MCU este de :
8 biti (0-255 valori) ;
10 biti (0-1023 valori )
12 biti (0- 4096 valori );
De mentionat ca atunci cand trebuiesc citite mai multe intrari analogice, un
MCU face citirea (conversia ) valorilor analogice de la intrari pe rand. Totusi pentru
a mari viteza de citire exista MCU cu mai multe module ADC incorporate.
Toate intrarile trebuie sa respecte regula tensiunilor aplicate pe intrari, in plus
pentru acuratetea citirilor, inpedanta de intrare trebuie sa fie < de 10 K. In cazul in
care aceasta valoare nu poate fi asigurata, dar viteza de variatie a semnalului
analogic este mica, inpedanta de intrare poate fi scazuta prin adaugarea unui
condensator paralel pe intrare care asigura o inpedanta de tranzitie mica asa cum
este exemplificat mai jos:

Utilizarea si programarea microcontrolerelor Pag 7


Pentru a fi folosit blocul de conversie ADC trebuie activat , si dupa aceasta, setati
(cu ajutorul registrelor adecvate) parametrii de lucru, cum ar fi:
Valoarea Vref-; care este o tensiune interna sau externa , cu valoarea minima de 0V
(GND) . De altfel, uzual Vref- se leaga intern la GND.
Valoare Vref+ ; care este o tensiune interna sau externa , cu valoarea maxima de Vdd.
Aceasta tensiune trebuie sa fie precisa fiindca toate masuratorile se vor raporta la
valoarea ei.
De regula, aceasta tensiune poate fi obtinuta in trei moduri , si anume :
- Vdd (tensiunea de alimentare a MCU), caz in care aceasta tensiune trebuie
sa aiba o buna stabilitate. De remarcat ca un stabilizator de tipul LM78L05
(foarte frecvent folosit) are o stabilitate de 1%. In aceasta situatie, daca
masuram o tensiune de 13.8V (evident prin intermediul unui divizor), cu o
precizie de +/- 1%; vom avea o marja de eroare de 0.138V , ceea ce
inseamna ca valoarea rezultata poate fi situata intre 13.66V si 13.94V
- Vref extern. Este cea mai buna solutie tehnica , deoarece permite utilizarea
unei surse de referinta de foarte buna calitate , dar este scumpa si necesita
in plus si utilizarea unui pin de MCU in acest scop.
- Vref legat intern la un modul propriu unor MCU (nu toate MCU contin acest
modul) , ce genereaza o tensiune fixa: Fixed Voltage Reference (FVR).
Folosirea aceastei tensiuni , presupune insa activarea modulului FVR ceea
ce creste curentul consumat pe capsula, si are o stabilitate de circa 4%
(modesta), dar este solutia ideala pentru montaje simple cu consum mic
alimentate direct din baterii sau acumulatori, a caror tensiune variaza in
timpul functionarii : o baterie standard de 1.5V are de fapt intre 1.42V si
1.61V, iar un acumulator Li-Ion are intre 3.6V si 4.2V.
Trebuie de asemenea configurata si viteza de conversie a datelor. Nu se recomanda
folosirea unei viteze de conversie mare daca nu este necesara, intrucat aceasta
dauneaza atit consumului cat si acuratetii conversiei.
Trebuie sa mai amintim aici ca functia de achizitie “Read_ADC(X)”( folosita in C++),
unde x reprezinta numarul unuia dintre canalele analogice valide, nu este utilizabila
decat in asociere cu Vref+ = Vdd. Daca se utilizeaza Vref extern sau FVR trebuie scrisa
o subrutina speciala de genul:
unsigned Get_ADC(){
ADCON0.F1 = 1; // start conversion
while (ADCON0.F1); // wait for conversion
return (ADRESH << 8) + ADRESL; // return value
}
iar pentru folosirea ei in cadrul programului se fixeaza intai canalul de citire si apoi
se apeleaza:
ADC_Value = Get_ADC();
Utilizarea si programarea microcontrolerelor Pag 8
• Blocul de conversie Digital to Analogic Conversion (DAC)
Dupa cum rezulta din denumire acest bloc poate face conversia unui numar digital
intr-o valoare analogica (lineara). Este de fapt opusul modulului ADC . Dupa
lungimea numarului ce urmeaza sa fie convertit , rezulta precizia (rezolutia)
convertorului.
De regula rezolutia DAC din MCU este de: 8 Biti (0-255 valori); 10 biti (0-1023
valori). Valoarea de iesire a convertorului depinde atat de numarul binar convertit ,
cat si de referinta analogica la care se raporteaza. Si aici tensiunea rezultanta de
referinta va fi diferenta dintre Vref+ si Vref- unde:
Vref- poate fi setat la: - Vref- extern
- GND;
Vref+ poate fi setat la: - Vref+ extern
- Vdd (tensiunea de alimentare)
- FVR intern Fixed Voltage Reference (cand exista)
mentionam ca nu toate procesoarele contin blocul FVR.
Tensiunea generata de blocul DAC poate fi disponibila extern , pe pini de iesire ai
MCU, sau folosita intern, la randul ei ca tensiune de referinta pentru alte blocuri ,
cum ar fi ADC, comparatoare, etc (vezi data sheet-ul corespunzator fiecarui MCU).

• Module analogice Speciale


Aceste module nu vor fi tratate in mod special in lucrarea de fata , ele fiind folosite
de regula in aplicatii speciale de tratarea unor semnale analogice .
Amintim ca avem aici module cum ar fi: comparatoare, amplificatoare operationale,
detectoare de trecere prin zero (Zero Cross Detect ZCD).
De mentionat ca daca aceste module exista in structura unui procesor utilizat, si nu
intentionati sa-i utilizati serviciile , se recomanda sa le dezactivati din cuvintele de
configurare sau din registrele corespunzatoare de configurare.

• Timer 0
In general un MCU contine mai multe TIMERE , care sunt de fapt numaratoare de 8
sau 16 biti (valoare maxima a contorului 256 sau 16384) a caror sursa de impulsuri
poate fi setata sa provina din interior sau exterior.
Ele pot fi setate sa contorizeze timpi (durata procese), sau sa genereze pulsuri la
intervale de timp constante.
Desi au destinatii preferentiale diferite, in aceasta lucrare von trata doar Timer0.
Acest contor este in general pe 8 biti , si poate fi legat la frecventa oscilatorului
intern divizata la 4 in mod direct, sau printr-un Prescaler (un divizor suplimentar
inseriat). Reamintim ca aceasta frecventa de lucru interna poate proveni din
functionarea oscilatorului pe componente interne (precizie1% ) sau externe, (pana la
0.00001% cu cristale Quartz de calitate).
De cate ori contorul atinge valoarea maxima, acesta genereaza un inpuls de
intrerupere catre procesor, care isi intrerupe activitatea curenta (retine intro memorie
speciala numita STIVA, locul unde se afla la momentul intreruperii) ,si trece la
executia unei subrutine, scrisa de utilizator, cu ceace trebuie sa faca procesorul in
aceasta situatie. De regula incrementarea unui contor cu valoarea REALA de timp
scursa de la intreruperea anterioara. Desi lungimea contorului este mica (uzual 256)
Utilizarea si programarea microcontrolerelor Pag 9
, in subrutina de intrerupere , se poate incrementa o variabila , pentru a se masura
cu precizie timpi de secunde, minute, ore ,C zileCetc.
Dupa terminarea subrutinei de intrerupere, procesorul reia locul de executie avut
anterior (memorat in Stiva) si isi continua activitatea curenta. De mentionat ca
Timer-ul nu pierde timp cu asteptarea procesorului sa-i execute subrutina de
intrerupere. El genereaza inpulsul de intrerupere (memorat in registrul de intreruperi)
si isi reia numaratoarea din nou. Procesorul dupa inceperea subrutinei de
intrerupere verifica motivul intreruperi , sterge cererea de intrerupere memorata in
registrul de intreruperi, si o executa.
In cazul in care mai multe periferice (blocuri interne ) genereaza cereri de
intreruperi , acestea se memoreaza in registrul de intreruperi, se face un test al
bitilor de intreruperi, pentru a se afla cine a solicitat intreruperile , dupa care se
trateaza fiecare pe rand intr-o ordine de prioritate stabilita de programator.

• Module de comunicare seriala

- Acestea pot fi Master Synchronous Serial Port (MSSP) cu SPI sau I2CTM
- Enhanced Universal Synchronous Asynchronous Receiver Transmitter
(EUSART)
- USB , etc
Ele sunt module ce pot comunica la cerere, cu alte periferice externe, folosind
diverse protocoale de comunicare, dupa numarul de fire, tensiunea pe liniile de
comunicare , viteza de transmisie , etc.
Astfel acestea pot diferi prin modul de adresare , un periferic sau mai multe
indexate, pe unul sau mai multe fire, sincron sau asincron.

• Modulele CCP –(Capture Compare PWM )

Aceastea reprezinta o serie de module configurabile la cerere, pentru aplicatii de


numarare controlata, sau executii in timp real, dar si de generare a unui semnal de
comanda , modulat in factor de umplere PWM.

Evident ca exista multe alte module aparute in special la MCU moderne, destinate
unor aplicatii de uz general (comanda LCD) sau specializate.

• Programarea in circuit a Microcontrolerelor

Anumiti pini din familia PIC de MCU au functie dubla. Ei sunt folositi atat pentru
programare cat si ca pini de uz general in timpul lucrului. Intrarea in regim de
programare se face fie prin aplicarea unei tensiuni mari (8-13V) pe pinul Vpp-MCLR,
fie prin aplicarea unei secvente speciale, daca la o scriere anterioara s-a activat in
“Configuration-world” “Low Voltage Programming”.
Scrierea se poate face si in montaj (dupa ce MCU a fost lipit pe placa ) nu doar
separat. Evident si in acest caz se foloseste tot interfata de scriere (programare).
Acest mod de scriere se numeste In-Circuit-Serial-Programming , sau pe scurt
Utilizarea si programarea microcontrolerelor Pag 10
ICSP. Insa pentru a beneficia de aceasta facilitate montajul trebuie sa respecte
cateva reguli ce vor fi expuse in continuare:
• Circuitul legat la pinul Vpp –MCLR trebuie sa suporte tensiuni mari (8-13V).
• Tensiunea de alimentare pentru MCU in timpul scrierii (Vdd) trebuie aplicata
numai lui, nu intregului montaj. In primul rand programatorul nu poate asigura
curentul de alimentare pentru tot montajul dar sunt situatii in care aplicarea
acestei tensiuni poate duce la arderea unor piese din circuit. Astfel daca
procesorul este alimentat din iesirea unui stabilizator (de exemplu 78L05)
varianta uzuala de altfel, acest stabilizator nu accepta tensiune de iesire mai
mare decat tensiunea la intrare.
• Cand este alimentat MCU el va avea tensiunea de Vdd la iesire, dar nimic pe
intrare si ca atare sint depasite valorile permise (prin urmare se distruge).In
figura de mai jos este exemplificat acest lucru cand Vdd>Va.

Pentru a se evita acest lucru se pot folosi doua variante de separare a


alimentarii MCU, si anume:
* Alimentarea prin dioda, care este simpla, sigura dar scade tensiunea de
alimentare a MCU cu Uf dioda (0.5-0.7V) si practic aceasta nu mai poate fi
folosita ca referinta pozitiva, daca procesorul o foloseste la conversia ADC.

* Sau o alta varianta mai buna dar incomoda la scriere, (trebuie avut grija ca
in timpul scrierii Jumper-ul sa fie scos) este prin intreruperea alimentarii dintre
MCU si montaj cu ajutorul unui “jumper” ca in schema de mai jos:

Utilizarea si programarea microcontrolerelor Pag 11


• Nu sunt permisi condensatori mari (>0.1uF) pe pini de Vdd si Vpp.
• Nu sunt permisi DELOC condensatori pe pinii de DATA si CLOCK. Daca
utilizarea lor este necesara pentru a suprima pulsatiile ce pot aparea pe acesti
pini, va trebui ca acestia sa fie decuplati prin rezistente suficient de mari pe care
interfata de programare sa le accepte (in general >1K) . Acest lucru este
exemplificat in schema de mai jos:

Utilizarea si programarea microcontrolerelor Pag 12


Capitolul 2: Notiuni de programare in limbaj C++

Acest capitol isi propune doar sa treaca in revista cateva din notiunile de baza din
programarea in limbaj C+
Pentru a intelege avantajul major pe care-l are programarea intr-un limbaj avansat,
vom pune in paralel acelasi program scris in assambler, cel mai scazut nivel de
programare, care foloseste direct instructiunile microprocesorului si varianta
aceluiasi program scris in C+:

In C+: TRISA =0b00111000 ;


ANSELA =0;

Acelasi program in Assambler:

BANKSEL PORTA ;
CLRF PORTA ;Init PORTA
BANKSEL LATA ;Data Latch
CLRF LATA ;
BANKSEL ANSELA ;
CLRF ANSELA ;digital I/O
BANKSEL TRISA ;
MOVLW B'00111000' ;Set RA<5:3> as inputs
MOVWF TRISA ;and set RA<2:0> as
;outputs

in plus cel scris in limbaj avansat este mult mai usor de inteles

Variabile

Variabilele pot fi: - numere (ale caror valori variaza in timpul rularii programului)
- siruri de caractere (variabile text)
- Arii (matrici)
Variabilele numerice
Inainte de folosire in limbajul "C" variabilele trebuiesc declarate , definindu-se atat
tipul variabilei cat si valoarea de start.
Este interzisa folosirea de nume rezervate pentru a declara variabile, acestea
generand erori fatale;
astfel de nume : for, next, while, do, int, (o lista a numelor de variabile neutilizabile
,o puteti gasi in PIC Microcontrollers -Programming in C ; manual de referinta
pentru incepatorii in programare. Vezi tabelul de mai jos:

absolute data if return typedef


asm default inline rx typeid
at delete int sfr typename
auto do io short union
bit double long signed unsigned

Utilizarea si programarea microcontrolerelor Pag 13


bool else mutable sizeof using
break enum namespace static virtual
case explicit operator struct void
catch extern org switch volatile
char false pascal template while
class float private this
code for protected throw
const friend public true
continue goto register try

Variabilele numerice pot avea nume formate din literele a-z (preferabil literele mici)
si cifrele 0-9 , dar nu pot incepe cu o cifra.
Pot fi folosite si literele mari , dar se prefera ca acestea sa defineasca doar
constante.
Dupa tipul variabilei , aceasta poate ocupa un spatiu de memorie diferit in timpul
programului.
Pentru economisirea spatiului ocupat in RAM de variabile, se recomanda definirea
variabilelor cu o lungime minima in care ele se pot incadra. In microC for PIC aceste
tipuri pentru variabile numerice sunt:

tip variabila octeti limite de valori


ocupati
short int 1 0 la 255
signed short int 1 -128 la 127
unsigned int 2 0 la 65535
int 2 -32768 la 32767
long int 4 0 la 4 294 967 295
signed long int 4 -2147483648 la 2147483647
floating point 4 +-1.17549435082 *10-38 la +-
6.80564774407*1038

Numere

Sistemul zecimal
In viata de zi cu zi am fost obisnuiti sa numaram si calculam in sistemul Zecimal,
altfel spus, in sistemul cu baza de numarare 10. Acesta contine cifrele de la 0 la 9.
Cu aceste cifre se pot forma numere ce contin mai multe cifre. Dupa locul ocupat de
cifre in numar , poarta numele de unitati , zeci, sute, mii ,etc. Valoarea numarului

Utilizarea si programarea microcontrolerelor Pag 14


este data de suma tuturor produselor dintre baza la puterea locului ocupat de cifra
si valoarea cifrei.
Astfel pentru o baza de numarare "B" si un numar XYZ valoarea numarului este :
X*B2 + Y*B1 + z*B0
In particular pentru baza 10 si numar 792 rezulta:
7*102 + 9*101 + 2*100 = 700+90+2 =792 zecimal
Apartent este complicat dar s-a facut aceasta exemplificare pentru a se intelege mai
usor ceea ce urmeaza si anume sistemul binar si cel hexazecimal.
Sistemul Binar
In tehnica de calcul este mult mai usor sa se lucreze cu doar 2 valori pe un fir si
anume:
- avem tensiune sau nu avem tensiune ; astfel nu depindem de valoarea tensiunii
de alimentare , ci doar daca tensiunea este mare sau mica abreviata cu 0 sau 1.
Pentru simplificare si siguranta in transmisia datelor 0 este considerata o tensiune
mai mica decat un maxim acceptat pentru valoarea 0 (dar nu mai mica decat 0 ; nu
negativa),
iar 1 o tensiune mai mare decat un minim admis pentru a fi considerata tensiune
valida , dar nu mai mare decat tensiunea de referinta (in general a sursei de
alimentare).

Astfel sunt definite mai multe standarde de limite , cum ar fi:


* TTL pentru U alimentare 5V (4.75-5.1V) nivel 0 intre 0si 0.8V; nivel 1 intre 2.4V si
Ualimentare ; Intre 0.8V si 2.4V zona incerta (nepermisa).
* CMOS nivel 0: intre 0si 0.33Ua; nivel 1:intre 0.66Ua si Ua unde Ua= Ualimentare
Intre 0.33Ua si 0.66Ua este zona incerta (nepermisa).
* Pentru familia de procesoare PIC fabricate de Microcip se poate considera in
general (trebuie citit in datele de catalog ale fiecarui integrat valorile recomandate)
urmatoarele intervale:
nivel 0 intre 0si 0.2Ua; nivel 1 intre (0.8 la 1)*Ua unde Ua= Ualimentare
Intrucat se folosesc doar 2 valori 0 si 1 putem exprima totul in baza 2 adica vom
folosi doar cifrele 0 si 1 in numerele formate de aceste cifre.
Conform regulii prezentate anterior un numar binar compus din mai multe cifre
ex:10110011 se va calcula dupa cum urmeaza:

1 0 1 1 0 0 1 1
1*2 + 0*2 +1*2 + 1*2 +0*2 +0*2 + 1*2 +1*20 =
7 6 5 4 3 2 1

128+ 0+ 32+ 16+ 0+ 0+ 2+ 1 =179(zecimal)

Dupa numarul de cifre binare pe care il contine un numar binar, definim 2 variante
de baza:
- cu o singura cifra :"bit-ul" poate fi doar 0 sau 1
Utilizarea si programarea microcontrolerelor Pag 15
- Cu 8 cifre (8 biti) "Byt-ul" poate fi intre 0 si 11111111 ( 0si 255zecimal) se mai
numeste si "octet"
- Cu 16 cifre (practic 2 octeti ) . Acestia se vor defini ca LSB (Low Semnificative
Byt) si respectiv MSB (Most Semnificative Byt).
De mentionat ca toate elementele de calcul (microprocesoare si implicit
microcontrolere) lucreaza exclusiv in sistem binar,

Sistemul Hexazecimal
Pentru simplificarea citirii numerelor mari in informatica se foloseste adesea si
sistemul hexazecimal ( baza de numarare 16) avand ca cifre
0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F. Se remarca aici ca A,B,C,D,E,F sunt simbolurile
cifrelor cu valori zecimale mai mari ca 9.
Intrucat in sistemul binar numarul maxim pe patru biti este 15zecimal (1111binar) se
observa ca putem grupa cate 4 biti ce pot fi reprezentati printr-o singura cifra in
hexazecimal .
Exemplul anterior 10110011 in binar, devine B3 in hexazecimal.
Adesea in program folosim toate cele 3 variante de sisteme de numeratie. Pentru a
le distinge atat noi cat si programul de compilare numerele vor fi precedate de un
prefix dupa cum urmeaza:
nimic pentru zecimal : 179
0b pentru binar: 0b10110011
0x pentru hexazecimal : 0xB3
asadar 179= 0b10110011=0xB3
Variabilele indexate (pointer)
Atunci cand avem un numar de variabile (numerice sau siruri), scrise intr-o anumita
succesiune (lista) ele se pot apela dupa locul lor in lista .
Char *ziua[8] =luni,marti,miercuri,joi,vineri,sambata,duminica, ; // unde [8] lungimea
unui sir Astfel cand apelam ziua3 v-a rezulta miercuri
Pentru incepatori insa, se poate evita folosirea variabilelor indexate
Variabilele text (sau siruri )
In general sirurile sunt variabile text ce urmeaza a fi tiparite pe un ecran. De
mentionat ca spre imprimanta sau ecran LCD (etc) daca avem de afisat T=94g ,
vom trimete:
caracterul “T”, caracterul “=”, caracterul “9”, caracterul “4”, caracterul “g” ,
Dupa cum se observa 94 nu mai este un numar trimes, ci un sir de caractere
(simboluri).
Pentru a fi recunoscute drept siruri si nu nume de variabile sau cifre , valoarea
sirurilor va fi introdusa intre ghilimele : valoarea lui T=94g vafi scrisa asa : “T=94g”
Exemplu de sir trimes spre ecran:
lcd_out(1,1, "Tset=");
Daca ea este definita ca variabila, pentru a putea fi calculata anterior, va arata ceva
de genul :
char numesir [5] ; // numele variabilei este numesir si are o lungime de 5
caractere
CCCCCCCC.
numesir = “Tset=” // atribuirea valorii pentru variabila numesir
DDDDDDDDDD..
lcd_out(1,6, numesir); // afisarea pe ecran a valorii lui numesir
(pe ecran apare Tset=)
Utilizarea si programarea microcontrolerelor Pag 16
pentru mai multe detalii trebuie aprofundata folosirea sirurilor in limbajul C++

Functii logice

Principalele functii logice utilizate sunt:


- functia si, (simbol &) adevarata atunci cand toate variabilele de intrare
sunt adevarate: pentru intrarile I1; I2; .. In; rezultatul functiei Rsi = 1 cand
toate intrarile (I1; I2; .. In) sunt in “unu” logic (deci si I1=1;si I2=1;si .. si
In=1).
- functia sau, (simbol | ) adevarata atunci cand cel putin una dintre
variabilele de intrare sunt adevarate: pentru intrarile I1; I2; .. In; rezultatul
functiei Rsau = 1 cand cel putin una dintre intrarile (I1; I2; .. In) este in
“unu” logic (deci I1=1;sau I2=1;sau .. sau In=1). Evident ca pot fi mai
multe intrari simultan in 1 (adevarate)
- functia nu , (simbol !) reprezinta negatia , si anume 0 negat=1 iar 1 negat
=0
- functia reminder, (simbol %) returneaza restul inpartirii prin numarul ce-l
urmeaza.
- functia xor , denumita si sau exclusiv , se raporteaza la 2 intrari cu
functia sau , dar numai cand doar una este adevarata (se exclud reciproc ),
altfel spus cand cele doua intrari difera intre ele functia este realizata.

Atribuirea de valori :
Atribuirea de valori unei variabile se face uzual prin semnul de egalitate intre numele
variabilei si noua valoare directa sau operatia al carui rezultat ii va fi atribuita
variamilei. Cateva exemple aveti mai jos:
variabila =754 ; variabila cu numele “variabila”ia valoarea 754 in zecimal
variabila =0x02F2 ; variabila cu numele “variabila”ia valoarea 02F2(hexa) =754
in zecimal;
variabila =7+a ; variabila cu numele “variabila”ia valoarea variabilei a la care se
aduna 7;
variabila = variabila +a ; variabila cu numele “variabila”ia valoarea initiala
+valoarea lui “a”

Operatori uzuali:
Adunarea :
variabila =7+a ; variabila cu numele “variabila”ia valoarea variabilei “a” la care se
aduna 7;
Scaderea:
variabila =a-7 ; variabila cu numele “variabila”ia valoarea variabilei “a” din care
se scade 7;
Inmultirea:

Utilizarea si programarea microcontrolerelor Pag 17


variabila =a*7 ; variabila cu numele “variabila”ia valoarea variabilei “a” multiplicata
de 7ori;
Inpartirea:
variabila =a/7 ; variabila cu numele “variabila”ia valoarea variabilei “a” inpartita la
7;

Increment :
variabila ++; variabila cu numele “variabila”isi mareste valoarea cu o unitate
(adunarea cu 1 ) ;

Decrement :
variabila - - ; variabila cu numele “variabila”isi micsoreaza valoarea cu o unitate;
(scaderea cu 1 ) ;

Comparatia:
Testul de egalitate :
variabila ==754 ; functia este 1 (adevarata) daca variabila cu numele
“variabila”avea valoarea
754 in zecimal
Testul de inegalitate :
variabila <754 ; functia este 1 (adevarata) daca variabila cu numele “variabila”
avea valoarea mai mica decat 754 in zecimal.
variabila >754 ; functia este 1 (adevarata) daca variabila cu numele “variabila”
avea valoarea mai mare decat 754 in zecimal;
se pot folosi si functiile combinate >= mai mare sau egal ; <= mai mic sau egal ;

Conditionarea simpla :
if (conditie sau conditii ) {
linii de program de executat;
} // sfarsit pachet program conditionat
de cate ori conditia sau conditiile sunt realizate (rezultatul functiilor dintre paranteze
este adevarat) se va executa o singura data pachetul de program cuprins intre
acoalade { }

conditionarea alternativa

if (conditie sau conditii ) {


linii de program de executat;
} // sfarsit pachet program conditionat
else {
linii de program de executat;
} // sfarsit pachet program executat cand nu a fost indeplinita
conditia;
se executa ori partea de sub influenta if ori cea de sub influenta else.

Conditionarea pe o directie data de un selector:

switch (selector) // selector are o valoare egala cu (valoare1C.. valoare n)


case valoare1:
Utilizarea si programarea microcontrolerelor Pag 18
linii de program de executat; // daca selector = valoare1
CCCCCC..
break;
case valoare2:
linii de program de executat; // daca selector = valoare2
CCCCCC..
break;
case valoare n:
linii de program de executat; // daca selector = valoare n
CCCCCC..
break;
default:
linii de program de executat; // daca selector nu a gasit
echivalent
CCCCCC..
break;

Bucle de program conditionate de functii:


do {
linii de program de executat;
}
while (conditie sau conditii ) // sfarsit pachet program reciclat
de cate ori conditia sau conditiile sunt realizate (rezultatul functiilor dintre paranteze
este adevarat) se vaexecuta pachetul de program cuprins intre acoalade { } dar cel
putin o data . Testul se face dupa prima executie

while (conditie sau conditii ) {


linii de program de executat;
} // sfarsit pachet program reciclat
de cate ori conditia sau conditiile sunt realizate (rezultatul functiilor dintre paranteze
este adevarat) se va executa pachetul de program cuprins intre acoalade { }. Testul
se face inainte de prima executie, astfel se poate sari peste pachetul de program.
Un caz particular il reprezinta bucla permanenta la infinit atunci cand functia este
permanent adevarata (1)
while (1 ) {
linii de program de executat;
} // sfarsit pachet program reciclat

Bucle de program repetate de un numar cunoscut de ori:

for (variabila = valoare initiala ; variabila operator ; test de valoare finala) {


linii de program de executat;
} // sfarsit pachet program reciclat
operator poate fi orice operatie valida; in general incrementul sau decrementul ;
test de valoare finala , reprezinta in general o comparatie cu valoarea finala peste
care bucla nu se mai repeta. Un exemplu practic :
for (ii=0; ii++; ii<100) {
Utilizarea si programarea microcontrolerelor Pag 19
linii de program de executat;
} // sfarsit pachet program reciclat
Bucla se varepeta de 100 de ori pentru ii=0 pana la ii=99 (total 100 treceri)
Oforma diferita cu acelasi efect este combinatia dintre cele 2 forme ; si anume o
bucla conditionata de functii , dar variabila testata se schimba in cadrul buclei de
executie:
stabilirea valorii initiale ;
while (conditie sau conditii ) {
modificrea conditiei ; // operator asupra variabilei testate
linii de program de executat;
} // sfarsit pachet program reciclat
Acelasi exemplu practic devine:
ii=0;
while (ii<100) {
ii++; // operator asupra variabilei testate
linii de program de executat;
} // sfarsit pachet program reciclat
Bucla se varepeta de 100 de ori pentru ii=0 pana la ii=99 (total 100 treceri)
Citirea unei valori de la intrari :
variabila = PORTA.F3; “variabila” ia valoarea (0 sau1) a valorii logice prezente pe
pinul RA3; (pinul 3 din PORT-ul A).
variabila = PORTA; “variabila” ia valoarea (in intervalul 0 la 255) a valorii logice
prezente pe pinii portului A; (seteaza intreg octetul).
variabila = Read_ADC (3); daca intrarea AN3 a fost setata ca intrare analogica
valoarea variabilei va fi rezultatul conversiei analog numerice a tensiunii aflata la
pinul AN3

Aplicarea unei valori logice la iesire :

PORTA.F2 = 1 ; Aducerea pinului RA2 la valoarea Vdd


(curentul livrat spre masa (source)vafi limitat de consumator).
PORTA.F2 = 0 ; Aducerea pinului RA2 la valoarea GND
(curentul consumat (sink) vafi limitat de consumator).
PORTA = 112 ; sau
PORTA = 0b01110000; sau
PORTA = 0x70 ; Aducerea intregului port A la valoarea binara 01110000.
Daca unii dintre pinii RA0 la RA7 nu sunt prezenti fizici sau sunt
setati ca intrari valoarea lor ramane nemodificata.

Inserarea de comenzi direct in assambler:

Uneori este necesara inserarea intr-un program scris in limbaj C++ de comenzi
preluate din assambler.
Ori de cate ori trebuie sa inseram o comanda in assambler vom scrie prefixul asm:

asm CLRWDT ; // comanda vafi precedata de prefixul asm

sau daca inseram o subrutina aceasta vafi precedata de prefixul asm si delimitata
de acoalade.
Utilizarea si programarea microcontrolerelor Pag 20
Asm {
BANKSEL PMADRL ; Select Bank for PMCON registers
MOVLW PROG_ADDR_LO ;
MOVWF PMADRL ; Store LSB of address
MOVLW PROG_ADDR_HI ;
MOVWF PMADRH ; Store MSB of address
BCF PMCON1,CFGS ; Do not select Configuration Space
BSF PMCON1,RD ; Initiate read
MOVF PMDATL,W ; Get LSB of word
MOVWF PROG_DATA_LO ; Store in user location
MOVF PMDATH,W ; Get MSB of word
MOVWF PROG_DATA_HI ; Store in user location
}

Anumite blocuri de program ce trebuiesc executate de mai multe ori , la cerere pot fi
definite ca “ FUNCTII” sau “ subrutine”, ce pot fi chemate la cerere ori de cate ori
este nevoie:
void display data ( ) {
liniile de executat pentru a fi afisate datele;
CCCCCCCCC..
} // sfarsit subrutina . de aici programul se intoarce de unde a plecat
CCCCCC..
linii de executat;
display data ( ) ; // chemare subrutina
CCCCCC.. // continuare dupa executie subrutina.
linii de executat;
Atentie : variabilele ce sunt folosite in mai multe subrutine poarta numele de
variabile globale si se vor defini inainte de aparitia lor initiala.
Comentariile:
Comentariile sunt inportante pentru programator , ele fiind destinate sa expliciteze
denumirea unor variabile, a unor functii, a unor subrutine,setari, etc.
Cu cat mai explicite sunt comentariile intr-un program, cu atat va fi inteles si
refolosit, modificat , adaptat , mai usor dupa o perioada de timp.
Sunt 2 moduri de a insera comentarii intr-un program scris in C+.
Comentariu scurt , este precedat de 2 bare inclinate spre dreapta (slash):
C. // comentariuCC
este valabil de la cele 2 bare (pot fi dupa o linie de program terminata in ; dupa o
acoalada ;sau la inceput de linie goala ) si se termina din oficiu la sfarsitul liniei de
program.
Comentariu lung : Incepe cu perechea /* continua cu orice continut pe orice
lungime, sau numar de linii , si se termina cu aceeasi pereche asezata in ordine
inversa : */
Atentie: Nu ezitati sa folositi cat mai multe comentarii inserate in program.
Descrieti numele date variabilelor, explicati semnificatia setarilor registrelor speciale
si a celor de configurare, semnificatia unor functii sau ale conditionarilor, etc.

Utilizarea si programarea microcontrolerelor Pag 21


Capitolul 3: Definirea schemei de utilizare MCU
In primul rand trebuie plecat de la stabilirea cu claritate a cerintelor temei propuse,
dupa cum urmeaza:
- Cate intrari digitale sunt
- Cate intrari analogice sunt
- Cate iesiri digitale sunt
- Cate iesiri analogice sunt
- Daca sunt iesiri speciale (si de care tip :PWM, etc)
- Daca se foloseste reset sau nu,
- Ce sursa de alimentare este disponibila (tensiune / consum)
1. Dupa tensiunea de lucru se alege un integrat din familia:
- LV (low Voltage ) cu Vdd cuprins intre 1.8V si 3.6V
- Sau normal cu Vdd cuprins intre 2.3V si 5.5V
Atentie: la acumulatoarele Li-Ion tensiunea nominala este de 3.6V, dar incarcat un
acumulator Li-Ion are tensiunea de 4.15-4.2V, ceea ce este peste limita maxima a
familiei LV (low Voltage ).
2. Stbilirea numarului maxim de pini utilizati, dupa cum urmeaza:
2 pini pentru alimentare, respectiv GND (denumit uneori si Vss) si Vdd
Se aduna (sau nu ) pinul de RESET,se aduna numarul maxim de intrari , se aduna
numarul maxim de iesiri, se mai aduna sau nu un numar de pini pentru testari
functionare (LED-uri de stare) si eventual pentru “DEBUG” (depanare program
inuitial) .
Se verifica sa incadram numarul maxim de pini intr-unul din numerele disponibile.
Mentionam ca familia PIC produsa de MICROCIP se fabrica in capsule cu 8; 14; 18;
20; 28; 40, 44 etc pini.
Trebuie verificat ca numarul de pini sa fie suficienti intrucat exista capsule cu 20/ 28
pini care au insa cate doi pini la Vdd sau GND si astfel numarul total real este de 18
respectiv 26 pini.
Exemplu : 2 alimentari (Vdd si GND) ; 3 intrari (switch-uri), 3 iesiri (LED-uri), si un
pin de reset, rezulta un total de 9 pini , si vom fi obligati sa folosim o capsula cu
MINIM 14 pini . Ne mai raman astfel 5 pini pentru utilizari suplimentare (teste,
debug, etc).
Se aleg din procesoarele cu numarul de pini corespunzatori, cele ce au modulele
interne necesare , (de xemplu sa aiba ADC daca aplicatia necesita achizitia de date
analogice),acestea avand la randul lor rezolutia corespunzatoare aplicatiei, apoi se
verifica (estimativ) daca avem memorii suficiente ; RAM pentru variabile, ROM
pentru program si EEPROM pentru date fixe si eventual salvari de valori
intermediare.
Intr-un final se verifica (se estimeaza) daca frecventa de lucru a procesorului din
MCU este suficienta pentru a prelucra in timp real informatiile dorite.
Daca in continuare dupa aceste FILTRE au rezultat mai multe Microcontrolere
compatibile cu aplicatia pe care intentionam sa o incepem, vom aplica si criteriul
pretului de cost si al disponibilitatii sale in stocul propriu sau la magazinul preferat.
De retinut ca se recomanda inceperea programului cu un procesor cu memorie
extinsa , iar dupa finalizarea si compilarea programului se reia scrierea programului
pe MCU cu o memorie suficienta. Dupa compilare ( convertire din limbaj C++ in cod
masina , adica binar sau Hexazecimal) compilatorul emite un raport cu lungimea
memoriilor utilizate, asa cum se poate vedea in exemplul urmator:
Utilizarea si programarea microcontrolerelor Pag 22
in cazul de mai sus intrucat dupa compilare nu s-au utilizat decat 13% din RAM si
21% din ROM este evident ca se putea folosi si un procesor mai simplu (daca era si
mai ieftin).
Exemplu de procesoare compatibile pentru aplicatia anterioara (14 pini cu
modul ADC prezent) - PIC16F1503 cu 128 byt RAM ; 14 pini
- PIC16F1703 cu 256 byt RAM ; 14 pini
- PIC16F1704 cu 512 byt RAM ; 14 pini
- PIC16F1705 cu 1024 byt RAM ; 14 pini
Pe de alta parte daca la rularea programului avem probleme , ( programul a
fost scris incorect , cu greseli sau omisiunui ) va fi nevoie de inserarea unor
indicatori ,sau markere de puncte pe unde programul trece. Daca folosim
simulatoare (gen PROTEUS) nu avem nevoie de modificare de procesor , dar
daca aceste simulari nu sunt disponibile si testarile se fac “pe viu” pe placa de
test se poate apela la un procesor din aceeasi familie , (care sa contina
aceleasi blocuri interne), dar care sa aiba un numar marit de pini , eventual
memorie extinsa si sa fie compatibile. Programul va fi relativ similar , anumite
registre specifice recalculate, si bucati suplimentare de program inserate
pentru a afisa pe LED-uri sau panouri LCD, puncte de trecere sau valori de
variabile. Dupa finalizare se poate reveni la MCU dorit initial cu recalcularea
finala a programului. Un exemplu de microcontrolere compatibile pentru
exemplul anterior este:
- PIC16F1707 cu 256 byt RAM ; 20 pini
- PIC16F1713 cu 512 byt RAM ; 28 pini
- PIC16F1716 cu 1024 byt RAM ; 28 pini

Utilizarea si programarea microcontrolerelor Pag 23


Mentionam ca nu continutul si nici calitatea microcontrolerului reprezinta
criteriile care dicteaza pretul, findca in multe situatii un rol hotarator il are
cantitatea in care se produce/ vinde un MCU. Astfel nu trebuie sa va surprinda
daca un MCU cu 1024 Byti de RAM este mai ieftin decat cel cu 512Byti.

Dupa hotararea microcontrolerului de lucru (sau cel definit pentru probe) , se


va trece la repartizarea functiilor pe pini si intocmirea unei scheme
preliminare.
Mentionam aici ca majoritatea intrarilor sau iesirilor pot ocupa orice pin fizic,
functie de programare (setarea unor registre corespunzatoare). Doar anumiti
pini cu functii speciale trebuiesc sa ocupe pini predefiniti, cum ar fi GND, Vdd,
Reset , pini USB etcC
O atentie deosebita trebuie acordata modului de tratare a intrarilor (schema
propriuzisa de legare la microcontroler la circuitele de intrare sau iesire),
pentru a nu depasi valorile de tensiune permisa pe intrari , sau a curentilor la
iesiri.
In cele ce urmeaza vor fi prezentate cateva exemple de interfatare a intrarilor
si iesirilor, cu avantajele si dezavantajele fiecarui circuit, precum si situatiile in
care sunt indicate a se folosi.
Exemple de protectie pe intrarile analogice:

Fig 1 are o intrare neprotejata la depasiri accidentale, cum ar fi


supratensiunile de inductie sau la intreruperea rezistentei de la masa din divizor

fig 2 intrarea este protejata la max Vdd+0.2v


(Uf dioda schottky <0.2V) precum si la minim –0.2V

Utilizarea si programarea microcontrolerelor Pag 24


In fig 3 intrarea este protejata la maxim Uz si la minim –0.5V (dioda pe direct)
Este mai simpla dar poate strica linearitatea masurarii in special la tensiunile
ce se apropie de Vz.

Exemple de protectie pe intrarile logice:

Ofera protectie integrala , Condensatorul daca nu intarzie procese rapide este util in
a reduce varfurile de zgomot.

Este o protectie simpla , ieftina si asigura o protectie buna la Vdd dar la limita la
GND (Umin= –0.5V). Condensatorul daca nu intarzie procese rapide este util in a
reduce varfurile de zgomot.

Utilizarea si programarea microcontrolerelor Pag 25


Este cea mai buna si sigura solutie (cu legatura galvanica) Umin = 0.1V (Uce
saturat) iar max este dat chiar de Vdd (poate fi si intern legat prin configurarea Weak
Pull Up resistor )

Este cea mai buna solutie Umin = 0.1V (Uce saturat) iar max este dat chiar de Vdd
(poate fi si intern legat prin configurarea Weak Pull Up resistor ) Fata de situatia
anterioara circuitul de intrare poate avea masa separata, sau sa fie expus unui
mediu nociv.

Este o solutie simpla si buna dar nu protejeaza la tensiuni de inductie negative. Nu


poate fi folosita pe fire lungi.

Exemple de utilizare a iesirilor de uz general (push-pull):


Reamintim ca este obligatoriu sa nu depasiti curentul maxim pe iesire, pe intregul
port, sau pe capsula.

Iesire de tensiune pozitiva (activ in 1 logic) curentul prin sarcina este de tip sursa
(source)

Utilizarea si programarea microcontrolerelor Pag 26


Iesire de tensiune negativa (activ in 0 logic) curentul prin sarcina este spre masa
(sink)

Este interzisa folosirea spre masa a unei iesiri de tensiune negativa (activ in 0 logic)
atunci cand sarcina este legata la o tensiune mai mare decat Uiesire (Vdd).

Iesire de tensiune pozitiva (activ in 1 logic) pe sarcina inductiva. Este obligatoriu ca


sa se suprime tensiunea de autoinductie generata in sarcina la intrerupere.

Iesire de tensiune negativa (activ in 0 logic) pe sarcina inductiva. Este obligatoriu ca


sa se suprime tensiunea de autoinductie generata in sarcina la intrerupere.

Utilizarea si programarea microcontrolerelor Pag 27


Nici aici nu se permite folosirea spre masa a unei iesiri de tensiune negativa (activ
in 0 logic) atunci cand sarcina este legata la o tensiune mai mare decat Uiesire
(Vdd).

Atunci cand sarcina este legata la o tensiune mai mare decat Uiesire (Vdd) se va
folosi un tranzistor extern de separare / amplificare in tensiune pentru comanda
sarcinii la tensiune mare. Evident ca si aici este obligatoriu ca sa se suprime
tensiunea de autoinductie generata in sarcina la intrerupere.

Exemplul este similar cu cel prezentat anterior, doar ca s-a folosit un tranzistor de tip
MOSFET pentru amplificarea in tensiune (comanda sarcinii). Desi nu exista un
curent de grila (grila este izolata ), trebuie sa tinem cont ca exista o capacitate (un
condensator) intre Grila si Sursa ceea ce face sa apara un curent suplimentar la
ridicarea / coborarea tensiunii de iesire. R1 se dimensioneaza pentru limitarea
curentului de varf . R2 are valoare mare si se pune pentru descarcarea sarcinii din
Grila-Sursa si pentru mentinerea tranzistorului blocat atunci cand iesirea nu este
activa (in perioada de Reset si pana la configurare).
Din pacate Circuitul R1-Cgs este un circuit de temporizare care intarzie comanda.

Utilizarea si programarea microcontrolerelor Pag 28


Asa cum se vede in figura de mai sus , curentul de drena apare dupa tensiunea de
comanda. La frecvente mici (KHz) acest lucru nu este suparator. La frecvente mari ,
trebuiesc folosite dryvere de Mosfet in acest scop.

Nici aici nu se permite folosirea spre masa a unei iesiri de tensiune negativa (activ
in 0 logic) atunci cand sarcina este legata la o tensiune mai mare decat Uiesire (Vdd).

Solutia corecta este cu folosirea unui tranzistor extern de separare / amplificare in


tensiune pentru comanda sarcinii la tensiune mare.

Anumite microcontrolere permit configurarea iesirilor de tip “OPEN-DRAIN” ceea ce


le fac capabile sa asigure doar curent de masa (sink), nu si curenti din sursa. Acest
lucru permite legarea in paralel a 2 sau mai multe iesri, ce functioneaza ca un SI
logic .

Utilizarea si programarea microcontrolerelor Pag 29


Iesirea se afla in 1logic (adus la unu prin Rextern) doar cand toate iesirile legate in
paralel sunt in 1. Acest montaj se foloseste in general la magistrale de transmisie
date.
Dupa definitivarea schemei de principiu se trece la calculul registrilor aferenti
functionarii MCU in regimul dorit si apoi scrierea programului propriuzis, urmat de
compilarea acestuia.
Dupa rularea programului , si testarea sa , se recomanda desenarea cablajului final
(desen Printed Circuit Board (PCB)) . Daca la proiectarea PCB rezulta
recomandarea de relocare a unor pini (compatibili ca functie), acestia se vor
repozitiona astfel ca sa rezulte un cablaj cat mai simplu, robust si cu intersectii
putine. Evident ca programul se va modifica in asa fel ca functile sa fie adecvate
noilor alocari de pini.
Recomandari :
- PASTRATI versiunile intermediare pe parcursul elaborarii unui program.
Atribuiti-le nume corespunzatoare evolutiei sau modificarilor si descrieti
intotdeauna in comentarii, provenienta versiunii si modificarile survenite.
- Desenati schemele preliminare intr-un program de editare scheme adecvat
si disponibil. Daca nu va-ti putut permite procurarea cu licenta a unui
program , cum ar fi Proteus-ul , puteti folosi cu succes pentru desenare
Tiny Cad, program Open-Source cu licenta GNU gratuita, si care va
permite redesenarea schemelor prin relocare rapida de blocuri,
modificarea lor comoda, si stocarea lor.Pastrati-le in cel putin 2 locuri
pentru siguranta datelor.
- Toate intrarile si iesirile vor respecta valorile maxime permise pe MCU
(vezi tratarea intrarilor si iesirilor in situatii diverse).
- Daca sunt sanse sa faceti modificari in program dupa lipirea MCU in
montaj , proiectati de asa natura schema incat sa va permita programarea
ICSP, si prevedeti acest conector pe placa.

Utilizarea si programarea microcontrolerelor Pag 30


Capitolul 4: Utilizarea compilatorului MikroC PRO for PIC
De la bun inceput trebuie spus ca acest compilator este scris exclusiv pentru
programarea MCU din familia PIC produsa de Microcip Inc. Tinand insa seama ca
este una din cele mai simple si usor de inteles-utilizat familii de microcontrolere, am
considerat ca este adecvat sa pornim initilalizarea in acest domeniu din acest loc.
Mai mult, Microcip Inc. pune la dispozitia incepatorilor sub forma de program
DEMO versiunea neinregistrata de MikroC PRO for PIC , cu limitare la compilarea
unor programe ce ocupa un spatiu de maxim 2048 cuvinte in ROM.
Aceasta lungime este suficienta pentru mici programe demonstrative de functionare
blocuri; de gestionarea intrarilor / iesirilor, achizitia si afisarea unor date etc.
Atat programul cat si tutorialele se gasesc pe www.mikroe.com/mikroc/pic
De remarcat ca inainte de inceperea scrierii unui program trebuie sa definim
microcontrolerul pe care intentionam sa-l folosim. Deoarece lungimea memoriilor,
denumirea registrelor,etc difera de la procesor la procesor, si comenzile vor diferii, si
ca atare Compilerul trebuie sa analizeze corectitudinea si compatibilitatea
comenzilor cu fiecare procesor in parte.
Din acest punct urmatorii pasi sunt necesari:
• Instalati in computerul dumneavoastra MikroC PRO for PIC, minim versiunea
demo pentru inceput.
• Procurati-va un programator de microcontrolere PIC si instalati Sftware-ul
aferent . (Pentru incepatori cu resurse financiare reduse , recomandam
constructia si utilizarea Open-Programmer a carui documentatie completa si
gratuita, beneficiind de regulile licentelor gratuite GNU, le gasiti pe
http://openprog.altervista.org/OP_eng.html sau pe
http://sourceforge.net/projects/openprogrammer/ acest program precum si
suportul tehnic sunt gratuite , au fost testate si dau rezultate excelente.
Mentionam in continuare ca programul aferent ruleaza atat in Windows cat si
sub Linux).
• Descarcati si studiati (gratuit in versiunea Download-online) pe site-ul
producatorului

Utilizarea si programarea microcontrolerelor Pag 31


• Descarcati si studiati
PIC microcontrollers for beginners,too! Author: Nebojsa Matic
• Urmariti Exemplele ce urmeaza si incercati sa intelegeti pe baza comentariilor,
modul de rezolvare practica a unor cerinte de sistem propuse.
• Este preferabil ca aceste exemple sa fie incarcate in compilator si parcurse pas
cu pas sau compilate si testate pe bancul de proba. De asaemeni va
recomandam ca dupa intelegere, sa faceti modificari, minore sau majore asupra
programelor si sa urmariti daca scopul propus la modificare a fost atins. Este mai
usor sa intelegeti modul de rulare a unui program prin modificarea unui program
apropiat ce inca mai ruleaza. Nu uitati Lucrurile complicate sunt compuse
din subansamble simple. Astfel si programele complexe sunt compuse din
miniprograme simple.
• Programarea nu se invata citind documentatie , ci parcurgand comenzile, sau
exemplele cu calculatorul pornit si rulate direct in compilator.
• Nu in ultimul rand recomandam procurarea sau constructia unei placi de test
pentru scheme bazate pe microcontrolere. Aceste placi sunt prezentate si pe
site-ul producatorului (www.mikroe.com), dar puteti sa va construiti si singuri , cu
investitii minime, (sub 100ron) urmand ca dupa necesitati sa upgradati in timp
placa dupa necesitati. O descriere a unei astfel de placi o veti gasi in anexa .
• Inainte de a lucra cu orice microcontroler descarcati de pe site-ul producatorului,
foaia de catalog aferenta (datasheet) pentru a avea in permanenta acces la
datele tehnice aferente:
- Tensiuni pe intrari
- Curenti de iesiri
- Tensiuni alimentari
- Blocuri disponibile
- Calculul registrelor de configurare.etc

Utilizarea si programarea microcontrolerelor Pag 32


Exemplul 1 : Utilizarea iesirilor logice

Pasul 1 alegerea MCU:S-a utilizat un procesor simplu cu 14 pini 16F1503, a carui


arhitectura o prezentam in continuare :
(extras din datasheet 16F1503.pdf furnizat de Microcip Inc.)

Utilizarea si programarea microcontrolerelor Pag 33


Acest procesor dispune de 12 pini de uz general dispusi cate sase pe portul A si
sase pe portul C , pinul RA3 – are utilizare speciala , el poate fi folosit doar ca pin de
intrare logica sau de comanda interna pentru RESET.

Pasul 2- definirea schemei :Ne propunem sa setam portul A cu toti pinii in regim de
intrare si portul C cu toti pinii in regim de iesire . Ulterior vom atasa Trei LED-uri pe
RC0,RC1 si RC2.
Intrucat din Datasheet gasim ca fiecare iesire poate asigura un curent de 25mA pe
sarcina , ne vom limita pentru demonstratii sa alimentam LED-urile cu un curent de
10mA:
Vdd=5V;VfLED(rosu)=2V; Ur= Vdd-VfLED = 5V-2V; ILED= 10mA
Rled= (5-2)/0.01=300R ; alegem o rezistenta standard de 330R

Utilizarea si programarea microcontrolerelor Pag 34


Pasul 3- Deschiderea compilatorului MicroC for PIC , si setarea in <proiect > <Edit
proiect> configuration Word adica setarea de baza a regimului de functionare
pentru MCU
Pasul 4– Scrierea programului in C PRO:

/* Modul de testare iesiri cu 16F1503 - acesta este TITLU


Mclr on; PortulC setat ca iesiri
RAM 1% ; ROM 117 Word=6%
*/

void main() {
// nu avem nevoie de variabile la acest stadiu - aici era locul lor
//------------------ setarea registrelor-------------------

OSCCON = 0b01110010; // 8MHz INTERN


TRISA = 0xFF ; //all IN ; MCLR on RA 3
ANSELA =0x00; // intrarile sunt de tip logic
TRISC = 0; // all OUT
PORTC =0; // iesirea in zero la inceput
delay_ms(1000); //stai pe loc 1 secunda
PORTC =0xFF; // TOATE iesirile in 1 (LED-urile aprinse)
Utilizarea si programarea microcontrolerelor Pag 35
delay_ms(1000); //stai pe loc 1 secunda
PORTC =0; // iesirea in zero

while (1){ // bucla fara sfarsit


PORTC =0b00000001; // iesirea RC0 in 1 (LED-1 aprins)
delay_ms(1000); //stai pe loc 1 secunda
PORTC =0b00000010; // iesirea RC1 in 1 (LED-2 aprins)
delay_ms(1000); //stai pe loc 1 secunda
PORTC =0b00000100; // iesirea RC2 in 1 (LED-3 aprins)
delay_ms(1000); //stai pe loc 1 secunda
PORTC =0b00000010; // iesirea RC1 in 1 (LED-2 aprins)
delay_ms(1000); //stai pe loc 1 secunda
/* cele trei LED-uri se vor comporta ca un semafor
(acest comentariu este scris ca un comentariu lung) */

} // sfarsit bucla While

} // sfarsit subrutina Main

Pasul 5- Compilarea in <Build> <rebuild all source> se face compilarea propriuzisa


, programul va genera o serie de fisiere (inclusiv fisierul text al programului (listing-
ul) ) cat si codul masina necesar procesorului din MCU , fisier cu extensia .hex .
Pasul 6- Programarea Acest fisier va fi incarcat in programator si scris in MCU.
de aici testarea pe viu .
Pasul 7- Testarea D. URAAAAA primul program functioneaza !!!!!!!!

Oservatii: Subrutina void main () este obligatorie in orice program , si reprezinta


subrutina principala de lucru. Vom observa in exemplele urmatoare ca vor mai apare
si alte subrutine definite de programator, necesare indeplinirii anumitor functii
speciale pe parcursul programului.
Setarea registrelor TRIS ; PORT, OSCCON este descrisa in Datasheet la capitolele
aferente modului de utilizare al MCU: TRISA si PORTA la capitolul intrari –iesiri;
OSCCON la capitolul oscilatorul intern , etc.
Dupa cum se vede la intrarea in program (dupa reset procesorul executa la rand
liniile de program) se stabilesc mai intai variabilele ce vor fi folosite in program (nu
este cazul la exemplul 1); apoi se definesc registrele de configurare ale unor blocuri
interne (aici oscilator si intrari iesiri pe porturile A si C)
In continuare se intra intr-o bucla fara sfarsit care se repeta la infinit scrisa cu
functia while (1) care este adevarata permanent.
A mai aparut o functie uzuala scrisa in MikroC PRO for PIC si anume :
delay_ms(1000); unde sintaxa este obligatorie intr-una din cele 2 variante:
- ms –pentru milisecunde si
- us pentru microsecunde
iar intre paranteze se trece valoarea intarzierii. De mentionat ca functia accepta ca
parametru de intarziere doar o constanta (nu variabila).

Tema : - incercati sa schimbati timpii de intarziere din comanda delay ;


- mutati iesirile pe alti pini din portul C
- activati cate 2 LED-uri simultan, etc.
Utilizarea si programarea microcontrolerelor Pag 36
Exemplul 2 : Utilizarea intrarilor logice
Pentru simplificare vom prelua exemplul anterior la care adaugam o serie de trei
variabile ce urmeaza a pastra valoarea starilor logice aplicate la trei intrari din
portul A.
Schema aferenta (valabila si pentru exemplul anterior este data mai jos):

Scrierea programului in C PRO:


/* Modul de testare intrari cu 16F1503 - acesta este TITLU
PortulA setat ca intrari; Mclr on;
PortulC setat ca iesiri
RAM 3% ; ROM 95 Word=5%
*/
void main() {
short int led1=0; // variabila "led1" are valoarea alocata pt LED1
short int led2=0; // variabila "led2" are valoarea alocata pt LED2
short int led3=0; // variabila "led3" are valoarea alocata pt LED3
//------------------ setarea registrelor-------------------
OSCCON = 0b01110010; // 8MHz INTERN

Utilizarea si programarea microcontrolerelor Pag 37


TRISA = 0xFF ; //all IN ; MCLR on RA 3
ANSELA =0x00; // intrarile sunt de tip logic
TRISC = 0; // all OUT
PORTC =0; // iesirea in zero la inceput
delay_ms(1000); //stai pe loc 1 secunda
PORTC =0xFF; // TOATE iesirile in 1 (LED-urile aprinse)
delay_ms(1000); //stai pe loc 1 secunda
PORTC =0; // iesirea in zero

while (1){ // bucla fara sfarsit


if (PORTA.F0==1){
led1=1;
}
if (PORTA.F1==1){
led2=1;
}
if (PORTA.F2==1){
led3=1;
}
PORTC =(4*led3+2*led2+led1) ; // iesirile RC0 RC1 si RC2 depind de valoarea
// variabilelor setate prin swtch-urile de la intrari
delay_ms(1000); //stai pe loc 1 secunda

/* cele trei LED-uri vor confirma switch-urile apasate


(acest comentariu este scris ca un comentariu lung) */
} // sfarsit bucla While
} // sfarsit subrutina Main
//================ end listing =======================

Tema : - incercati sa schimbati timpii de intarziere din comanda delay ;


- schibati Switch-urile la masa (GND)

Utilizarea si programarea microcontrolerelor Pag 38


Exemplul 3 : Utilizarea intrarilor analogice
Pentru simplificare vom continua exemplul anterior la care adaugam un
potentiometru pe intrarea RA4 denumita si AN3
Schema aferenta (valabila si pentru exemplele anterioare este data mai jos):

Scrierea programului in C PRO:


In scopul citirii marimii analogice prezente la intrarea RA4 (cuprinse intre 0 si 5V),
va trebui sa setam registrele corespunzatoare utilizarii blocului ADC.
La sfarsitul capitolului “blocul ADC” din datasheet pentru PIC16F1503 la pag130,
avem un sumar al tuturor registrelor ce influenteaza functionarea blocului ADC.
Citind acest capitol si verificand pe rand fiecare registru vom constata ce registre
trebuiesc setate si cu ce valori.
La acest moment vom insista pe calculul acestor registre pentru a se intelege ,
modul de setare al lor. In exemplele ce vor urma , se vor vedea doar in “listing” ce
registre au trebuit modificate si valoarea finala.
Acest sumar este prezentat in continuare:

Utilizarea si programarea microcontrolerelor Pag 39


ADCON0 = nu se foloseste acum. Functia variabila = ADC _ Read (x) unde x este
una din intrarile analogice valide (in cazul nostru 3 ), preseteaza singura registrul .
FVRCON = nu se foloseste acum. Functia sus amintita functioneaza numai cu
Vref+ la Vdd
ADCON1 = 0b11010000 ; f conversie este de 1/16 pentru 8MHz si Vref+ la Vdd
ANSEL A= 0b00010000 ; RA4 intrare analogica.
INTCON = nu se foloseste acum. Nu generam intreruperi.

Listing-ul programului este urmatorul:


/* Modul de testare intrari cu 16F1503 - acesta este TITLU
PortulA setat ca intrari; Mclr on;
PortulC setat ca iesiri
RAM 3% ; ROM 95 Word=5%
*/

void main() {
short int led1=0; // variabila "led1" are valoarea alocata pt LED1
short int led2=0; // variabila "led2" are valoarea alocata pt LED2
short int led3=0; // variabila "led3" are valoarea alocata pt LED3
int tensiune =0;// in urma conversiei (citirii) tensiunii de la intrarea AN3
int i =0; // variabila curenta pentru bucla for
// situata pe RA4 va rezulta o valoare numerica pe 10 biti (max 1023)
//------------------ setarea registrelor-------------------

OSCCON = 0b01110010; // 8MHz INTERN


TRISA = 0xFF ; //all IN ; MCLR on RA 3
ANSELA = 0b00010000; // intrarile sunt de tip logic RA4 in AN3
ADCON1 = 0b11010000; // f= 1/16 pt 8MHz ; Vref+ = Vdd
TRISC = 0; // all OUT
PORTC =0; // iesirea in zero la inceput

Utilizarea si programarea microcontrolerelor Pag 40


delay_ms(1000); //stai pe loc 1 secunda
PORTC =0xFF; // TOATE iesirile in 1 (LED-urile aprinse)
delay_ms(1000); //stai pe loc 1 secunda
PORTC =0; // iesirea in zero

while (1){ // bucla fara sfarsit


tensiune =Adc_Read(3); // conversia tensiunii de intrare
if (PORTA.F0==1){
led1=1;
}
if (PORTA.F1==1){
led2=1;
}
if (PORTA.F2==1){
led3=1;
}
PORTC =(4*led3+2*led2+led1);// iesirile RC0 RC1 si RC2 depind de
// valoarea variabilelor setate prin swtch-urile de la intrari
for (i=0 ; i++ ; i<tensiune){ // arata LED-urile
delay_ms(1); //stai pe loc (1la 1023) milisecunde
} // sfarsit bucla de repetitie for
PORTC =0; // stinge LED-urile
delay_ms(200); //stai pe loc -raman stinse 0.2secunde

/* cele trei LED-uri vor confirma switch-urile apasate


timpul de afisare va depinde de pozitia potentimetrului
si anume de la 0 la 1.024 secunde
(acest comentariu este scris ca un comentariu lung) */

} // sfarsit bucla while

} // sfarsit subrutina main

Tema : - incercati sa schimbati timpii de intarziere din comanda delay ;


- incercati sa schimbati ordinea pinilor . Mutati in schema si in program locul
pinilor si recalculati registrele aferente si porturile.

Utilizarea si programarea microcontrolerelor Pag 41


Exemplul 4 : Utilizarea FVR si WDT

In acest exemplu s-a folosit modulul de tensiune de referinta interna FVR, utilizat in
special cand tensiunea de alimentare poate fi variabila (alimentarea din baterii).
Inrucat stabilitatea acestui modul este relativ modesta 4% , nu se recomanda
utilizarea lui atunci cand avem tensiuni de alimentare de calitate (obtinute din
stabilizatoare performante).
Acest program a fost scris sa supravegheze tensiunea a 2 baterii de acumulatoare
montate pe o masina . Atunci cand tensiunea pe bateria principala este >13.6V
(bateria se afla in regim de incarcare) , trebuie sa cupleze un releu (sau doua in
paralel, pentru cresterea curentului) si sa decupleze la o scadere sub 13.1V.
Acest “histerezis” este necesar pentru a nu apare oscilatii.
Tinand cont ca acest program are durata nedeterminata de lucru, (luni-ani) fara sa
fie intrerupt sau resetat , si ca acest montaj lucreaza in conditii cu posibilitati de
perturbatii , (paraziti, tensiuni de inductie ,etc) s-a activat modulul de supraveghere
WDT. In acest scop el a fost activat din Configuration-Word si a fost setat registrul
WDTCON corespunzator aplicatiei dorite , iar in program s-au introdus comenzi de
CLRWDT pentru resetarea periodica a registrului (contorului) WDT.
Nota: la urmarirea si intelegerea acestui program (ca de altfel la orice alt program)
incarcati si urmariti in paralel permanent datele din datasheet-ul corespunzator
procesorului utilizat ( in cazul de fata PIC12F1572)
Schema de utilizare este prezentata mai jos:

/* DBM 80A v4 cu 12F1572 ; Mclr off; 8MHz INTERN WDT activ


CFG =0E38 ;1E03 ; ROM= 475 -23% ; RAM = 21 -8%
RA2 out cuplare releu incarcare;
RA1 out BUZZER inversat fata de schema
RA5 out Led
RA0 = AN0 in Masura Bat2 DIVIZOR 15K / 5K1 Vref=5V
Utilizarea si programarea microcontrolerelor Pag 42
RA4 = AN3 in Masura Bat1 masurat =xVin
GP3 = INTRARE SW comanda PARALEL */
//***************************************************

unsigned Get_ADC(){
ADCON0.F1 = 1; // start conversion
while (ADCON0.F1); // wait for conversion
return (ADRESH << 8) + ADRESL; // return value
}

void main() {
long int cont =0;
int factor=350 ;
int i =0 ;
int puls =0 ;
short int ron =0;
short int buz =0;
short int paralel =0;
int cntsw =0;
long int contsw =0;
unsigned int contbp =0;
short int ledon =0;
short int buzr =0; // lucru buz
int vbat1,vbat2 = 800 ; // 15k + 5k1 tensiune baterie 862 =13.6v
OSCCON =0b01110010; // 8 MHz INTERN
TRISA = 0b00011001 ; //GP1;2;5 out ; GP0;4- in Ana ; SWitch on GP 3
ANSELA = 0b00010001 ; // A0; A3 SUNT IN ana
FVRCON =0 ; // Vref = 5V ; Atentie CITIRE ANALOGICA !
WDTCON = 0b00010111 ; // 2sec (VALOARE DE RESET)
ODCONA = 0 ; // OUT-urile SUNT PUSH-POLL
WPUA =0 ; // WEAK PULL UP DISABLE
OPTION_REG =0x8F; // no WPU ; WDT prescaler 18ms x 128
ADCON1 =0b11010000; // f=1/16 ; Vref = Vdd

LATA =0x00 ;
buz=0;
while(1){
asm CLRWDT ;
// TEST SW PARALEL
if (PORTA.F3 ==0 && paralel ==0){
cntsw++ ;
//if (cntsw >251){
// cntsw =251 ;
}

else {
cntsw =0;}
if (cntsw >200 && paralel ==0){ // cuplare paralela la cerere pt 1 min
Utilizarea si programarea microcontrolerelor Pag 43
paralel =1 ;
ledon =1 ;
contsw =0 ;
ron =1 ;
}
if (contsw >60000 && paralel ==1){ // de testat pt 1 minut
paralel =0 ;
ledon =0 ;
ron =0 ;
Delay_us(100);
contsw =0 ;
}
cont++; // contorizeaza nr cicluri
contsw++; // contorizeaza nr cicluri
if (cont >1000) {
cont=0;
}
// ADCON0 = 0x81 ; // an0 on GP0 cu Vref =5v
// ADCON0 = 0x83 ; // Start AD pe AN0
Delay_us(300);
//--------------------------------------------------------------------------
asm CLRWDT ;
ADCON0 = 0b00001111 ; // Start AD pe AN3
Delay_us(100);
vbat1 = Get_ADC(); // read AN0
vbat1 = vbat1*1.18 ;

Delay_us(300);
asm CLRWDT ;
ADCON0 = 0x03 ; // Start AD pe AN0
Delay_us(100);
vbat2 = Get_ADC(); // read AN1
vbat2 = vbat2*1.18 ;

//--------------------------------------------------------------------------
if ( vbat1 >793 && paralel ==0){ // >13.6v //828
ron=1 ; // cupleaza incarcarea
ledon=0;
contbp =0;
buzr=0; // permite sa sune a doua oara
}
if ( vbat1 <753 && paralel ==0){ // <13.1 v //794
ron=0 ; // decupleaza incarcarea
}
// *********** subrutina beep ******************************

if ( vbat2 <626 && buzr==0){ // <10.8 v 657 la11.27


ledon =1;
contbp++ ;
Utilizarea si programarea microcontrolerelor Pag 44
while ( contbp <4 ){
buz=1;

PORTA = ( ron*4 +ledon*32 + buz*2 );


delay_ms(500);
buz=0;
PORTA = ( ron*4 +ledon*32 + buz*2 );
delay_ms(200);
contbp++ ;
asm CLRWDT ;
}
Delay_ms(300);
if (contbp > 200){
contbp =0;
}
}
// *********** end subrutina beep *************************
if ( vbat2 >696) {
puls =10 ;
}
if (vbat2 >681 && vbat2 <696){ // 50 - 75%
puls = 150 ;

}
if (vbat2 >650 && vbat2 <681){ // 25 - 50%
puls = 300 ;
}
if (vbat2 >636 && vbat2 <650){ // 10 - 25%
puls = 750 ;
}
if (cont < puls && paralel ==0){
ledon =1;
}
if (vbat2 >626 && cont > puls && paralel ==0){
ledon =0;
}

PORTA = ( ron*4 +ledon*32 + buz*2 );


} // end while
} // end main

/* contbp++ ; // SUBRUTINA PENTRU DIFUZOR PIEZO


while (i <2000 && contbp <4 ){
buz=1;
delay_us(1);
PORTA = ( ron*4 +ledon*32 + buz*2 );
buz=0;
delay_us(105);
PORTA = ( ron*4 +ledon*32 + buz*2 );
Utilizarea si programarea microcontrolerelor Pag 45
i++;
Delay_us(300);
asm CLRWDT ;
}
i=0;
Delay_ms(300); */

Observati ca in acest program nu s-a mai folosit functia Adc_Read(x) folosita la


citirea de marimi analogice descrisa in exemplul 3 , Intrucat s-a folosit FVR pentru
tensiunea de referinta , s-a scris o subrutina speciala pentru acest scop:
unsigned Get_ADC(){
ADCON0.F1 = 1; // start conversion
while (ADCON0.F1); // wait for conversion
return (ADRESH << 8) + ADRESL; // return value
}
iar pentru apelarea ei s-a folosit:
ADCON0 = 0b00001111 ; // Start AD pe AN3
Delay_us(100);
vbat1 = Get_ADC(); // read AN0
vbat1 = vbat1*1.18 ;
De remarcat ca inainte de citirea analogica trebuie setat ADCON0 pentru a se
specifica ce intrare va fi citita si activarea citirii (vezi registru ADCON0).
Pentru variabila vbat2 s-a recalculat ADCON0.
De asemeni subrutina de difuzor piezo (varianta “ascunsa” la compilare) nu s-a
scris cu bucla for (D) {D} , ci cu while (D) { ..i++D}.
Se mai remarca citirea repetata a Switch-ului . daca este apasat timp de 250 citiri
succesive , se considera apasat. Acest lucru se face pentru evitarea citirii false a
unui parazit sau vibratiei contactelor inperfecte (debouncing).

Utilizarea si programarea microcontrolerelor Pag 46


Exemplul 5 : Utilizarea afisajelor cu 7 segmente

De multe ori avem nevoie sa afisam numere compuse din cateva cifre (de exemplu un
voltmetru cu 3 digiti). Exista o multitudine de dispozitive de afisare , inclusiv lampi ce
folosesc tensiuni mari si care au chiar si cate un terminal pentru fiecare cifra (10 cifre + 1
comun ). O alta varianta des folosita , o reprezinta afisarea cu LED-uri (perfect vizibila in
medii intunecate ) ,si care pot forma orice cifra zecimala (uneori si Hexazecimala ) din 7
segmente plus terminalul de referinta (comun). Astfel vom avea doar 8 terminale in loc de
11, dar avem nevoie de un decodor Binar-zecimal si un codor (codificator) din zecimal in 7
segmente. Dea lungul timpului s-au creat o serie de circuite specializate ce fac direct
conversia binar-7segmente cu etaje finale capabile sa asigure curentii de lucru pentru LED-
urile din afisaj. Pentru simplificarea legaturii cu panoul de afisaj cifrele ce formeaza
numarul, pot fi afisate pe rand cu o frecventa mai mare de 50 de iluminari pe secunda ,
astfel ca imaginea obtinuta sa fie stabila, iar numarul de fire sa fie 7 (cate unul pentru
pentru fiecare segment), plus cate un fir pentru fiecare terminal de referinta (comun).
Astfel pentru un numar compus din trei cifre , in loc de 3x7+1=22 fire, vom avea 7+3=10
fire. Acest mod de folosire a afisajelor poarta numele de strobare. Un exemplu de afisaj
destinat acestui mod de utilizare il aveti in continuare.

Daca folosim Microcontrolere, atat afisarea pe rand a cifrelor , cat si decodarea –codarea
binar 7 segmente pot fi facute doar prin programare fara componente electronice
suplimentare. Daca folosim afisoare LED ce folosesc tehnologii superbright , si ne
incadram in valorile maxime de iesire ale unui MCU (25mA),putem sa folosim un astfel de
afisaj utilizand doar 7 rezistente externe corespunzatoare utilizarii LED-urilor si numai 10
terminale de MCU.
In continuare vom exemplifica pe un Voltmetru realizat cu microcontrolerul PIC16F1824.
Schema de conexiuni este data mai jos:

Utilizarea si programarea microcontrolerelor Pag 47


Acest exemplu foloseste ca sursa de alimentare 2 baterii alcaline , ce au tensiunea de
alimentare standard de 3v, dar in realitate tensiunea pe element,variaza de la 1.4V(uzata)
pana la 1.6V (noua), adica intre 2.8-3.2V ceea ce inseamna o variatie de13%.
Din acest motiv alegem sa utilizam FVR intern ca sursa de referinta pentru Vref+.
Curentul pe fiecare segment este in jur de 1mA ce asigura o buna iluminare, rezultand
astfel un curent mediu de 5mA pe digit (curentul total este acelasi).

Programul propus este cel de mai jos:


/* Varianta pentru 3 digiti
TESTAT SI MERGE ***OK*** 14 RAM ; 885 ROM
3.8mA LA 3V CU LED VERDE OPD-S4031UPG-BW
Project:voltmetru cu 3 digit Katod comun direct drive

MCU: PIC16F1824 oscilator intern 8MHz


MCLR activ, tensiunea este masurata pe canalul ADC: AN0
RCO - RC6 SEGMENTE "a" LA "f" CU 680 ohm */

// Define digit selection port pins


sbit DG2 at RA2_bit; //KATOD S DIRECT DRIVE
sbit DG3 at RA1_bit; //KATOD Z DIRECT DRIVE
sbit DG4 at RA4_bit; //KATOD U DIRECT DRIVE
sbit SEG at RA5_bit; //segment C

unsigned short i, DD1, DD2, DD3, DD4;

Utilizarea si programarea microcontrolerelor Pag 48


//unsigned int ADC_Value;
long DisplayVolt, ADC_Value;

//-------------- Function to Return mask for common cathode 7-seg. display


unsigned short mask(unsigned short num) {
switch (num) {
case 0 : return 0x7B;
case 1 : return 0x48;
case 2 : return 0x2F;
case 3 : return 0x6D;
case 4 : return 0x5C;
case 5 : return 0x75;
case 6 : return 0x77;
case 7 : return 0x68;
case 8 : return 0x7F;
case 9 : return 0x7D;
} //case end
}

void Display_Data(){
for (i = 0; i<=10; i++) {
DG2 = 0; // Select sute Digit
DG3 = 1;
DG4 = 1;
if(DD2>63) SEG = 1; //segment g drivered by portA
PORTC = DD2;
delay_ms(5);
PORTC = 0; SEG = 0;
DG2 = 1; // Select Zeci Digit
DG3 = 0;
DG4 = 1;
if(DD3>63) SEG = 1;
PORTC= DD3;
delay_ms(5);
PORTC = 0;SEG = 0;
DG2 = 1; // Select unitati Digit
DG3 = 1;
DG4 = 0;
if(DD4>63) SEG = 1;
PORTC = DD4;
delay_ms(5);
DG4 = 1;
PORTC = 0; SEG = 0;
}
}

unsigned Get_ADC(){
ADCON0.F1 = 1; // start conversion
while (ADCON0.F1); // wait for conversion
return (ADRESH << 8) + ADRESL; // return value
}

void main() {
Utilizarea si programarea microcontrolerelor Pag 49
ANSELA = 0b00000001; // RA0 analog input
//ANSELB =0 ; // REST DIGITAL
ANSELC =0 ; // REST DIGITAL
TRISA = 0b00000001; // RA4, RA5 inputs
//TRISB = 0; //PORT B OUT
TRISC = 0x00;
OSCCON = 0b01110010 ; // CONFIG INTERNAL OSCILATOR PE 8 MHZ
DD2 = mask(0);
DD3 = mask(0);
DD4 = mask(0);

// Configure ADCON1
/* ADCON1.ADNREF = 0; // Vref- is connected to ground
ADCON1.ADCS0 = 0; // Use conversion clock, Fosc/16
ADCON1.ADCS1 = 0; // Fosc = 8MHZ
ADCON1.ADFM = 1; // result is right Justified */
ADCON1 =0b11010011 ; // VREF INTERN la FVR
/* // Configure ADCON0 for channel AN0
ADCON0.ADON = 1; // enable A/D converter */
ADCON0 = 0b00000001 ;
// Configure FVR to 2.048V
// FVRCON = 0b11000011 ; LA 16F1824
FVRCON = 0b11000010 ; // 1O PT 2048 mV
Display_Data(); // Display all zeros

do {
ADC_Value = Get_ADC();
DisplayVolt = ADC_Value * 98; // modificata scala : max 9.99
// DD1 = DisplayVolt/100000; // Extract DD1 "pentru 4 cifre"
// DD1 = mask(DD1);
DD2 = (DisplayVolt/10000)%10;
DD2 = mask(DD2);
DD3 = (DisplayVolt/1000)%10;
DD3 = mask(DD3);
DD4 = (DisplayVolt/100)%10;
DD4 = mask(DD4);
Display_Data();
} while(1); // end bucla do-while

} // end main

In acest listing urmariti:


- Folosirea comenzilor sbit ,de stabilire a unei iesiri sub forma de
variabila.Atentie ca functia PORTx.Fy poate da erori colaterale, si anume
desi seteaza corect bitul “y” din portul”x” poate deranja alti biti din portul x
setati anterior.Puteti sa scrieti miniprograme de iesire pe un port sub cele
doua forme pentru a sesiza diferentele.
- Folosirea de subrutine pentru functii repetabile :citire tensiune,afisare.
- Folosirea buclei fara sfarsit sub alta forma , si anume do{-}while(), fata de
while() {}.
- Folosirea operatorului % pentru extragerea restului.

Utilizarea si programarea microcontrolerelor Pag 50


- Folosirea functiei switch(){caseD.}.de selectie. Incercati programul si cu
10 randuri scrise cu functia if (){}.

Dupa scrierea , intelegerea si incercarea exemplului propus, recomandam


incercarea de a repozitiona pini de intrare iesire (necesar firesc dupa reproiectarea
cablajului imprimat), si rescrierea corespunzatoare a programului:
- modificarea registrelor afectate
- recalcularea bitilor de iesire (mask)
- Alimentarea schemei pe tensiune mare printr-un stabilizator de calitate.
Rescrierea programului pentru afisaj cu Anod comun.

Utilizarea si programarea microcontrolerelor Pag 51


Exemplul 6 : Utilizarea afisajelor matriciale LCD

Cand avem de afisat mai multe cifre sau caractere alfanumerice (texte),etc este
recomandat sa folosim un afisaj LCD cu generator de caractere intern . Acestea pot
comunica pe 6 sau 10 fire cu un MCU .
Cel mai raspandit (datorita raportului calitate/pret) este display-ul xx1602 ce are o
capacitate de afisare de 2 randuri ori16 caractere . De remarcat ca acest afisaj permite si
predefinirea unor semne grafice proprii pe o matrice de 7x5 pixeli.
Pentru regimul de lucru in mediu intunecat acestea au un dispozitiv de iluminat cu LED-uri.
Mentionam ca astfel de afisaje se fac si cu un rand (1601 ; 0801;etc ) , sau cu mai multe
randuri , cum ar fi 2004 care are 4 randuri a 20 caractere.
Pentru utilizare trebuie :
- Respectarea tensiunii de lucru a LCD (Pot fi pe 3.3V, 5V , etc.)
- Alimentare Back-light daca este cazul
- Daca MCU are alta tensiune de alimentare decat LCD trebuiesc translatoare de
tensiune (adaptoare), corespunzatoare.
- Stabilirea tipului de comunicare pe linia de date a LCD (4 sau 8 date)

Dupa hotarirea modului “hard” de utilizare in program trebuiesc realizati urmatorii pasi:
- Defidirea pinilor de dialog
- Initializarea (reset) a LCD
- Modul de lucru pentru “cursor”
- Stergerea initiala a ecranului
- Transmiterea mesajelor la coordonate: rand,caracter, text
- intelegeti si verificati functionarea functiilor de conversie, din variabila numerica
in text: bytetostr; inttostr; si longtostr.

Realizati schema de mai jos:

S-a folosit procesorul PIC16F1707, intrucat este unul dintre cele mai ieftine procesoare cu
20 pini, si care contine toate modulele tratate in acest curs.

Utilizarea si programarea microcontrolerelor Pag 52


// =========UTILIZARE DISPLAY LCD ================
// PIC 16F1707 ******* CU LCD 1602******** *****
// 8 MHz intern
// RA0 = AN0 INTRARE TENSIUNE;

// INSERT LCD
//lcd connction SE POT PERMUTA la desen PCB
sbit LCD_RS at LATC3_bit;
sbit LCD_EN at LATC2_bit;
sbit LCD_D4 at LATC4_bit;
sbit LCD_D5 at LATC5_bit;
sbit LCD_D6 at LATC6_bit;
sbit LCD_D7 at LATC7_bit;

sbit LCD_RS_Direction at TRISC3_bit;


sbit LCD_EN_Direction at TRISC2_bit;
sbit LCD_D4_Direction at TRISC4_bit;
sbit LCD_D5_Direction at TRISC5_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISC7_bit;
// End Lcd module connections

void main() {

unsigned long tensiune =0 ; // citire AN0 tensiune

char dtensiune[4] ; // text de tiparit

OSCCON = 0X72 ; // PT 8MHz intern PLL -off


ZCD1CON =0 ; // Zero cross disable
OPTION_REG =0x00; // Prescaler (1/8) is assigned to timer TMR0 ; WPU enable
// si bit 6 in 0 pt RA2 cazator
TRISA = 0xFF; //Ra0-RA5 are IN; RA3 = MCLR
ANSELA = 0x07; // Ra0-RA2 are IN Ana Ra4-RA5 are configured as digital
TRISB = 0; // All port B pins are configured as outputs
TRISC = 0x03; // RC0=AN4; RC1 in logic rest pins are configured as outputs
ANSELC = 0x01; // RC0=AN4
Lcd_Init(); // Initialize Lcd
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
lcd_out(1,1, "MartinStefanAron");

lcd_out(2,1, "Exemplul 6 LCD ");


delay_ms(2000); // pastreaza textul 2 secunde
// ============== SFARSIT AFISARE ===================

Lcd_Cmd(_LCD_CLEAR); // Clear display


delay_ms(500);
WPUA =0x30 ; // set pull up resistor on RA4 si RA5
ADCON1 = 0xD0; // f conv 1/16 pentru; CLK 4MHz ; RIGHT just Vref = Vdd
ADCON2 =0; // NO TRIGGER SELECT
Utilizarea si programarea microcontrolerelor Pag 53
do { // Endless loop

tensiune = Adc_Read(0);
delay_ms(10);

// ********** prescalare ************


tensiune= (30 + (tensiune/34));
// -----------------------------------
inttostr(tensiune,dtensiune); // conversia unui numar in caractere (sir)

dtensiune[(1)]= dtensiune[(2)] ; // shift text la stanga


dtensiune[(2)]= dtensiune[(3)] ; // shift text la stanga
dtensiune[(3)]='.' ; //
lcd_out(1,1, "Tensiune= "); lcd_out(1,11, dtensiune);
} while(1);
} //end main
=========================================.

Dupa compilare se constata ca acest program utilizeaza doar 25% din RAM si 56% din
ROM in conditia in care de fapt biblioteca de dialog cu LCD ocupa cel mai mult.
Rezulta in fapt ca puteti scrie programe suficient de mari in limita a 2K-word (varianta demo
a MikroC pro for PIC) putand folosi afisase. Afisajele pot fi definitive in schema , prezentand
in timpul lucrului valori de interes pentru utilizator, cum ar fi tensiuni, frecvente, timp,
temperaturi, etc, sau pot fi inserate doar pentru testarea functionarii unui program “debug” ,
inserand in anumite locuri de interes comenzi de afisare valori variabile sau linia de
program , ori valori aflate in diverse registre, urmand ca programul final sa le ignore in
timpul lucrului, daca nu exista pe montajul final ,modulul LCD; sau sa rescrieti programul
,eliminand aceste linii de ajutor (programul va rula mai repede) si eventual chiar
transcrierea lui (de cele mai multe ori doar recompilarea) pe alt procesor din familia lui.
Astfel daca fara afisaj este suficient un procesor cu 14 pini la care adaugam 6 pini de dialog
cu LCD (total 20) vom folosi PIC16F1707 la probe cu LCD, de 2 sau 4 randuri (B1602 ;
[HD44780] sau B2004, [TWI 2004] pentru 4 randuri). Iar montajul final poate avea
microcontrolerul PIC16F1703 sau PIC16F1704 ,functie de momoria necesara.
Vezi datele preliminare pentru familia de microcontrolere PIC16F170x :

Utilizarea si programarea microcontrolerelor Pag 54


Exemplul 7: Utilizare Timer0

In cazul de fata Timer0 s-a folosit pentru a masura timpul corect fara a depinde de
viteza de parcurgere a liniilor de program.
Desi timpul de executie a liniilor de program se poate calcula cu precizie , intrucat in
programe exista frecvent linii conditionate ( if (conditie)C.), aceste linii vor fi
executate sau sarite la rularea programului, functie de starea conditiei si astfel
durata de executie a unei bucle , nu va mai fi constanta.
De mentionat ca pentru simplitate in exemplul de mai jos sa folosit oscilatorul intern
ce are o precizie de doar 1%. Pentru scop didactic si chiar pentru executii in timp
real care nu sunt deranjate de aceasta precizie scazuta (1minut la o ora si jumatate)
ar fi suficient.
Daca insa dorim timpi lungi cu precizie exceptionala (pana la secunde pe an) este
suficient sa avem 2 pini liberi ( OSC1 si OSC2 adica pini 2 si 3) pe care sa-I
conectam la un cristal de Quart de * MHz, inpreuna cu 2 condensatori de 22pF.
Mentionam ca se poate folosi orice alt cristal cu recalcularea timpilor de lucru.
In cazul nostru schema de baza , pentru care s-a scris programul a fost urmatoarea:

Utilizarea si programarea microcontrolerelor Pag 55


Listing Program:
// =========CRONO TERMOSTAT ================
// PIC 16F1707 ******* CU LCD********

// lungime ROM 1871= 91% RAM 145= 44%


// 8 MHz intern
// RA0 = AN0 preset TEMPERATURA;
// RA1 = AN1 preset TIMP maxim;
// RA2 = AN2 intraRE senzor TEMPERATURA NTC 25K lA 20G ;
// RA4 = in digital Buton START WPU activ
// RA5 = in digital Buton STOP WPU activ
// RB4 = out puls tact functionare
// RB5 = out Comanda incalzire
// RB6 = out Buzeer
// RC0 = AN4 preset TACT TIMP ;

//lcd connction SE POT PERMUTA la desen PCB


sbit LCD_RS at LATC2_bit;
sbit LCD_EN at LATC5_bit;
sbit LCD_D4 at LATC4_bit;
sbit LCD_D5 at LATC3_bit;
sbit LCD_D6 at LATC6_bit;
sbit LCD_D7 at LATC7_bit;

sbit LCD_RS_Direction at TRISC2_bit;


sbit LCD_EN_Direction at TRISC5_bit;
sbit LCD_D4_Direction at TRISC4_bit;
sbit LCD_D5_Direction at TRISC3_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D7_Direction at TRISC7_bit;
// End Lcd module connections
sbit buzzer at LATB6_bit;
sbit buzzer_Direction at TRISB6_bit;
int i=0 ; // Define variable i pentru bucle FOR
int cntt0=0 ; // Define variable cnt

short int ledb4 =0; //out led puls


short int ledb7 =0; //out led TEST
short int incalzire =0; //out on RB5 comanda iesire
short int buzer =0; //out on RB6 comanda buzer
// short int ncnt=0 ;
//short int start=1 ; // buton start activ "0"
//short int stop=1 ; // buton stop activ "0"
short int sec=0 ;
short int activ =0 ;
short unsigned int minute=0 ;
unsigned short int beep=0 ;

void interrupt() {
Utilizarea si programarea microcontrolerelor Pag 56
INTCON.F7 = 0; //stop interrupt GIE=0
// asm CLRWDT ;
if(INTCON.F2 ==1){ // TEST TMR0 overflow T0IF is on (functioneaza )
cntt0++ ; // Interrupt causes cnt to be incremented by 1
if (cntt0 > 200 ){ //puls scurt
ledb4 =0 ;
}
if (cntt0 >2000){ // de testat valoare pt 1 sec
ledb4 =1 ;
if (sec< 1 && activ ==1){ // scade minut
sec =60;
minute-- ;
if (minute<0){
minute=0 ;
}
}
if (activ ==1){
sec-- ; // scade 1 sec
beep++;
}
cntt0 = 0 ;
}
// TMR0 = 0; // Timer TMR0 is returned its initial value

INTCON = 0xE0; // Bit GIE set; T0IE is set, bit T0IF is cleared
} // end interrupt TMR0 overflow
} // end interrupt

void main() {
unsigned valtimp =1 ; // preset timp citire AN1
unsigned ptact =0 ; // preset timp tact AN4
// unsigned ctemp =0 ; // citire temperatura citire AN2
unsigned rtemp =0 ; // temperatura reala prescalata
unsigned ptemp =0 ; // preset temperatura citire AN0
// unsigned long dpmin,dpmax,dpa;
char dptemp[4], drtemp[4],dmin[4],dsec[4],dptact[4];// text de tiparit
OSCCON = 0X68 ; // PT 4MHz intern
INTCON =0xE0; // enable : GIE ; TMR0 overflow ;
OPTION_REG =0x00; // Prescaler (1/8) is assigned to timer TMR0 ; WPU enable
// si bit 6 in 0 pt RA2 cazator
TRISA = 0xFF; //Ra0-RA5 are IN; RA3 = MCLR
ANSELA = 0x07; // Ra0-RA2 are IN Ana Ra4-RA5 are configured as digital
// CMCON0 = 0x07 ; // Comparatoarele oprite (intrari digitale)
TRISB = 0; // All port B pins are configured as outputs
TRISC = 0x03; // RC0=AN4; RC1 in logic rest pins are configured as outputs
ANSELC = 0x01; // RC0=AN4
WPUA =0x38 ; // set pull up resistor on RA3 ;RA4 si RA5
ADCON1 = 0xD0; // f conv 1/16 pentru; CLK 4MHz ; RIGHT just Vref = Vdd
Lcd_Init(); // Initialize Lcd
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
lcd_out(1,1, "MartinStefanAron");
delay_ms(200);
Utilizarea si programarea microcontrolerelor Pag 57
lcd_out(2,1, " == TERMOSTAT ==");
delay_ms(2000);
Lcd_Cmd(_LCD_CLEAR); // Clear display

// ============== SFARSIT AFISARE ===================


// Citire timp setat
do { // Endless loop
while (PORTA.F3==0 && activ ==0 ) { // citiri setari
valtimp = Adc_Read(1); // citire TIMP SETAT
minute = valtimp/10+1 ;
lcd_out(1,1, "timp setat=");
bytetostr(minute,dmin);
minute = minute ;
sec =0;
beep =0;
dmin[(0)]= dmin[(1)] ; // shift text la stanga // subrutina afisare minute
dmin[(1)]= dmin[(2)] ; // shift text la stanga
lcd_out(1,12, dmin);
lcd_out(1,14, "min"); // sfarsit afisare timp
// Citire PULS de timp setat
// ADCON0 = 0x11; //activat ADC
delay_ms(10);
// ADCON0 = 0x13; // ca sus si pornit conversie
ptact = Adc_Read(4); // citire TIMP SETAT
ptact = ptact /5; // dptact max = 200 sec = 3,5 minute
lcd_out(2,1, "tact setat=");
bytetostr(ptact,dptact); // poate if setat

lcd_out(2,12, dptact);
lcd_out(2,15, " s");
// sfarsit afisare PULS timp
} // end citiri setari
if (PORTA.F5 ==0 && activ ==0) { // start
Lcd_Cmd(_LCD_CLEAR); // Clear display
activ =1 ;
}
if (PORTA.F4 ==0 && activ ==1) { // stop
buzzer =1;
delay_ms(500);
buzzer =0;
activ =0 ;
}
if (minute==0 && sec==0 && activ ==1 ) {
activ =0 ;
for (i=0;i<3;i++){
buzzer =1;
delay_ms(500);
buzzer =0;
delay_ms(500);
}
}

if ( beep > (ptact-1) && activ ==1 ) {


Utilizarea si programarea microcontrolerelor Pag 58
buzzer =1;
delay_ms(300);
buzzer =0;
beep=0;
}
ptemp = Adc_Read(0);

delay_ms(1);

rtemp = Adc_Read(2);
delay_ms(1);
// ********** prescalare ************
ptemp= (30 + (ptemp/34));
rtemp = (20 +((1050-rtemp)*0.06)); // temp citita pe termistor NTC
// -----------------------------------

bytetostr(ptemp,dptemp); // SE FOLOSESTE INAINTE DE AFISARE

//******** NU CONVERTI MAI MULTE , DOAR CATE UNA**********

lcd_out(1,1, "Tset="); lcd_out(1,6, dptemp);


lcd_out(1,10, "min: " );
lcd_out(2,10, "sec: " );
bytetostr(sec,dsec);
dsec[(0)]= dsec[(1)] ; // shift text la stanga
dsec[(1)]= dsec[(2)] ; // shift text la stanga
lcd_out(2,15, dsec);

lcd_out(2,1,"Tact= " );
bytetostr(rtemp,drtemp);

lcd_out(2,6, drtemp);
bytetostr(minute,dmin);
dmin[(0)]= dmin[(1)] ; // shift text la stanga
dmin[(1)]= dmin[(2)] ; // shift text la stanga
lcd_out(1,15, dmin);

if (rtemp < ptemp && activ ==1){


incalzire =1;
}
else {
incalzire =0;
}

LATB = (ledb7*128 + buzer*64 + incalzire*32 + ledb4 *16 );

} while(1); // Endless loop

} //end main

Utilizarea si programarea microcontrolerelor Pag 59


Anexa1 : Tester logic auto cu voltmetru

Date generale: Utilizabil pentru masuratori de stari logice in domeniul auto


- masa (mai mic decat 0.5 sau 1V selectabil)
- nivel logic 5v pentru bus de date (intre 3.5V si 5.5V)
- prezenta tensiune (Mai mare de 10V)
- posibilitatea extinderii si la nivel peste 22V (pentru auto pe 24V)
- Starile logige selectate pot fi insotite de sunet

Executa masuratori rapide (peste 1000 de evaluari pe secunda) ceea ce permite analiza
pulsurilor pe linii , cum ar fi variatiile pe bus-urile de date (functionare CAN , etc) sau a
pulsurilor de 12V pe echipamentele comandate in factor de umplere (PWM) cum ar fi
reglajul iluminatului de bord , stopuri modulate in intensitate, turatie aeroterme , etc.
Datorita voltmetrului atasat poate citi cu precizie de 0.1V media tensiunii la varful testerului
.
De mentionat ca aparatul are o rezistenta de intrare de 100Kohmi ceea ce confera o buna
stabilitate la paraziti , dar nu afecteaza functionarea corecta a masinii testate , indiferent in
ce loc se efectueaza masuratorile.
De asemeni o calitate deosebita fata de testerele curente, o reprezinta faptul ca acest
aparat face diferenta intre “NIMIC” si “MASA”. Firul liber , desi are tensiune 0 nu este
confirmat de ledul (verde) de stare "0".
Aparatul se bazeaza pe 2 microcontrolere, si anume:
- voltmetrul foloseste PIC 16F1704 si este pornit doar la cerere , (consum
aproximativ 4mA in afisare medie)
- Testerul logic foloseste PIC12F675 ;acesta este alimentat permanent , dar la
zece minute daca nu este folosit intra singur in regim economic de “sleep”,
asteptand comutatorul de mod sa-l readuca la activitate.

Schema de baza este prezentata mai jos:

Utilizarea si programarea microcontrolerelor Pag 60


Listing-ul programului din partea logica (sonda) este:

// =================================================//
/* "logicTest v5" derivat din tlogig 12f675 v3led3
selectie mod de lucru cu Vminim 0.45 sau 1V pentru beep
are si citire logica cu beep selectat din mod
In analogic cu Vref la Vdd=3V Autooprire daca este nefolosit >10 minute
F1= pullup in ANA; F2=Buzz; F4=L1; F5=L2; F4&F5=L3; F3 =in SW; F0=inANA
4MHz intern 12F675 test go to SLEEP wake up cu GP3
merge numai cu WDT si BOD dezactivat S-A ACTIVAT CODE PROTECT
2.5 Khz Beep cu 2 citiri intre beep-uri aprox 5000 citiri/sec
Used RAM= 18= 38% ; ROM 712 = 70% */
short int cnt =0;
short int msel =0;
short int md =0;
short int vmic =62;
int i =0; //bucla for
long int toff =0;
void beep () {
for (i=0;i<1000;i++) {
GPIO.F2 = 1;
delay_us(100);
GPIO.F2 = 0;
delay_us(400);}}
void sleep (){
beep();delay_ms(300); beep() ; //anunt ca intra in sleep
CMCON =0x07;
VRCON =0x00;
GPIO = 0x00; //stingere iesiri inainte de sleep
Utilizarea si programarea microcontrolerelor Pag 61
INTCON =0x08; // activeaza interrupt "vede tasta "
asm SLEEP;
toff =0;
delay_ms(10); }
void interrupt() {
INTCON =0x00; //dezactivare interrupt
GPIO = 0x00;
delay_ms(100);
cnt =0;
while (GPIO.F3) {
cnt++; // cronometrare timp apasare
delay_ms(100);}
if (cnt >20 ) sleep (); // test apasare lunga pentru sleep
else {
msel++; // la apasare scurta schimba modul (msel) 0;1;2;3;4;
if (msel>=5) msel =0;
}
beep ();
switch (msel) { //afiseaza modul 0.5 sec la pornire sau schimbare
case 0 : GPIO =0x02;md =0;break ;
case 1 : GPIO =0x12;md =1;vmic =40;break ;
case 2 : GPIO =0x12;md =1;vmic =65;
delay_ms(300);GPIO =0x02; beep ();GPIO =0x12;break ;
case 3 : GPIO =0x22;md =2;break ;
case 4 : GPIO =0x32;md =3;break ;
}
delay_ms(500);
GPIO =0x02;
ANSEL =0x11;
CMCON =0x07;
IOC =0x08;
INTCON =0x88; //set GIE =1 ; set GPIE =1; reactivare interrupt
}
void main() {
int vin; //vin definit ca marime intrare
short int vbep =0; //variabila activare beep
//int i =0; // variabila bucla FOR
// int td =2; // td timp de delay
INTCON = 0x88; //set GIE =1 ; set GPIE =1;
IOC =0x08; // set IOC interrupt on change pe GP3
TRISIO = 0x09; // GP0 =AN0 GP3 = IN logic GP 1,2,4, OUT GP5 out Beep
ANSEL =0x11; //oscilator conversie 1/8 (51h pt 1/16) , AN0 intrare
CMCON = 0x07; // comparator oprit
GPIO =0x02 ; // initializarea iesirilor in 0 cu pullup la in ANA
ADCON0 =0x81; // referinta interna si activat ADC
ADCON0 =0x83; // start AD conversion set bit 1
while (1){
vin = Adc_Read(0); // Read AN0 input
if (vin >64 && vin <184) { // intre 1 si 3V ledurile stinse
GPIO =0x02;
toff++ ; if (toff >1790000 ) {sleep();
beep (); // iesire din sleep cu beep si afisarea starii
switch (msel) { //afiseaza modul 0.5 sec la pornire sau schimbare
Utilizarea si programarea microcontrolerelor Pag 62
case 0 : GPIO =0x02;md =0;break ;
case 1 : GPIO =0x12;md =1;vmic =32;break ;
case 2 : GPIO =0x12;md =1;vmic =52;
delay_ms(300);GPIO =0x02; beep ();GPIO =0x12;break ;
case 3 : GPIO =0x22;md =2;break ;
case 4 : GPIO =0x32;md =3;break ;
}
delay_ms(500);
GPIO =0x02;
ANSEL =0x11;
CMCON =0x07;
IOC =0x08;
INTCON =0x88; //set GIE =1 ; set GPIE =1; reactivare interrupt
}} // sa execute subrutina de interrupt} // nefolosit >10 minute
if (vin > 550 ) { // peste 10V aprinde LED 3
if (md==3) // verifica daca trebuie cu Beep
vbep =1; // activeaza beep la sfarsit de bucla for
GPIO =0x32; // Aprinde led 3
toff =0;}
if (vin < vmic){ // pentru Vin < 0.5 sau 1V aprinde led 1
if (md==1) // verifica daca trebuie cu Beep
vbep =1; // activeaza beep la sfarsit de bucla for
toff =0; GPIO =0x12;} // Aprinde led 1
if (vin > 184 && vin < 307){ //intre 3 -5V aprinde Led 2
if (md==2) // verifica daca trebuie cu Beep
vbep =1; // activeaza beep la sfarsit de bucla for
toff =0; GPIO =0x22; }// aprinde led 2
vin = Adc_Read(0); // Read AN0 input
if (vin > 550 ) { // peste 10V aprinde LED 3
if (md==3) // verifica daca trebuie cu Beep
vbep =1; // activeaza beep la sfarsit de bucla for
GPIO =0x32; // Aprinde led 3
toff =0;}
if (vin < vmic){ // pentru Vin < 0.5 sau 1V aprinde led 1
if (md==1) // verifica daca trebuie cu Beep
vbep =1; // activeaza beep la sfarsit de bucla for
toff =0; GPIO =0x12;} // Aprinde led 1
if (vin > 184 && vin < 307){ //intre 3 -5V aprinde Led 2
if (md==2) // verifica daca trebuie cu Beep
vbep =1; // activeaza beep la sfarsit de bucla for
toff =0; GPIO =0x22; }// aprinde led 2
if (vbep ==1) { // verifica daca trebuie cu Beep
GPIO.F2 =1; delay_us(120); GPIO.F2 =0;} //puls pt beep activ 100usec
vbep =0;
} // end while
} // end main

//=============== end listing ==================//

Utilizarea si programarea microcontrolerelor Pag 63


Listing-ul programului din partea de masura analogica este:

// =================================================//

/* TESTAT SI MERGE ***OK*** 14 RAM ; 885 ROM


3.8mA LA 3V CU LED VERDE OPD-S4031UPG-BW
Project:voltmetru cu 3 digit Katod comun direct drive
MCU: PIC16F1704 running at 8MHz internal clock
MCLR is enabled, and the input voltage is
measured through AN0 ADC channel
RCO - RC6 SEGMENTE "a" LA "f" CU 680 ohm */

// Define digit selection port pins


sbit DG2 at RA2_bit; //KATOD S DIRECT DRIVE
sbit DG3 at RA1_bit; //KATOD Z DIRECT DRIVE
sbit DG4 at RA4_bit; //KATOD U DIRECT DRIVE
sbit SEG at RA5_bit; //segment C

unsigned short i, DD2, DD3, DD4;

long DisplayVolt, ADC_Value;

//-------------- Function to Return mask for common cathode 7-seg. display


unsigned short mask(unsigned short num) {
switch (num) {
case 0 : return 0x7B;
case 1 : return 0x48;
case 2 : return 0x2F;
case 3 : return 0x6D;
case 4 : return 0x5C;
case 5 : return 0x75;
case 6 : return 0x77;
case 7 : return 0x68;
case 8 : return 0x7F;
case 9 : return 0x7D;
} //case end
}

void Display_Data(){
for (i = 0; i<=10; i++) {
DG2 = 0; // Select sute Digit
DG3 = 1;
DG4 = 1;
if(DD2>63) SEG = 1; //segment g drivered by portA
PORTC = DD2;
delay_ms(5);
PORTC = 0; SEG = 0;
DG2 = 1; // Select Zeci Digit
DG3 = 0;
DG4 = 1;
if(DD3>63) SEG = 1;
PORTC= DD3;
delay_ms(5);
Utilizarea si programarea microcontrolerelor Pag 64
PORTC = 0;SEG = 0;
DG2 = 1; // Select unitati Digit
DG3 = 1;
DG4 = 0;
if(DD4>63) SEG = 1;
PORTC = DD4;
delay_ms(5);
DG4 = 1;
PORTC = 0; SEG = 0;
}
}

unsigned Get_ADC(){
ADCON0.F1 = 1; // start conversion
while (ADCON0.F1); // wait for conversion
return (ADRESH << 8) + ADRESL; // return value
}

void main() {

ANSELA = 0b00000001; // RA0 analog input


//ANSELB =0 ; // REST DIGITAL
ANSELC =0 ; // REST DIGITAL
TRISA = 0b00000001; // RA0 inputs rest output
TRISC = 0x00; // portC output
OSCCON = 0b01110010 ; // CONFIG INTERNAL OSCILATOR PE 8 MHZ
DD2 = mask(0);
DD3 = mask(0);
DD4 = mask(0);

ADCON1 =0b11010011 ; // VREF INTERN la FVR


/* // Configure ADCON0 for channel AN0
ADCON0.ADON = 1; // enable A/D converter */
ADCON0 = 0b00000001 ;
// Configure FVR to 2.048 V
FVRCON = 0b11000010 ; // 1O PT 2048 mV
Display_Data(); // Display all zeros

do {
ADC_Value = Get_ADC();
DisplayVolt = ADC_Value * 98; // modificata scala : max 9.99
DD2 = (DisplayVolt/10000)%10;
DD2 = mask(DD2);
DD3 = (DisplayVolt/1000)%10;
DD3 = mask(DD3);
DD4 = (DisplayVolt/100)%10;
DD4 = mask(DD4);
Display_Data();
} while(1); // end while

} // end main

//=============== end listing ==================//


Utilizarea si programarea microcontrolerelor Pag 65
pentru partea logica desenele sunt prezentate mai jos , testerul fiind montat intr-o incinta de
“textmarker”:

Desen PCB pentru imprimare LASER

Desen echipare

Pentru partea de voltmetru , alimentare si sunet desenele sunt prezentate mai jos,
montarea s-a facut intr- carcasa de tip Z-71/B (cod TME).

Desen PCB inversat pentru tiparire pe imprimanta Laser

Utilizarea si programarea microcontrolerelor Pag 66


Desen echipare

Fata SMD cu PCB echipat

Utilizarea si programarea microcontrolerelor Pag 67


Fata piese cu PCB echipat

Manualul de utilizare pentru acest aparat :


Pornirea se face prin apasarea scurta (prox 0.3-0.5 sec) pe SW de functii.
testerul va porni in "modul" din care a fost oprit, afisind acest mod.
Oprirea testerului:
1. se poate face fortat apasand continuu circa 3-5sec SW de functii,
2. Oprirea automata , daca timp de peste 10 sec aparatul nu a semnalat nici un regim diferit de
asteptare. ( toate led-urile au fost stinse)
(In ambele cazuri se aud 2 beep-uri fara lumini pe led si aparatul se opreste).
Modurile de lucru :
Dupa apasarea SW de functii apare 1-2 beep-uri insotit de 1-2 flash-uri pe led-uri:

sunet Led-uri U pt Verde aprins U pt Galben U pt Rosu aprins


aprins
1 beep stinse < 1V 3.5-5.1V > 10V
1 beep 0.5s VERDE < 0.5V cu sunet 3.5-5.1V > 10V
2 beep 2x0.5s < 1V cu sunet 3.5-5.1V > 10V
VERDE
1 beep 0.5s < 1V 3.5-5.1V cu > 10V
GALBEN sunet
1 beep 0.5s ROSU < 1V 3.5-5.1V > 10V cu sunet
2 beep 2x0.5s ROSU < 1V 3.5-5.1V > 22V cu sunet
* ultimul rand nu este activ in softul de baza prezentat in acest manual( prag 22V pt LED rosu)

In orice moment la cerere (prin apasarea Sw de pe cutia cu afisaj numeric) se poate citi tensiunea la
tester. Cu testerul pornit dar varful in gol tensiunea trebuie sa fie de circa 1.2V +- 0.1V.
Cu testerul oprit si varful in gol tensiunea trebuie sa fie de circa 0V .

Utilizarea si programarea microcontrolerelor Pag 68


In orice moment la cerere (prin apasarea Sw de pe cutia cu afisaj numeric) se poate citi tensiunea
bateriei daca varful testerul este conectat la punctul de masura baterie (gaura din colt dreapta jos).
Testerul poate fi utilizat la 12 sau 24 V (pragul superior ; LED rosu, ramane la >10V).
Poate fi conectat gresit , Masa la +12V; nu se defecteaza dar toate indicatiile sunt in Verde <1V.
Poate fi folosit ca tester de continuitate (led verde , eventual cu sunet ) la contact intre varf si fir de
masa.

Recomandari: Pentru cei ce doresc modificari / inbunatartiri, (upgrade) la acest aparat:


* intrucat partea de masura logica utilizeaza ca referinta Vdd baterie (2.8-3.2V),puteti
incerca utilizarea unui procesor cu FVR intern utilizat ca Vref+, si retranscrierea programului .
De exemplu in loc de PIC12F675 utilizat in proiectul de fata se recomanda PIC12F822;
PIC12F840; PIC12F1540; avand in vedere sa dezactivati soft toate modulele interne ce nu
sunt utilizate (ZCB,DAC,CCP etc) pentru a nu creste consumul pe capsula , si in special de
a rescrie subrutina de intrare si iesire din starea "SLEEP" trecand procesorul la frecventa
redusa in asteptare. Consumul in stand-by nu are voie sa depaseasca 50nA.De asemenea
in "SLEEP" trebuie oprit si FVR si ADC.

* Pentru cei ce doresc utilizarea aparatului si la 24V, cu indicare a LED-ului Rosu la peste
22 V (reamintim ca in lipsa acestei modificari aparatul poate fi utilizat la 24V cu indicare
insa a pragului superior la peste 10V) se poate adauga inca un "mod" de lucru suplimentar
switch (msel) unde msel=5 si confirmat la selectie cu 2 Beep ; 2Flash LED rosu .

Utilizarea si programarea microcontrolerelor Pag 69


Anexa 2 : Programator Open Programmer
Pentru amatorii ce doresc realizarea unui programator relativ ieftin, de calitate si cu suport
tehnic de inalta calitate, recomand in mod deosebit constructia Open Programmer V0.9.1
a carui documentatie completa o puteti gasi pe site-ul openprog.altervista.org sau pe
sourceforge.net .

Reamintesc ca acest programator beneficiaza de licenta gratuita GNU, de un suport


tehnic deosebit sustinut de D-l Alberto Maccioni (proiectantul acestui produs) si de multi
membrii de pe forumul atasat. Periodic lista de controlere si de memorii compatibile, a fost
upgradata , in plus daca este de constructie proprie, poate fi reparat in caz ca sufera avarii.
Acest lucru nu este exclus daca avem in vedere ca acest programator poate intra sa "scrie"
microcontrolere sau memorii direct pe placa "PCB" in regim ICSP . Daca insa pe aceste
placi sunt defecte ascunse (se intampla la montajele noi manufacturate) sau nu sunt corect
pregatite pentru scrierea pe placa, riscul de a distruge PIC18F2550 de pe programator sau
sursa de Vdd ; Vpp sunt mari. Atat timp cat, programatorul este de constructie proprie ,un
astfel de incident nedorit se remediaza usor prin simpla inlocuire a unui tranzistor, sau chiar
a microcontrolerului PIC18F2550 pe care este bine sa-l montati pe soclu. In cazul unui
programaor achizitionat finit (PICKIT 3 produs de Microcip sau clone , ori K150, etc, ),
acesta devine inutilizabil dupa orice defectare, intrucat nu exista componente de schimb
(chiar daca procesorul are nume cunoscut, soft-ul aferent este protejat).
Recomand de asemeni urmatoarele modificari fata de documentatia din site-ul indicat:
* Pentru Rezistentele R11-R21 se vor folosi rezistente de 220R in loc de 100R, aceasta
modificare reducand riscul de distrugere pentru PIC18F2550 la ICSP.
* Montarea pe socluri pentru Q1 si Q2 expuse la aceleasi riscuri la programarea
defectuasa in regim ICSP.
* Inlocuirea bobinei L1=100uH cu o bobina avand inductanta de 150-180uH, acest lucru
inbunatatind regimul de functionare al sursei de Vpp.
* C1=100uF, va avea tensiunea de lucru mai mare sau egala cu 25V si daca este posibil va
fi de joasa inpedanta (ESR mic)
* Conectorul 4 =ICSP-IN poate fi modificat pe placa de baza si inlocuit cu legaturile de la
ICSP-out de pe extensii, intrucat putin probabil sa se faca Upgrade de soft, direct pe placa
de baza , in schimb veti utiliza programarea ICSP fregvent fara extensii.

* Pe extensiile de tensiune mica (LowVoltage) in loc de LD1086V33 se poate utiliza orice


integrat specializat pe 3.3V cum ar fi AP1117-3.3 , LD1117xx33, L78L33 , cu respectarea
functionalitatii pinilor.
* In loc de socluri pe placile de extensie (si pe placa de baza) se pot folosi siruri de pini de
TIP ZL262-xx (NINGI) in care se pot infige socluri ZIF corespunzatori, astfel cu doar 2
socluri zif , unul ingust 7.62mm de 28pini si unul lat de 40pini, se pot acoperi toate
extensiile.

Prezentam mai jos pozele unui astfel de programator realizat dupa documentatia amintita
si cu modificarile recomandate:

Utilizarea si programarea microcontrolerelor Pag 70


Au fost prezentate doar extensiile strict necesare pentru inceput. Dupa cum am recomandat
mai inainte, se poate folosi un singur set de socluri zif , ce pot fi folosite pe toate extensiile.

Pentru circuitele SMD de tip SO s-au confectionat 2 ZIF -SO , unul pentru 8-16 pini si
celalalt pentru 18-28 pini folosind conectorii de extensie de pe mother-board -ul unui PC .
Mentionam ca acesti conectori au pasul de 1.27 mm si au contacte aurite de foarte buna
calitate. Prin sectionare si utilizarea corespunzatoare (vezi pozele anexate) , puteti obtine
cu cateva ore de munca si fara investitii 2 socluri de calitate deosebita.

Utilizarea si programarea microcontrolerelor Pag 71


Soclurile SO astfel obtinute.

Contactele aferente (spatele) pentru a fi utilizate in ZIF-urile Dual-in-Line

Conectorii de pe mother -board.

Utilizarea si programarea microcontrolerelor Pag 72


Voi prezenta in continuare si 2 placi de test, necesare la probarea circuitelor dupa ce au
fost scrise.
Recomand sa incepeti cu ceva simplu si pe masura ce avansati, iar necesitatile cresc, dar
si rezultatele, puteti trece la ceva mai complex, sau chiar la o placa profesionala.

Placa de test (PIC Tester 01) cu Vdd 5V si Va=12v, 16LED-uri, 8 switch-uri si un driver
ULN2003.

O varianta inbunatatita a testerului (PIC Tester 02) contine:


* sursa Va interna cu potentiometru de reglaj intre 10V si 15V (pentru a simula un
acumulator auto de la descarcat complet la incarcat maxim);
* sursa Vdd selectabila intre 3.3V fixa; 5V fixa; 1.3-4.2V reglabila (pentru a simula baterii
noi sau uzate , alcaline sau Litiu-Ion).
* Cele patru surse pot fi monitorizate cu un voltmetru digital intern
* 3 Push-buton la GND cu rezistente de Pull-up; 5 Dip-Switch cu rezistente de Pull-up;
4 Push-buton la Vdd cu rezistente de Pull-down ; cu Vdd selectabil la Vdd procesor.
* 12 (8+2+2) LED-uri de stare logica active in unu logic.
* Buzer incorporat activ in unu logic.
* Driver ULN2003 (7 finali de 700mA cu intrare CMOS).
* Inversor CD 4049 (contine 6 inversoare , cu Vdd intre 3-15V)
* 2 potentiometre multitura si unul monotura pentru tensiuni variabile.
* Un soclu ZIF universal de 40 pini accesibil cu cate 2 sau 3 contacte pe fiecare pin.
* Se pot folosi o serie de perifericele suplimentare externe, cum ar fi : afisaje cu 7
segmente sau LCD , dupa necesarul aplicatiei.
Atat programatorul cat si cele 2 variante de placi pentru testari, reprezinta doar idei ce pot
fi urmate in caz ca le considerati utile.
Dupa fantezia si necesitatile fiecaruia ele pot fi dezvoltate si inbunatatite.

Utilizarea si programarea microcontrolerelor Pag 73


Utilizarea si programarea microcontrolerelor Pag 74

You might also like