Documente Academic
Documente Profesional
Documente Cultură
Sisteme Incorporate
n exemple simple
Refereni tiinifici:
Prof. dr. ing. Ioan P. Mihu
Sl. dr. ing. Beriliu Ilie
Chenar ISBN
Cuprins
Prefa ............................................................................................................ 1
1. Introducere ................................................................................................. 2
1.1. Introducere ......................................................................................... 2
1.2. Mediul de dezvoltare MPLAB IDE ................................................... 2
1.2.1. Selectarea dispozitivului............................................................. 3
1.2.2. Crearea proiectului ..................................................................... 4
1.2.3. Setarea limbajului de programare (alegerea compilatorului
folosit pentru proiect) ........................................................................... 5
1.2.4. Denumirea proiectului ................................................................ 6
1.2.5. Adugarea fiierelor n proiect ................................................... 7
1.2.6. Setrile microcontrolerului ....................................................... 10
1.3. Descriere general - Low Pin Count Demo Board ......................... 11
1.4. Schema electric - Low Pin Count Demo Board ............................ 12
1.5. Layout - Low Pin Count Demo Board ........................................... 13
1.6. Lista de materiale - Low Pin Count Demo Board ............................ 13
1.7. Probleme propuse ............................................................................. 14
2. Embedded C ............................................................................................. 15
2.1. Introducere ....................................................................................... 15
2.2. Sintaxa limbajului C ......................................................................... 17
2.2.1. Comentarii ................................................................................ 17
2.2.2. Directive de pre-procesare........................................................ 18
2.2.3. Variabile ................................................................................... 20
2.2.4. Funcii ....................................................................................... 22
2.2.5. Operatori ................................................................................... 23
2.2.6. Instruciuni de control .............................................................. 27
2.3. Programare embedded ...................................................................... 29
2.3.1. Bucla infinit ............................................................................ 29
Prefa
Noiunea de sistem incorporat este folosit tot mai des n zilele noastre n
domeniul hardware i software. Un sistem incorporat poate fi definit ca i
sistem dedicat, proiectat pentru a fi capabil s realizeze o anumit funcie
ntr-un sistem mai complex, iar pentru aceasta sarcin are nevoie de intrri
prin care s citeasc starea sistemului i de ieiri pentru controlul unor
procese.
Tot mai multe dispozitive folosite zi de zi au la baz un microcontroler.
Chiar i un banal filtru de cafea sau un usctor de pr au la baza un astfel de
circuit (compus dintr-o parte hardware pe care ruleaz o aplicaie software).
Tocmai din acest motiv nelegerea funcionrii unui microcontroler nu ar
trebui s lipseasc din bagajul de cunotine al unui absolvent de
electronic, electromecanic sau calculatoare.
Aceast carte are ca i scop introducerea cititorului n lumea embedded prin
nite pai progresivi, mprii n zece capitole care trateaz noiunile de
baz necesare realizrii unor proiecte simple care au la baz un
microcontroler.
Cartea dorete s fie un suport pentru orice student care o parcurge i un
punct de plecare pentru cei care vor s cunoasc lumea embedded n detaliu
prin studiu individual ulterior.
Cartea este scris de nite foti studeni pentru actualii studeni, ntr-un
format pe care l-au considerat potrivit ca un prim contact al cititorului cu
noiuni despre microcontroler i programarea acestuia.
Dorim s mulumim fotilor notri profesori Mihu P. Ioan, Ilie Beriliu si
Toma Emanoil care nu de puine ori au fost mai mult dect profesori pentru
noi n timpul anilor de studiu i un permanent sprijin n cadrul activitilor
noastre. Mulumim i companiei Continental i n special lui Sorin Ban
pentru sprijinul acordat n vederea tipririi acestei cri. Nu n ultimul rnd
mulumim tuturor celor care au avut rbdarea necesar pentru a citi
materialul i s-au asigurat de forma lui corect nainte de tiprire.
Sibiu, 21 ianuarie 2012
1. Introducere
1.1. Introducere
Aceast lucrare se dorete a fi un suport pentru disciplina Sisteme
Incorporate i prezint o abordare practic asupra aplicaiilor cu
microcontrolere. Pentru a putea parcurge cu uurin acest material, cititorul
are nevoie de cunotine de baz n electronic i noiuni introductive de
programare. Materialul cuprinde paii necesari pentru a porni la drum n
acest domeniu, oferind o perspectiv asupra celor dou componente majore:
electronic i software. Pentru ilustrarea acestor concepte prin proiecte
practice am ales folosirea unei plci de dezvoltare relativ uor de gsit pe
pia i anume placa Low Pin Count Demo Board, produs de firma
Microchip. Aceasta are la baz un microcontroler pe 8 bii numit
PIC16F690.
n prima parte a acestui material vom prezenta uneltele de baz de care
avem nevoie pentru a ncepe un proiect (mediul de dezvoltare, placa i
microcontrolerul folosit, bazele limbajului C), trecnd apoi la descrierea
celor mai uzuale module ale unui microcontroler (porturi GPIO, module
timer, ADC). Fiecare capitol este structurat n dou pri: prima conine
informaiile teoretice necesare, iar a doua cerine practice (cu explicaii i
fragmente de cod) i probleme propuse.
1.2. Mediul de dezvoltare MPLAB IDE
MPLAB IDE este o aplicaie PC oferit de ctre firma Microchip i are ca
scop facilitarea dezvoltrii de cod pentru proiectele care folosesc
microcontrolerele acestei firme. Funcionalitatea de baz a mediului de
dezvoltare incorporeaz editare de cod, compilare, suport flashing i debug.
Mediul de dezvoltare este disponibil gratuit pe site-ul firmei Microchip
(www.microchip.com). Pentru realizarea acestui material am folosit
MPLAB IDE versiunea 8.73.
Pentru a putea folosi funciile mediului de dezvoltare este necesar crearea
unui proiect ce conine sursele aplicaiei ct i setrile microcontrolerului.
Pentru a crea un proiect trebuie realizai urmtorii pai:
Introducere
Introducere
Introducere
5
Figura 1-4: Fereastra de selecie microcontroler
Introducere
Pasul doi din Project Wizard este setarea compilatorului folosit. Bifai
csua Show all installed toolsuite i selectai HI-TECH Universal
ToolSuite din lista de unelte active. Dup selectarea toolsuite-ului, n
fereastra Toolsuite Contents va aprea HI-TECH ANSI C Compiler. n
cazul n care n dreptul acestuia apare un X rou, locaia compilatorului
trebuie specificat. Dac instalarea s-a fcut n prealabil n directorul
Microchip, locaia executabilului asociat va fi cea implicit. Compilatorul
poate fi instalat n orice alt director, iar n acest caz, cu ajutorul butonului
Browse, se va indica manual locaia executabilului.
Compilatorul HI-TECH Universal ToolSuite va fi folosit pentru toate
proiectele prezentate n acest material i se descarc separat de mediul
MPLAB de pe site-ul firmei Microchip. Varianta LITE este gratuit i ofer
funcionalitate de baz, optimizrile de cod fiind ns dezactivate dup 60 de
zile.
Se apas butonul Next.
1.2.4. Denumirea proiectului
Pasul trei din Project Wizard presupune alegerea unui nume pentru proiectul
la care lucrm ct i locaia unde acesta va fi salvat. Alegerea locaiei se
face folosind butonul Browse.
Figura 1-6: Alegerea locaiei proiectului
Introducere
Introducere
Se pot aduga sau terge fiiere din proiect, accesnd meniul adiional din
fereastra proiectului, prin apsarea butonului dreapta a mouse-ului. Spre
exemplu, prin click dreapta pe cmpul Source Files, putem aduga un fiier
nou.
Pentru a crea un fiier C i a-l aduga n proiect, efectuai urmtorii pai:
Activai meniul File / New. Va aprea o fereastr Untitled n care se poate
edita poriunea de cod dorit. Orice fiier C trebuie s aib urmtorul
schelet:
Introducere
9
Figura 1-10: Crearea unui fiier nou
10
Introducere
Figura 1-12: Fiierul main.c adugat in proiect
Introducere
11
12
Introducere
Introducere
13
14
U1-Microcontroler
P1
J1
JP1-JP5
Introducere
1
1
1
5
2. Embedded C
2.1. Introducere
Pentru a realiza controlul unui sistem incorporat cu microcontroler, avem
nevoie de un cod software care s ruleze pe acesta. Programul trebuie s se
foloseasc de resursele hardware disponibile, colectnd informaii prin
intermediul intrrilor (push-buttons, senzori digitali sau analogici, reele de
comunicaie .a.), n funcie de acestea controlnd ieirile (leduri, display
LCD, motoare .a.). Pentru a realiza acest lucru, fiecare procesor ofer un
set de instruciuni de baz, numite instruciuni main, cu ajutorul crora se
pot crea aplicaii. Dei aplicaiile pot fi scrise direct, folosind instruciuni
main, numrul redus de instruciuni existente duce la o complexitate mare
a codului. Din acest motiv, majoritatea aplicaiilor sunt scrise n limbaje de
programare de nivel nalt, folosindu-se un compilator pentru a transforma
codul scris de noi, n limbaj main. Cel mai rspndit limbaj folosit n
aplicaiile embedded este ANSI C.
Pentru a ne familiariza cu sintaxa limbajului C i cu elementele specifice
programrii embedded, n cele ce urmeaz vom analiza i explica un scurt
exemplu de cod. Mai multe informaii despre limbajul C i particulariti ale
programrii embedded putei gsi n Anexa 1.
16
EXEMPLUL 01:
#include "SI_L03_ex_01.h"
/* defines of constants and macros */
#define NUMAR_MAGIC 32
#define SUMA(a,b) ((a)+(b))
/* variable definitions */
unsigned int suma_01, suma_02;
/* function declarations */
void functie_01(void);
unsigned int suma(unsigned char b, unsigned int a);
/* function definitions */
void main()
{
unsigned char numar_01;
unsigned int numar_02;
numar_01 = 7;
numar_02 = 15;
suma_01 = SUMA(7,NUMAR_MAGIC);
suma_02 = suma(numar_01, numar_02);
if(suma_01 > suma_02)
{
functie_01();
}
else
{
suma_01 = suma_02 + NUMAR_MAGIC;
}
while(1)
{
;
}
} /* end main() function */
Embedded C
Embedded C
17
void functie_01(void)
{
; /* do nothing */
}
unsigned int suma(unsigned char b, unsigned int a)
{
unsigned int c;
c = a + b;
return c;
}
2.2. Sintaxa limbajului C
2.2.1. Comentarii
Folosindu-ne de exemplul anterior, putem ncepe s analizm codul i s
identificm componentele principale.
Probabil cel mai la ndemn element al sintaxei C sunt comentariile. Un
comentariu este un text introdus n cod pentru a aduga explicaii
suplimentare sau pentru a delimita prile componente ale unui cod. n
exemplul anterior se pot observa mai multe comentarii, acestea fiind textele
ncepute cu /* i ncheiate cu */. Comentariile de aceast form se pot
ntinde pe mai multe rnduri, atta timp ct sunt cuprinse ntre cele dou
delimitatoare:
/* tot acest text
este un comentariu pe mai multe rnduri */
Mai exist i posibilitatea de a folosi comentarii de o linie. Acestea sunt
ncepute cu // i se ncheie unde se termin rndul respectiv:
// acesta este un comentariu de un rnd
// pe noul rnd, delimitatorul fiind folosit din nou
Se recomand folosirea comentariilor pentru a aduga explicaii
suplimentare asupra funcionalitii implementate ntr-un cod. O
documentare bun a codului duce la o nelegere mai uoar i mai rapid n
18
Embedded C
cazul n care codul este folosit de o alt persoan sau dac este revizuit dup
o perioad mai lung de timp.
2.2.2. Directive de pre-procesare
Continum analiza exemplului cu codul folosit pe primul rnd:
#include "SI_L03_ex_01.h"
Acest rnd este o directiv de pre-procesare. nainte ca un fiier s fie
compilat, are loc etapa de pre-procesare. n acest moment, toate directivele
de pre-procesare, adic toate rndurile ce ncep cu #, sunt nlocuite cu cod C
normal. Spre exemplu, directiva #include va fi nlocuit cu ntreg coninutul
fiierului scris ntre ghilimele. La includerea unui fiier, n loc de ghilimele,
se pot folosi i semnele mai mare i mai mic dup cum urmeaz:
<SI_L03_exemplu_01.h>.
n codul din exemplu se mai pot observa alte directive de preprocesare:
#define NUMAR_MAGIC 32
Acest tip de instruciune (#define) duce la nlocuirea numelui simbolic din
stnga (NUMAR_MAGIC) cu codul din dreapta (32). Astfel, codul a =
NUMAR_MAGIC este echivalent cu a = 32. i atunci, ntrebare evident
este de ce s mai complicm codul folosind un nume simbolic n locul
valorii numerice? S presupunem c, spre deosebire de exemplul anterior,
constanta 32 este folosit n mai multe locuri n cod, n mai multe fiiere.
Dac, dup un anumit timp, decidem s schimbm valoarea 32 cu 77? n
acest moment, va trebui s cutm prin tot codul locurile unde am folosit
numrul 32 i s l nlocuim cu 77. Dac definim un nume simbolic pentru
valoarea 32, precum n exemplu, este suficient s schimbm valoarea ntr-un
singur loc, pre-procesarea nlocuind apoi n tot codul. Cnd folosim acest tip
de definire spunem despre numele simbolic asignat c este o constant.
Alt mod pentru a crea constante este prin folosirea calificativului const.
Explicaii despre acest calificativ se pot gsi n Anexa 1. n cele ce urmeaz
vom analiza un scurt exemplu n care sunt folosite cele dou tipuri de
constante. n imaginile de mai jos putem observa n partea stng codul C
iar n partea dreapt instruciunile n cod main rezultate dup compilare.
Embedded C
19
Figura 2-1: Comparaie ntre #define i const
Din acest exemplu (imaginea de mai sus) este evident c folosirea unei
constante prin #define produce un cod mai rapid, att n cazul n care
constantele se adun cu variabile care au 16 bii (cazul de sus) ct i n cazul
n care se adun cu variabile pe 8 bii (cazul de jos).
Ca i exemplu, pentru lucrul cu variabile pe 8 bii, instruciunea C:
sum_01 = variable + MACRO;
20
Embedded C
((a)+(b))
Embedded C
21
Tip de date
char
short
int
long
22
Embedded C
este mai complex dect cea a numerelor ntregi, motiv pentru care nu va fi
explicat n acest material.
2.2.4. Funcii
O funcie este o bucat delimitat de cod ce ndeplinete o sarcin specific
i poate fi executat din mai multe puncte ale aplicaiei. Funciile sunt
folosite pentru a mpri codul aplicaiei n mai multe subrutine generice.
Spre exemplu, dac ntr-un program avem nevoie s calculm de mai multe
ori rdcinile unei ecuaii de gradul al doilea, n loc s scriem de fiecare
dat toate calculele pentru aflarea acestora, vom crea o funcie generic ce
primete ca parametri de intrare ecuaia i returneaz rdcinile, aceasta
urmnd s fie chemat din codul principal de cte ori este nevoie.
n exemplul dat, se pot observa trei funcii: functie_01, suma i main. Putem
observa pentru functie_01 i suma c acestea apar de mai multe ori n cod.
Prima folosire a acestora este momentul n care sunt declarate:
void functie_01(void);
unsigned int suma(unsigned char b, unsigned int a);
Se observ c n momentul n care funciile sunt declarate, nu este specificat
i codul acestora. Declaraia unei funcii implic doar stabilirea numelui
acesteia, tipului returnat i tipurile datelor primite ca i parametri de intrare.
Tipul de date returnat este specificat nainte de numele generic al funciei iar
parametri sunt specificai n interiorul parantezelor, dup numele funciei.
Dac dorim ca o funcie s primeasc mai muli parametri, acetia vor fi
separai prin virgul.
Pentru prima funcie, numele este functie_01, tipul de date returnat este
void, iar funcia primete ca i parametru de intrare tot tipul void. Prin void
ca tip returnat nelegem c funcia nu returneaz nici o valoare iar void ca i
parametru de intrare nseamn c funcia nu primete nici un parametru.
Spre deosebire de functie_01, suma returneaz o variabil de tip unsigned
int i primete doi parametri, unul unsigned char iar al doilea unsigned int.
Al doilea moment n care ntlnim cele dou funcii, putem observa c
suntem n codul propriu-zis. Aici spunem despre funcii c sunt apelate sau
chemate. Chiar dac nc nu am definit codul funciilor, acestea au fost
declarate n prealabil i astfel compilatorul poate verifica dac ele sunt
Embedded C
23
24
Embedded C
Embedded C
25
26
Deplasare la dreapta pe bii
Embedded C
>>
a >> b
Embedded C
27
28
Embedded C
Embedded C
29
do
{
... /* cod */
} while( expresie );
Alt instruciune ce poate fi folosit pentru a crea bucle este instruciunea
for dup cum urmeaz:
int i;
for(i = 0; i < 10; i++)
{
... /* cod */
}
Prima observaie n ceea ce privete aceast instruciune este faptul c avem
nevoie de o variabil declarat pentru a realiza bucla. La nceputul buclei,
variabilei i i este atribuit valoarea 0. Condiia de execuie a buclei este i <
10 iar dup execuia codului, se incrementeaz variabila de control i++.
Astfel, codul din interiorul acoladelor se va executa atta timp ct i este mai
mic dect 10 i anume de 10 ori.
2.3. Programare embedded
Limbajul C este un limbaj general, menit s ruleze pe orice platform. Din
aceste motive, n funcie de locul unde este folosit, apar anumite
particulariti.
n aplicaiile create pentru sisteme incorporate se pot observa o serie de
particulariti ce vor fi prezentate n cele ce urmeaz.
2.3.1. Bucla infinit
n cazul unui program scris special pentru un PC, nu trebuie acordat mare
atenie asupra contextului unde acesta va rula, deoarece sistemul de operare
se va ocupa de aceste detalii. n cazul unui sistem incorporat, unde gestiunea
aceasta nu este realizat, avem nevoie s introducem n cod diverse
mecanisme de control. Bucla infinit este unul din aceste mecanisme i prin
folosirea ei se evit rechemarea funciei main de fiecare dat dup ce
execuia a ajuns la captul acesteia. Spre exemplu, dac n codul prezentat la
nceputul capitolului nu am fi adugat o bucl infinit la captul funciei
main, programul ar fi fost reluat la nesfrit. Dac, spre exemplu, primele
30
Embedded C
Embedded C
31
Operaiile pe bii sunt att de des folosite nct exist i denumiri specifice
pentru scrierea unui bit cu o anumit valoare. Se spune despre un bit n care
se scrie 1 c acesta este setat, iar cnd scriem 0 c este resetat.
Alt denumire des folosit este aceea de flag. Un flag este un bit, un registru
sau o variabil indicatoare de stare. Dac spunem c flag-ul unei anumite
ntreruperi a fost setat, nseamn c bitul indicator de stare corelat acelei
ntreruperi a luat valoarea 1.
2.4. Aplicaie propus
Pentru a putea vedea cum se comport codul din exemplul prezentat, avem
opiunea de a l rula folosind un debugger simulat de ctre mediul de
dezvoltare MPLAB. Pentru a realiza acest lucru, trebuie urmai paii:
a) Creai un proiect i adugai un fiier ce conine codul prezentat la
nceputul acestui capitol. Compilai proiectul accesnd meniul Project /
Build sau butonul
b) Din meniul principal, selectai Debugger, apoi Select Tool iar apoi
opiunea 4.MPLAB SIM. Observai noul panou de comand aprut.
c) Pentru a opri execuia unui program, avem posibilitatea de a selecta
breakpoints. Acestea se adaug prin click dublu pe o anumit linie de
cod. Adugai un breakpoint pe linia 18 (numar_01 = 7;).
d) Din meniul debugger-ului, apsai butonul Run
aplicaia.
pentru a porni
e) Din bara de meniu principal, selectai View iar apoi Watch. Noua
fereastr deschis ne ofer un mod de a vedea valorile variabilelor sau a
regitrilor. Din dreptul butonului Add Symbol, selectai variabilele
folosite n codul principal: numar_01, numar_02, suma_01 i suma_02,
ct i cele folosite n funcia suma: a, b i c. Dup selectarea fiecrei
variabile, trebuie apsat butonul Add Symbol.
f) Folosind butonul Step Into
din panoul debugger-ului, rulai
aplicaie pn la bucla infinit i observai irul de execuie al acesteia
ct i valorile luate de ctre variabile.
32
Embedded C
b=
b=
c=
c=
3. Prezentare C
3.1. Introducere
n cadrul acestui capitol va fi prezentat pe scurt microcontrolerul
PIC16F690.
3.2. Caracteristici principale PIC16F690
a) RISC CPU:
35 instruciuni single-word.
Toate instruciunile sunt single-cycle, exceptnd instruciunile de
salt (program branch) care sunt two-cycle.
Frecvena maxim de funcionare: DC 20MHz clock input; DC 200ns ciclul de instruciune.
Memorie program (flash) 4Kx14 words. 4K de cuvinte a cte 14 bii
pentru codificarea instruciunilor, ceea ce nseamn o memorie
program de 7K.
Memorie de date (RAM) 256x8 bytes. Adic, 265 de bytes (octei) a
cte 8 bii fiecare, memorie folosit pentru salvarea variabilelor.
Configuraia pinilor compatibil fie pentru capsul de 20 pini PDIP,
fie pentru SOIC, SSOP i QFN.
b) Periferice digitale:
Timer 0: 8-bit timer/counter cu pre-scalar pe 8 bii.
Timer 1: 16-bit timer/counter cu pre-scalar. Numrtorul (counter)
poate fi incrementat i n modul Sleep.
Timer 2: 8-bit timer/counter cu registru de perioad pe 8 bii, prescalar i post-scalar.
Dou module Enhanced Capture/Compare/PWM: Capture pe 16 bii
cu rezoluie maxim 12.5ns; Compare pe 16 bii cu rezoluie maxim
200ns; PWM cu rezoluie pe 10 bii i frecven maxim de 20KHz.
Comunicare serial sincron prin SPI (Master mode sau Slave mode) i
I2C (Master/Slave mode).
Comunicare serial asincron/sincron prin UART/SCI cu posibilitatea
de detecie 9-bit address mode. Suport modul RS-232, RS-485 i
LIN2.0.
Prezentare C
34
Prezentare C
35
RA0/AN0/C1I
N+
/ICSPDAT/UL
PWU
RA1/AN1/C12I
N0/VREF/ICSPCL
K
RA2/AN2/T0C
LK
/INT/C1OUT
RA3/MCLR/VP
P
Funcie
Tip
intrare
Tip ieire
RA0
TTL
CMOS
AN0
CIN+
ICSPDAT
ULPWU
AN
AN
TTL
AN
CMOS
-
RA1
TTL
CMOS
AN1
C12IN0-
AN
AN
VREF
AN
ICSPCLK
ST
RA2
ST
CMOS
AN2
T0CLK
INT
C1OUT
AN
ST
ST
-
CMOS
RA3
TTL
MCLR
VPP
ST
HV
Descriere
Pin general de intrare ieire. Activare
individual de pull-up.
Intrarea 0 A/D.
Intrarea pozitiv a comparatorului C1.
ICSP DATA I/O.
Intrare de Wake-up Ultra Low-Power.
Pin general de intrare ieire. Activare
individual de pull-up.
Intrarea 1 A/D.
Intrarea negativ a comparatorului C1 sau C2.
Tensiune de referin extern pentru
convertorul A/D.
Ceas pentru ICSP.
Pin general de intrare ieire. Activare
individual de pull-up.
Intrarea 2 A/D.
Ceas de intrare pentru Timer0.
Pin pentru ntrerupere extern.
Ieirea comparatorului C1.
Pin general de intrare ieire. Activare
individual de pull-up.
Pin de RESET general cu pull-up intern.
Tensiunea de programare.
Prezentare C
36
RA4/AN3/T1G
/OSC2/CLKOU
T
RA5/T1CLK/
OSC1/CLKIN
RB4/AN10/
SDI/SDA
RB5/AN11/RX/
DT
RB6/SCK/SCL
RB7/TX/CK
RC0/AN4/C2I
N+
RC1/AN5/C12I
N1-
RC2/AN6/C12I
N2-/P1D
RC3/AN7/C12I
N3-/P1C
RC4/C2OUT/P
1B
RA4
TTL
CMOS
AN3
TIG
OSC2
CLKOUT
AN
ST
-
XTAL
CMOS
RA5
TTL
CMOS
T1CLK
OSC1
CLKIN
ST
ST
XTAL
-
RB4
TTL
CMOS
AN10
SDI
SDA
AN
ST
ST
OD
RB5
TTL
CMOS
AN11
RX
DT
AN
ST
ST
CMOS
RB6
TTL
CMOS
SCK
SCL
ST
ST
CMOS
OD
RB7
TTL
CMOS
TX
CK
ST
CMOS
CMOS
RC0
ST
CMOS
AN4
C2IN+
AN
AN
RC1
ST
CMOS
AN5
C12IN1-
AN
AN
RC2
ST
CMOS
AN6
C12IN2P1D
AN
AN
-
CMOS
RC3
ST
CMOS
AN7
C12IN3P1C
AN
AN
-
CMOS
RC4
ST
CMOS
C2OUT
P1B
CMOS
CMOS
Prezentare C
RC5/CCP1/P1
A
RC6/AN8/SS
RC7/AN9/SDO
37
RC5
ST
CMOS
CCP1
P1A
ST
-
CMOS
RC6
ST
CMOS
AN8
SS
AN
ST
RC7
ST
CMOS
AN9
AN
SDO
CMOS
VSS
VSS
Power
VDD
VDD
Power
Legend: AN intrare sau ieire analogic
TTL pin de intrare compatibil TTL
HV tensiune ridicat (high voltage)
CMOS pin de intrare sau ieire compatibil CMOS
ST pin de intrare de tip Trigger Schmitt cu nivele logice CMOS
XTAL cristal
OD open drain
Prezentare C
38
3.4. Arhitectura microcontrolerului PIC16F690
Figura 3-2: Arhitectura PIC16F690 [6]
Prezentare C
39
40
Prezentare C
Prezentare C
41
h) Care din cele dou tipuri de memorie RAM/Flash are un consum mai
mare de curent? Care credei c este mai rapid i de ce?
i) Dac declarm 20 de constante pe 2 octei (16 bii), cte variabile int
mai putem declara dac memoria are 256 de octei?
j) Scriei rezultatul urmtoarelor operaii:
0xAE+0x2A = 0x.. = 0b..
0b01001110 + 0b01100010 = 0b.= 0x
0b00110011 & 0b00100000 = 0b. ..= 0x
0b00001100 | 0xA1 = 0b= 0x
43
Dup cum am precizat anterior, pinii GPIO pot fi configurai de intrare sau
de ieire. Aceast setare se face cu ajutorul registrului TRISx:
Dac bitul K aferent pinului K este setat 1 atunci pinul K va fi pin de
intrare.
Daca bitul K aferent pinului K este setat 0 atunci pinul K va fi pin de
ieire.
Cnd pinul K este configurat ca i ieire, atunci scriind n registrul PORTx
la poziia bitului K, vom modifica starea electric a pinului.
Scriind 1 n registru, pe pin vom citi cu ajutorul unui multimetru 5V
(1 logic).
Scriind 0 n registru, pe pin vom citi cu ajutorul unui multimetru 0V
(0 logic)
Cnd este configurat ca i pin de ieire, din punct de vedere electric pinul
poate fi echivalat cu urmtorul circuit tri-state:
Figura 4-1: Echivalarea electric a unui pin de ieire (Digital Output)
44
Vom avea urmtoarele cazuri:
Funcie
RCO/AN4/C2IN+
RC1/AN5/C12IN1-
RC2/AN6/C12IN2/P1D
RC3/AN7/C12IN3/P1C
RC4/C2OUT/P1B
RC5/CCP1/P1A
RC6/AN8/SS
RC7/AN9/SDO
Tip Ieire
Descriere
RC0
AN4
C2IN+
RC1
AN5
C12IN1-
Tip
Intrare
ST
AN
AN
ST
AN
AN
CMOS
CMOS
-
RC2
AN6
C12IN2-
ST
AN
AN
CMOS
-
P1D
RC3
AN7
C12IN3-
ST
AN
AN
CMOS
CMOS
-
P1C
RC4
C2OUT
P1B
RC5
CCP1
P1A
RC6
AN8
SS
RC7
AN9
ST
ST
ST
ST
AN
ST
ST
AN
CMOS
COMS
CMOS
CMOS
COMS
CMOS
CMOS
CMOS
-
45
Pin de ieire de date pentru SPI.
46
Pentru a seta direcia pinilor se utilizeaz registrul TRISC, iar pentru citirea
sau scrierea portului registrul PORTC.
Tabel 4-2: Regitri asociai cu PORTC [6]
Nume
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
ANSEL
ANS7
ANS6
ANS5
ANS4
ANS3
ANS2
ANS1
ANS0
ANSELH
ANS11
ANS10
ANS9
ANS8
CCP1CON
P1M1
P1M0
DC1B1
DC1B0
CCP1M3
CCP1M2
CCP1M1
CCP1M0
CM2CON0
C2ON
C2OUT
C2OE
C2POL
C2R
C2CH1
C2CH0
CM2CON1
MC1OUT
MC2OUT
T1GSS
C2SYNC
PORTC
RC7
RC6
RC5
RC4
RC3
RC2
RC1
RC0
PSTRCON
STRSYNC
STRD
STRC
STRB
STRA
SRCON
SR1
SR0
C1SEN
C2REN
PULSS
PULSR
SSPCON
WCOL
SSPOV
SSPEN
CKP
SSPM3
SSPM2
SSPM1
SSPM0
TRISC
TRISC7
TRISC6
TRISC5
TRISC4
TRISC3
TRISC2
TRISC1
TRISC0
VRCON
C1VREN
C2VREN
VRR
VP6EN
VR3
VR2
VR1
VR0
Legend: x=necunoscut, u=nemodificat, -=bitul se citete ca 0. Biii nchii la culoare nu sunt folosii de PORTC.
47
48
49
50
4.7. Problem propus
Scriei un program prin care s setai portul C astfel nct ledurile s afieze
alternative valoarea 0xA i 0x5 ntr-o bucl infinit.
n Figura 4-5 se poate vizualiza rezultatul dorit al temei. ntr-o bucl
infinit n funcia main, pinii RC0-RC3 vor indica alternativ valorile 0x5 i
0xA.
Figura 4-5: Alternarea valorii 0x5 i 0xA pe pinii din PORTC
52
53
54
Cnd este configurat ca i pin de intrare, din punct de vedere electric, pinul
poate fi echivalat cu o rezisten de valoare foarte mare legat la mas.
55
+5V
R3
+Vcc
+5V
Btn1
PA2
I~0
I~0
RIN
Gnd
RIN
PA0
R1
Btn2
LED
56
Funcie
RAO/AN0/C1IN+/
ICSPDAT/ULPWU
RA1/AN1/C12IN0/VREF/ICSPCLK
RA0
AN0
C1IN+
ICSPDAT
ULPWU
RA1
AN1
C12IN0-
Tip
Intrare
ST
AN
AN
TTL
AN
ST
AN
AN
Tip
Ieire
CMOS
CMOS
CMOS
-
VREF
AN
ICSPCLK
TTL
RA2
ST
CMOS
AN2
AN
T0CLK
ST
INT
ST
C1OUT
CMOS
RA3/MCLR/VPP
RC3
ST
CMOS
MCLR
ST
VPP
HV
RA4/AN3/T1G/
RC4
ST
COMS
OCS2/CLKOUT
AN3
AN
T1G
ST
OSC2
XTAL
CLKOUT
CMOS
RA5/T1CLK/
RA5
ST
COMS
OSC1/CLKIN
T1CLK
ST
OSC1
XTAL
CLKIN
ST
Legend: AN intrare sau ieire analogic
TTL pin de intrare compatibil TTL
HV tensiune ridicat (high voltage)
CMOS pin de intrare sau ieire compatibil CMOS
ST pin de intrare de tip Trigger Schmitt cu nivele logice CMOS
XTAL cristal
OD open drain
RA2/AN2/T0CLK/
INT/C1OUT
Descriere
Pin digital de intrare/ieire.
Pin analogic de intrare al A/D. Pinul 0.
Intrarea pozitiv a comparatorului C1.
Pin de date intrare/ieire ICSPTM
Pin de intrare ultra-low Wake-up.
Pin digital de intrare/ieire.
Pin analogic de intrare al A/D. Pinul 1.
Intrarea negativ a comparatorului C1 sau
C2.
Tensiune extern de referin pentru
convertorul ADC.
Ceas pentru ICSPTM.
Pin digital de intrare/ieire.
Pin analogic de intrare al A/D. Pinul 2.
Pin de ceas pentru Timer 0.
Pin de ntrerupere extern.
Pin de ieire al comparatorului C1.
Pin digital de intrare/ieire.
Pin de reset cu pull-up intern.
Tensiune de programare.
Pin digital de intrare/ieire.
Pin analogic de intrare al A/D. Pinul 2.
Intrare de validare a Timer 1.
Quartz/Rezonator.
Pin de ieire frecventa Fosc/4.
Pin digital de intrare/ieire.
Ceas de intrare pentru Timer 1.
Quartz/Rezonator.
Intrare de ceas extern / Oscilator RC.
57
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
ANSEL
ANS7
ANS6
ANS5
ANS4
ANS3
ANS2
ANS1
ANS0
ADCON
ADFM
VCFG
CHS3
CHS2
CHS1
CHS0
GO/DONE
ADON
CM1CON0
C1ON
C1OUT
C1OE
C1POL
C1R
C1CH1
C1CH0
INTCON
GIE
PEIE
T0IE
INTE
RABIE
TOIF
INTF
RABIF
IOCA
IOCA5
IOCA4
IOCA3
IOCA2
IOCA1
IOCA0
PORTC
RA5
RA4
RA3
RA2
RA1
RA0
OPTION_REG
RABPU
INTEDG
TOCS
TOSE
PSA
PS2
PS1
PS0
T1CON
T1GINV
TMR1GE
T1CKPS1
T1CKPS0
T1OCSEN
T1SYNC
TMR1CS
TMR1ON
SSPCON
WCOL
SSPOV
SSPEN
CKP
SSPM3
SSPM2
SSPM1
SSPM0
TRISC
TRISA5
TRISA4
TRISA3
TRISA2
TRISA1
TRISA0
WPUA
WPUA5
WPUA4
WPUA2
WPUA1
WPUA0
Legend: x=necunoscut, u=nemodificat, -=bitul se citete ca 0. Biii nchii la culoare nu sunt folosii de PORTA.
5.3. Pull-up/Pull-down:
Dac intrarea pinului este lsat n aer, starea logic a pinului poate fi
influenat de cmpuri electromagnetice. Pentru a evita aceast situaie
nedorit, pinul trebuie legat fie la VSS, fie la VDD. Exist dou posibiliti:
a) Pull-down (legarea la mas)
Figura 5-7: Conexiune pull-down
58
b) Pull-up (legarea la +5V)
59
Practic o apsare fizic a unui push-button este vzut din punct de vedere
electric ca o serie de apsri. Empiric se poate determina durata acestor
oscilaii, ea fiind in jur de 10ms. Exist mai multe soluii, fie hardware fie
software, pentru switch debouncing. Cea mai convenabil i care va fi
prezentat n continuare este soluia software.
Este prezentat un algoritm pentru schimbarea strii unui led la fiecare
apsare a unui push-button.
Figura 5-10: Algoritm debounce
60
61
n figura de mai jos se poate vedea c la fiecare nou apsare a push-buttonului conectat la pinul de intrare RA3, pinul RC0 i va schimba starea
logic, lucru care se observ i prin aprinderea sau stingerea ledului DS1.
Figura 5-12: Trecea din starea 0 logic n starea 1 logic la prima acionare a
push-button-ului
Figura 5-13: Trecea din starea 1 logic n starea 0 logic la o nou acionare a
push-button-ului
62
/* function declarations */
void init();
void delayMs(unsigned int ms);
/* function definitions */
void main()
{
init();
LED = OFF;
/* delay before entering infinite loop */
delayMs(1000);
while(1)
{
/* check if push button has been pressed */
if(PUSH == ???)
{
delayMs(10); /* 10ms delay */
if(PUSH == ???) /* if push button is still pressed */
{
???
}
}
}
}
63
void init()
{
ANSEL = 0x0F; /* set RC0 to RC3 as digital pins */
ANSELH = 0x0C ; /* set RC6 and RC7 as digital pins */
TRISA = ???; /* set all pins on port A as input */
TRISC = ???; /* RC4 to RC7 input. RC0 to RC3 output */
PORTC = ???; /* port C pins reset value */
}
void delayMs(unsigned int ms)
{
unsigned int i,j;
for(i = 0; i< ms; i++)
{
/* delay for 1 ms - empirically determined */
for(j=0; j<62; j++)
{
;
}
}
}
Observaie 1: Pinul RA3, pe lng funcia de intrare-ieire digital, mai
poate fi folosit i ca pin de reset (MCLR). Pentru a putea folosi push-buttonul de pe plac pentru alt funcie dect cea de reset, trebuie modificai biii
de configurare ai microcontrolerului dup cum am prezentat n primul
capitolul la punctul 1.2.6 (Pin Function Select bit ia valoarea MCLR pin
function is digital input).
Observaie 2: n momentul n care programatorul PICKIT 2 este conectat la
placa de dezvoltare, starea electric a pinului RA3 (MCLR) este controlat
din mediul de dezvoltare MPLAB (pentru a putea ine sau scoate din reset
microcontrolerul). Datorit faptului c n aplicaia noastr alimentarea se
face prin PICKIT 2, programatorul nu poate fi deconectat dup scrierea
programului aa c starea pinul RA3 nu poate fi modificat prin apsarea
push-button-ului. Pentru a putea totui folosi push-button-ul n timp ce
programatorul este conectat trebuie fcut urmtoarea setare din meniul
Programmer / Settings: csua 3-State on Release from Reset trebuie
bifat precum n figura de mai jos:
64
65
6. Timer 1
6.1. Introducere
Pentru realizarea sarcinii de a funciona n timp real, aplicaiile embedded
au nevoie de mecanisme specifice pentru a determina intervale precise de
timp. Microcontrolerele ofer astfel de mecanisme incorporate n modulul
numit Timer. Cea mai important funcie a modulului Timer este aceea de
numrtor intern (internal counter). Un registru (counter register) este
incrementat la intervale fixe, frecvena de incrementare fiind egal cu
frecvena la care ruleaz aplicaia (frecvena sistemului) sau este divizat (n
funcie de setrile modulului) din frecvena sistemului. Pentru a folosi
aceast funcie, putem fie citi registrul intern, determinnd din numrul de
incremente timpul trecut, fie putem folosi ntreruperile hardware generate de
ctre modul n momentul n care contorul atinge o valoare prestabilit.
Microcontrolerul PIC16F690 dispune de 3 module Timer:
Timer 1
67
Figura 6-1: Schema bloc a modulului Timer 1 [6]
68
Timer 1
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
CM2CON1
MC1OUT
MC2OUT
T1GSS
C2SYNC
INTCON
GIE
PEIE
T0IE
INTE
RABIE
T0IF
INTF
RABIF
PIE1
ADIE
RCIE
TXIE
SSPIE
CCP1IE
TMR2IE
TMR1IE
PIR1
ADIF
RCIF
TXIF
SSPIF
CCP1IF
TMR2IF
TMR1IF
TMR1H
TMR1L
T1CON
T1GINV
T1CKPS0
T1OSC
T1SYNC
TMR1CS
TMR1ON
TMR1GE
T1CKPS1
Legenda: x=necunoscut, u=nemodificat, -=bitul se citete ca 0. Biii nchii la culoare nu sunt folosii de TIMER1.
Timer 1
69
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
70
Timer 1
Figura 6-2: Logica generrii de ntreruperi [6]
Biii GIE i PEIE din registrul INTCON trebuie setai pentru a activa
ntreruperile generale i ale perifericelor.
Tabel 6-3: Registrul INTCON
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
Timer 1
71
Bitul flag TMR1IF din registrul PIR1 trebuie ters nainte de a valida sursa
de ntrerupere prin setarea bitului de activare a ntreruperii. n caz contrar,
riscm ca bitul flag sa aib valoarea 1, iar n momentul activriii
ntreruperii, programul s sar n rutina de tratare a ntreruperii, lucru
nedorit de noi n acel moment. Aceasta ar trebui s fie o regul de la care s
nu ne abatem niciodat n timpul scrierii programului pentru microcontroler:
bitul flag trebuie ters nainte de a activa sursa de ntrerupere.
Tabel 6-4: Registrul PIR1
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
72
Timer 1
Timer 1
73
NRincrementari = Tdorit/Ttimer
NRincrementari = 500ms/1us
NRincrementari = 500 000
Valoarea maxim ce poate fi scris n registrul TMR1 este 65535 (0xFFFF),
deci perioada de timp maxim ce poate fi msurat este aproximativ
65.5ms. Vom fi nevoii s folosim un pre-scalar diferit de 1:1.
Dac vom folosi un pre-scalar 1:8 Ttimer va deveni 8us, deoarece registrul
TMR1 se va incrementa doar la fiecare al optulea impuls de la intrare.
Atunci:
NRincrementari = Tdorit/Ttimer
NRincrementari = 500ms/8us
NRincrementari = 62 500 = 0xF424
Din numrul de incrementri rezult valoarea ce trebuie scris n TMR1H i
TMR1L. Ea este 0xFFFF- 0xF424 = 0xBDB. Adic timer-ul se va
incrementa de la 0xBDB la 0xFFFF, adic de 62 500 de ori. TMR1H =
0x0B; TMR1L = 0xDB.
Dup stabilirea valorii pre-scalarului i a registrului TMR1H i TMR1L,
vom trece la setarea celorlali bii din registrul de configurare T1CON:
Bitul 7 i 6 (T1GINV i TMR1GE) vor rmne zero deoarece nu
folosim funcia de Gate a timer-ului.
Bitul 5 i 4 (T1CKPS1:T1CKPS2) sunt bii pentru setarea prescalarului. Pentru pre-scalare de 1 la 8 avem nevoie de valoarea 0b11.
Bitul 3 (T1OSCEN) este folosit doar n cazul n care folosim
oscilator intern pentru low-power. Pentru configuraia folosit,
acest bit este ignorat.
Bitul 2 (T1SYNC) este valid doar dac modulul folosete un ceas
extern pentru configuraia folosit, acest bit este ignorat.
Bitul 1 (TMR1CS) alege sursa ceasului folosit. Pentru a avea ceas
intern Fosc/4, acesta ia valoarea zero.
Bitul 0 (TMR1ON) este folosit pentru activarea modulului. Timer 1
este activ/pornit cnd acesta ia valoarea 1.
Pentru activarea ntreruperii, setm biii GIE i PEIE din registrul INTCON.
n final, trebuie ters bitul de stare (flag) TMR1IF i apoi setat bitul
TMR1IE pentru activarea ntreruperii.
74
Timer 1
Timer 1
/* function declarations */
void init();
/* function definitions */
void main()
{
init();
while(1)
{
/* switch LED after m seconds */
if(counter == ???)
{
if(LED == ON)
{
LED = OFF;
}
else
{
LED = ON;
}
counter = 0; /* reset counter */
}
}
}
void init()
{
ANSEL = ??? ; /* set RC0 to RC3 as digital pins */
ANSELH = ??? ; /* set RC6 and RC7 as digital pins */
TRISC = ??? ; /* RC4 to RC7 input. RC0 to RC3 output */
PORTC = 0x00; /* port C pins reset value */
/* timer 1 settings */
TMR1L = ??? ;
TMR1H = ??? ;
T1CON = ??? ;
75
76
Timer 1
/* interrupt settings */
GIE = 1; /* global interrupt enable */
PEIE = 1; /* peripheral interrupt enable */
TMR1IF = 0; /* clear TMR1 interrupt flag */
TMR1IE = 1; /* TMR1 interrupt enabled */
/* start TMR1 */
TMR1ON = 1;
/* variable intializations */
counter = 0;
}
/* Interrupt function */
void interrupt isr(void)
{
/* check if THR1 interrupt enable and flag are set */
if((TMR1IE == 1) && (TMR1IF == 1))
{
TMR1L = ??? ;
TMR1H = ??? ;
counter ++;
/* increment counter every 500ms */
TMR1IF=0;
/* clear TMR1 interrupt flag*/
}
}
Observaie: Implementnd aplicaiile prezentate n aceast lucrare pe
diverse calculatoare s-a observat c, n mediile unde sunt instalate mai multe
compilatoare, folosind anumite compilatoare n combinaie cu definirea
funciei de tratare a ntreruperilor duce la un comportament eronat: dup
ieirea din reset, n loc s se execute funcia main, aplicaia sare direct n
rutina de tratare a ntreruperilor. Dac, dup scrierea programului n
microcontroler, aplicaia pare s nu ruleze, acest comportament se poate
datora compilatorului activ folosit n proiect. Aceast problem este
prezent chiar dac selectm compilatorul potrivit cnd crem proiectul
(capitolul 1, punctul 2.3). Pentru a verifica dac folosim compilatorul
potrivit, accesai meniul Project / Build Options / Project i n fereastra
Driver, asigurai-v c primul compilator din list este Compiler for
Timer 1
77
78
Timer 1
n Figura 6-7 este pus n eviden, ntre cele dou cursoare prezente pe
oscilogram, valoarea pulsului high a semnalului (factorul de umblere
60%).
Timer 1
Figura 6-7: Semnal dreptunghiular cu factor de umplere 60%
79
7. Timer 2
7.1. Descriere Timer 2
Timer pe 8 bii, compus dintr-un registru contor (TMR2) i un
registru pentru perioad (PR2).
pre-scalar programabil (1:1,1:4,1:16).
post-scalar programabil (1:1 pn la 1:16).
valoarea pre-scalarului i post-scalarului se reseteaz la orice scriere
n regitri TMR2 sau T2CON.
registrul TMR2 se incrementeaz pornind de la valoarea 0x00 pn
atinge valoarea setat n registrul perioad PR2. Dup acest moment,
la urmtorul impuls, incrementarea se reia de la 0x00.
dup reset, registrul PR2 este iniializat cu valoarea 0xFF. n acest
registru, nainte de activarea modulului, trebuie scrisa valoarea
calculat pentru a msura perioada de timp dorit.
cnd avem condiie de egalitate ntre contorul TMR2 i valoarea
scris n PR2, se genereaz o ntrerupere.
biii asociai ntreruperilor sunt: TMR2IE pentru activarea
ntreruperii; TMR2IF bitul flag al ntreruperii; GIE bitul pentru
activarea ntreruperilor globale; PEIE bitul pentru activarea
ntreruperilor de la periferice.
Figura 7-1: Schema bloc a Timer2 [6]
Timer 2
81
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
INTCON
GIE
PEIE
T0IE
INTE
RABIE
T0IF
INTF
RABIF
PIE1
ADIE
RCIE
TXIE
SSPIE
CCP1IE
TMR2IE
TMR1IE
PIR1
ADIF
RCIF
TXIF
SSPIF
CCP1IF
TMR2IF
TMR1IF
TMR2
PR2
T2CON
TOUTPS1
TOUTPS0
TMR2ON
T2CKPS1
T2CKPS0
TOUTPS3
TOUTPS2
Legend: x=necunoscut, u=nemodificat, -=bitul se citete ca 0. Biii nchii la culoare nu sunt folosii de TIMER2.
82
Timer 2
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
Timer 2
83
Figura 7-2: Logica generrii de ntreruperi [6]
Biii GIE i PEIE din registrul INTCON trebuie setai pentru a activa
ntreruperile generale i a perifericelor.
Tabel 7-3: Registrul INTCON
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
84
Timer 2
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
Timer 2
85
Figura 7-3: ntrerupere generat la 2s cu Timer 2
86
Timer 2
Timer 2
87
88
/* function declarations */
void init();
/* function definitions */
void main()
{
init();
while(1)
{
/* switch LED after m seconds */
if(counter == ???)
{
??? /* insert code here */
}
}
}
void init()
{
/* pin settings */
???
/* timer 2 settings */
TMR2 = 0x00; /* reset TMR2 counter */
PR2 = ??? ; /* overflow value */
T2CON = ??? ; /* TMR 2 settings */
/* interrupt settings */
???
/* start TMR2 */
???
/* variable intializations */
counter = 0;
}
Timer 2
Timer 2
89
/* Interrupt function */
void interrupt isr(void)
{
/* check if TMR2 interrupt enable and flag is set */
if((???) && (???))
{
??? /* insert code here */
}
}
7.5. Problem propus
Descriei pe scurt un proiect n care poate fi folosit un timer. Ce rol ar avea?
Pe care din cele dou module de timer (Timer 1 sau Timer 2) le-ai folosi i
de ce?
8. Servomotor
8.1. Introducere
Multe aplicaii embedded presupun comanda unui motor cu scopul de
acionare mecanic a unui sistem. n astfel de aplicaii, alegerea corect a
motorului constituie de multe ori o sarcin dificil. Trebuie luate n calcul
mai multe aspecte, dintre care cele mai importante, n funcie de aplicaie,
sunt:
Gabarit: motorul trebuie s poat fi amplasat n spaiul dedicat
produsului. De exemplu, pentru cutiile de vitez automate,
ambreiajul este acionat de un motor electric, iar dimensiunile sunt
impuse de cerinele clienilor (gabaritul cutiei de vitez).
Cuplu: n funcie de sistemul ce trebuie acionat este nevoie de un
anumit cuplu. Fiecare tip de motor are un anumit cuplu n funcie de
gabarit, tensiune de alimentare, turaie i tip constructiv. Cuplul
motorului ales trebuie sa satisfac cerinele proiectului.
Comanda motorului: comanda electric a motorului este un criteriu
important, deoarece difer mult de la motor la motor, fiind fie simpl
(servomotor), fie foarte complex (motor brushless).
Tensiunea de alimentare: ca exemplu, la autoturisme, tensiunea de
alimentare este 12V. Un motor cu o tensiune de alimentare diferit de
12V poate introduce n proiect necesitatea unei surse n comutaie sau
altor soluii hardware, care cresc preul produsului i complexitatea
acestuia.
Durata de via: un motor de curent continuu are perii colectoare
care, n timp, se deterioreaz, pe cnd un motor brushless nu
ntmpin acest impediment. Din acest punct de vedere, un sistem cu
motor brushless este indicat n locuri greu accesibile sau n produse
crora li se impune o durat de via lung i fr defecte.
Preul: preul motorului este un procent important din costul total al
produsului i astfel trebuie s se ncadreze n nite limite foarte bine
stabilite. Preul poate varia de la civa EURO (servomotoare
analogice RC) la sute de EURO (motor de curent continuu cu
encoder i cutie reductoare).
S lum n continuare un caz particular, o posibil aplicaie. S plecm de la
ideea c trebuie s realizm pentru bordul unui automobil un vitezometru
Servomotor
91
care s par analogic, adic s aib o scal i un ac indicator, dar care s fie
acionat de un motor electric comandat de sistemul care msoar viteza
autovehiculului. Pentru alegerea motorului trebuie s inem cont de criteriile
de mai sus i am putea lua n calcul cteva tipuri de motoare:
Motor de curent continuu: din punct de vedere al gabaritului, al
cuplului dezvoltat i al preului poate fi o variant. Mari dezavantaje
ar fi comanda complicat cu bucl nchis (avem nevoie de comand
cu feedback pentru a fi siguri c acul este la poziia dorit) i durata
de via a periilor.
Motorul pas cu pas: motorul pas cu pas n conexiune bipolar are de
asemenea dezavantajul complexitii driverului hardware pentru
comand. n schimb, motorul pas cu pas n conexiune unipolar
depete acest dezavantaj, comanda fiind una relativ simpl. Pentru
cuplul necesar acionrii acului indicator n aceast aplicaie, motorul
are de asemenea un gabarit relativ redus. Durata de via este foarte
mare dar preul poate fi considerat mare.
Motorul brushless: nu corespunde din mai multe puncte de vedere.
Preul este ridicat comparativ cu alte tipuri de motoare. Comanda este
complex. n plus, un alt dezavantaj este consumul mai mare de
curent.
Servomotorul: la baz are tot un motor de curent continuu dar de
dimensiuni foarte mici. Este cel mai simplu de comandat, deoarece
include un sistem de feedback cu poteniometru iar poziia la care
trebuie s se deplaseze rotorul se d prin comand PWM pe un singur
fir. Include i un reductor, deci cuplul este ridicat comparativ cu
gabaritul lui i consumul de curent. Preul este de asemenea un
avantaj, acest tip de motor fiind mai ieftin dect un motor pas cu pas.
8.2. Comanda unui servomotor
Servomotorul este compus din mai multe pri: un motor (DC de regul), un
reductor mecanic, un traductor de poziie (cel mai adesea un poteniometru),
un driver de motor, un amplificator de eroare i un circuit pentru
decodificarea poziiei dorite.
n Figura 8-1 putem observa schema bloc a unui astfel de sistem.
92
Servomotor
Figura 8-1: Schema bloc a unui servomotor analogic
Servomotor
93
94
Servomotor
Servomotor
95
96
/* function definitions */
void main()
{
init();
while(1)
{
; /* further development */
}
}
void init()
{
/* pin configuration */
???
/* timer 1 settings */
???
/* timer 2 settings */
???
/* interrupt settings */
???
/* other initializations */
???
}
/* Interrupt function */
void interrupt isr(void)
{
/* check if TMR1 interrupt enable and flag are set */
if((TMR1IE == 1) && (TMR1IF == 1))
{
??? /* insert code here */
}
/* check if TMR2 interrupt enable and flag are set */
Servomotor
Servomotor
97
99
100
101
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
ADCON0
ADFM
VCFG
CH3
CH2
CH1
CH0
GO/DONE
ADON
ADCON1
ADCS2
ADCS1
ADCS0
ANSEL
ANS7
ANS6
ANS5
ANS4
ANS3
ANS2
ANS1
ANS0
ANSELh
ANS11
ANS10
ANS9
ANS8
ADRESH
ADRESL
INTCON
GIE
PEIE
T0IE
INTE
RABIE
T0IF
INTF
RABIF
PIE1
ADIE
RCIE
TXIE
SSPIE
CCP1IE
TMR2IE
TMR1IE
PIR1
ADIF
RCIF
TXIF
SSPIF
CCP1IF
TMR2IF
TMR1IF
PORTA
RA5
RA4
RA3
RA2
RA1
RA0
PORTB
RB7
RB6
RB5
RB4
PORTC
RC7
RC6
RC5
RC4
RC3
RC2
RC1
RC0
TRISA
TRISA5
TRISA4
TRISA3
TRISA2
TRISA1
TRISA0
102
TRISB
TRISB7
TRISB6
TRISB5
TRISB4
TRISC
TRISC7
TRISC6
TRISC5
TRISC4
TRISC3
TRISC2
TRISC1
TRISC0
Legend: x=necunoscut, u=nemodificat, -=bitul se citete ca 0. Biii nchii la culoare nu sunt folosii de ADC.
R2
D/A
P
CAN
x x x x x 0 1 x
PORTA
LED
x x x x x 1 0 1
ADCON0 & ADCON1
- -
- - - - 0 0
ADRESH
TRISA
0 1 1 0 0 1 0 1
ADRESL
R1
103
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
104
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
Salvarea rezultatului conversiei poate fi fcut n dou feluri: right sau left
justified. Dac alegem modul right justified, cei mai puin semnificativ 8 bii
vor fi scrii n ADRSEL, iar cei mai semnificativi 2 bii in ADRSEH. n
cazul selectrii modului left justified, cei mai puin semnificativ 2 bii vor fi
salvai n ADRSEL, iar cei mai semnificativ 8 bii n ADRESH.
Figura 9-5: Alinierea rezultatului conversiei [6]
105
106
n Figura 9-7 este prezentat starea ledului DS3 pentru o tensiune la intrarea
convertorului ADC care depete pragul de 3V (moment n care pinul RC2
devine 1 logic) i care, dup un timp, revine sub pragul de 3V (pinul revine
i el n starea de 0 logic).
Figura 9-7: Starea pinului RC2 n funcie de tensiunea de pe pinul RA0
107
108
Activarea modulului:
Activarea modulului se face prin setarea bitului ADON din registrul
ADCON0 (bitul 0). Urmtorul pas ar fi declanarea n software a conversiei
prin setarea bitului GO, bitul 2 din ADCON0. n momentul scrierii acestui
bit, modulul ADC va incepe conversia analog numeric a tensiunii regsite
pe pinul analogic de intrare. La finalul conversiei modulul ADC va returna
n regitri ADRSEH si ADRSEL o valoare corespunztoare cu tensiunea de
pe pin (numrul cuantelor q coninute de tensiunea de convertit).
Activarea ntreruperilor, att pentru Timer 1 ct i pentru modulul
ADC:
Trebuie setai biii GIE i PIE din registrul INTCON, biii TMR1IE i ADIE
din registrul PIE1. Flag-urile ambelor surse de ntrerupere trebui terse i
anume biii TMR1IF i ADIF din registrul de flag-uri PIR1.
9.5. Model software
n programul scris de noi va trebui s avem n vedere:
Configurarea Timer 1
Configurarea modulului ADC
Configurarea ca i ieire a pinului la care este legat ledul DS3
Scrierea rutinei de tratare a ntreruperii.
Exemplu de cod:
/* include files */
#include "pic.h"
/* constant and macro defines */
???
#define THRESHOLD 3000 /* threshold for turning the LED ON */
#define ADC_TO_mV 5 /* rounded from 4.88 */
/* variables */
volatile unsigned int ADCValue, lastADCValue;
volatile unsigned int milliVolts;
/* function declarations */
void init();
109
/* function definitions */
void main()
{
init();
while(1)
{
/* check if last ADC value is different from current read - only if true
execute code */
if(ADCValue != lastADCValue)
{
milliVolts = ADCValue * ADC_TO_mV; /* convert from ADC value
to mV */
/* turn LED ON if greater than set threshold */
???
/* save last ADC value */
lastADCValue = ADCValue;
}
}
}
void init()
{
/* pin configuration */
???
/* timer 1 settings */
???
/* ADC configuration */
ADCON0 = 0x80; /* right justify; Vref = Vdd; AN0; module turned off */
ADCON1 = 0x40; /* Fosc/4 */
ADON = 1; /* turn module on */
/* interrupt settings */
???
110
/* start TMR1 */
TMR1ON = 1;
/* initialize variables */
lastADCValue = 0;
ADCValue = 0;
milliVolts = 0;
}
/* Interrupt function */
void interrupt isr(void)
{
/* check if TMR1 interrupt enable and flag are set */
if((TMR1IE == 1) && (TMR1IF == 1))
{
TMR1L = ??? ;
TMR1H = ??? ;
ADCON0 |= 0x02; /* set GO bit to start ADC conversion */
TMR1IF = 0;
/* clear TMR1 interrupt flag*/
}
else if((ADIE == 1) && (ADIF == 1))
{
ADCValue = (ADRESH << 8) + ADRESL;
ADIF = 0; /* clear ADC ISR flag */
}
}
10. UART
10.1. Introducere
UART (Universal Asynchronous Receiver Transmitter) este o interfa de
comunicare asincron serial. Fiecare dintre participani are propriul circuit
de generare a ceasului necesar comunicrii i astfel protocolul este asincron
(nu exist semnal de ceas transmis ntre participani). Se mai numete i SCI
(Serial Communications Interface).
UART este un protocol de comunicare pe 2 fire, nu necesit master i
comunicarea poate fi iniiat simultan de oricare dintre noduri. Acest mod se
numete full-duplex. Protocolul poate fi folosit pentru comunicaia dintre
dou microcontrolere aflate la civa metri distan (dac se folosete cablu
torsadat). Ambii participani la comunicare trebuie s aib aceleai setri
(numr de bii, frecvena semnalului de ceas sau paritatea).
10.2. Descriere modul UART
n funcie de implementarea hardware, modulul UART poate avea diferite
caracteristici. Cele mai importante la PIC16F690 sunt:
Datele transmise pot avea o lungime de 8 sau 9 bii, n funcie de
setrile fcute.
Datele ce se doresc a fi transmise sunt mpachetate de ctre
hardware pentru a corespunde cu protocolul, fiind adugai un bit de
start i unul de stop.
Modulul dispune de pini dedicai de transmisie i de recepie.
ntreruperi dedicate att pentru transmisie ct si pentru recepie.
Un buffer de transmisie i unul de recepie (de tip FIFO cu
adncime 2).
Modulul dispune de bii de stare care indic eroarea de format i
eroarea de recepie a unui nou mesaj (cnd buffer-ul de recepie este
plin).
Cnd bitul SPEN este setat, pinul RX este configurat ca si pin de
intrare, indiferent de starea bitului din registrul TRIS, chiar dac
blocul de recepie nu este activat.
Trebuie adugat c n unele implementri hardware (nu este cazul
microcontrolerului PIC16F690) exist i un bit de paritate (par sau impar)
112
UART
care face parte (opional) din formatul mesajului trimis. Acest bit de paritate
este calculat i mpachetat alturi de biii de date n formatul mesajului de
ctre participantul care trimite datele. La recepie, acest bit este
despachetat i comparat cu valoarea de paritate calculat la recepie. n
cazul n care difer, se genereaz eroare de paritate.
Exist i implementri hardware unde, n funcie de setri, putem alege unul
sau doi bii de stop.
Figura 10-1: Formatul protocolului UART
UART
113
114
UART
Ultimul bit mpachetat n formatul mesajului este bitul de stop care are
valoarea de 1 logic. n figura urmtoare bitul de stop este cuprins ntre
cursoare i are o lime de 104.1 s.
Figura 10-5: Bit de stop pentru un mesaj trimis cu 9600 bit/secunda
UART
115
116
UART
Cnd datele sunt mutate (automat de ctre hardware) dup recepie din
buffer n registrul RCREG, bitul de stare RXIF va fi setat. Dac i bitul
RXIE este setat, o ntrerupere va fi generat.
Blocul de recepie este activat prin setarea bitului SPEN i CREN. Pentru a
recepiona date n format de 8 bii, bitul RX9 trebuie sa fie 0. Pinul RX
(RB5) are i funcie analogic AN11, aa c pe lng activarea modulului
(setarea bitului SPEN din registrul RCSTA) i activarea blocului de recepie
(setarea bitului CREN din registrul RCSTA), pinul trebuie asignat
modulului UART (devine pin digital) prin scrierea bitului ANS11 din
registrul ANSELH cu 0 logic.
Dac se dorete folosirea ntreruperilor, bitul RXIE trebuie setat n registrul
PIE1, ct i biii PEIE i GIE, din registrul INTCON.
Figura 10-7: Schema blocului de recepie UART [6]
UART
117
118
UART
Mod de
funcionare UART
8 bit/ Asincron
8 bit/ Asincron
16 bit/ Asincron
16 bit/ Asincron
8 bit/ Asincron
16 bit/ Sincron
BRGH
0
1
0
1
X
X
Formul calcul
FOSC/[64*(n+1)]
FOSC/[16*(n+1)]
FOSC/[4*(n+1)]
Bit7
Bit6
Bit5
Bit4
Bit3
Bit2
Bit1
Bit0
INTCON
GIE
PEIE
T0IE
INTE
RABIE
T0IF
INTF
RABIF
PIE1
ADIE
RCIE
TXIE
SSPIE
CCP1IE
TMR2IE
TMR1IE
PIR1
ADIF
RCIF
TXIF
SSPIF
CCP1IF
TMR2IF
TMR1IF
RCSTA
TXREG
RCSTA
SPEN
RX9
SREN
CREN
ADDEN
FERR
OERR
RX9D
TXSTA
CSRC
TX9
TXEN
SYNC
SENDB
BRGH
TRMT
TX9D
BAUDCTL
ABDOVF
RCIDL
SCKP
BRG16
WUE
ABDEN
SPBRG
Registrul pentru calculul ratei de transfer. Cei mai puin semnificativi 8 bii.
SPBRGH
TRISB
TRISB7
TRISB6
TRISB5
TRISB4
ANSELH
ANS11
ANS10
ANS9
ANS8
Legend: x=necunoscut, u=nemodificat, -=bitul se citete ca 0. Biii nchii la culoare nu sunt folosii de UART.
UART
119
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
120
UART
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
UART
121
Legend: R - bitul poate fi citit; W - bitul poate fi scris; U - bit neimplementat, se va citi 0; n valoare dup POR;
1 - bitul e setat; 0 - bitul e ters; X - valoare necunoscut;
122
UART
UART
123
124
UART
Exemplu de cod:
UART
125
/* include files */
#include "pic.h"
/* macro*/
#define LED ???
/* function declarations */
void init();
/* function definitions */
void main()
{
unsigned int i, j;
init();
/* local variables*/
while(1)
/* infinit loop*/
{
for (i = 0; i<101; i++)
/* loop to send 101 messages*/
{
TXREG = i; /* send all values from 0 to 100*/
for (j = 0; j<100; j++); /* small delay between messages*/
if (RCREG == 90) /* read the received data and compare it to 90*/
LED =???;
/* turn on DS1*/
}
}
}
void init()
{
/* Pin settings for LEDs*/
ANSEL = 0x0F; /* set RC0 to RC3 as digital pins */
TRISC = 0xF0; /* RC4 to RC7 input. RC0 to RC3 output */
PORTC = 0x00; /* port C pins reset value. LEDs off*/
/* Baud setting */
126
UART
Anexa 1
Anexa 1 prezint cteva elemente ale limbajului C ce nu au fost explicate n
Capitolul 2. Acestea sunt descrise pe scurt, sub forma de list, avnd ca scop
familiarizarea cititorului cu ct mai mult elemente ale limbajului de
programare.
Const este un calificativ care, atribuit definiiei unei variabile, o transform
pe aceast ntr-o constant, adic devine read-only. Precum o variabil
normal, constanta creat va avea un tip, un nume generic i o adres,
diferena fiind c, o dat atribuit o valoare, aceasta nu mai poate fi
modificat.
const unsigned int a = 10;
Pe parcursul codului se poate folosi noua constant cu numele ei generic,
atribuirea unei alte valori fiind imposibile. n aplicaiile embedded o
constant va fi stocat n memoria de tip read-only (ROM, Flash) i nu n
RAM precum n cazul variabilelor.
Volatile este la rndul su un calificativ care se atribuie variabilelor i care
semnaleaz compilatorului s nu optimizeze accesele la acea variabil. n
aplicaiile embedded sunt dese momentele n care se citesc regitri de stare
care se pot schimba independent de aplicaia care ruleaz pe microcontroler.
Considerm exemplul urmtor:
while(reg_read == 0)
{ ; }
Presupunem c registrul pe care l citim n bucla anterioar este zero la
nceput, primind o valoare diferit doar dup un anumit timp (ex: se seteaz
un bit pentru un mesaj recepionat). Dac variabila reg_read nu este
declarat ca fiind volatile, compilatorul ar putea optimiza codul i n loc s
citeasc valoarea de la adresa registrului de fiecare dat, o va citi o singur
dat, la nceput i aceasta fiind 0, bucla va deveni infinit. Declarnd
variabila ca fiind volatile foreaz compilatorul s aduc de fiecare dat
valoarea din memorie, n cazul nostru, din registrul pe care dorim s l citim.
128
Anexa 1
Anexa 1
129
130
Anexa 1
Anexa 2
Anexa 2 va prezenta scrierea codului (fiierul *.hex) n memoria
microcontrolerului.
Dup scrierea codului n mediul de dezvoltare MPLAB i compilarea
acestuia, vom obine un fiier *.hex care conine codul main al
programului. Acesta trebuie scris in memoria program (Flash) a
microcontrolerului, de unde va fi rulat instruciune cu instruciune.
Trebuie urmai urmtorii pai:
a) Selectai meniul Programmer / Select Programmer / PICkit 2. Se va
deschide n bara de tool-uri un nou cmp, PICkit 2 Program Toolbar
care conine 9 butoane, fiecare avnd cte o funcie.
b) Apsai primul buton din partea stng, cel de scriere a memoriei, numit
Program the target device
. Ateptai ca scrierea s se finalizeze.
n urma acestui proces, codul main se va regsi n memoria Flash a
microcontrolerului.
c) Scoatei microcontrolerul din starea de reset (n care a fost introdus de
programatorul PICkit 2 n timpul scrierii memoriei) prin apsarea
butonului 7 din partea stng Bring target MCLR to Vdd
. Din
acest moment, microcontrolerul va ncepe execuia programul regsit in
memoria sa Flash pornind de la adresa 0x0.
Anexa 3
Privind urmtoarea oscilogram, este firesc s ne ntrebm: Cum putem
interpreta informai coninute de aceasta, i mai mult, unde regsim aceste
informai?
Figura 11-1: Principalele informai dintr-o oscilogram
Anexa 3
133
134
Anexa 3
Figura 11-2: Folosirea cursoarelor verticale
Bibliografie
[1] Ioan P. Mihu, Dispozitive i Circuite Electronice, Volumul I,II, ISBN
973-95604-0-4, Ed. Alma Mater, Sibiu, 2004
[2] Ioan P. Mihu, Procesarea Numeric a Semnalelor. Noiuni Eseniale,
ISBN 973-632-195-1, Ed. Alma Mater, Sibiu, 2005
[3] Ioan P. Mihu, ANSI-C pentru microcontrolere, Note de curs, Sibiu,
2011
[4] Ilie Beriliu, Microcontrolere Aplicaii, ISBN 978-973-739-578-8, Ed.
Universitatea Lucian Blaga Sibiu, 2008
[5] Ilie Beriliu, Cu un PIC mai detept, Note curs, 2005
[6] PIC16F631/677/685/687/689/690 Data Sheet (DS41262E), Microchip
[7] Low Pin Count Demo Board Users Guide (DS51556A), Microchip
[8] *** http://publications.gbdirect.co.uk/c_book/
[9] *** http://microchip.com/