Documente Academic
Documente Profesional
Documente Cultură
Microcontrolerul PIC16F84
Aplicații practice
Editura
N A U T ICA
Mihaela HNATIUC Cătălin Constantin POMAZAN
Microcontrolerul PIC16F84
Aplicații practice
Editura
N A U T ICA
Copyright © 2015, Editura NAUTICA
Toate drepturile asupra acestei ediţii sunt rezervate Editurii
MIHAELA HNATIUC
CĂTĂLIN CONSTANTIN POMAZAN
MICROCONTROLERUL PIC 16F84. APLICAŢII PRACTICE
Laborator 1.......................................................................................................................................1
Microcontrolerul PIC16F84, platforma experimentală Z11/EV
și mediul de dezvoltare MPLAB X
Laborator 2.....................................................................................................................................17
Instrucțiuni pentru transferul de date
Laborator 3.....................................................................................................................................26
Instrucțiuni aritmetice și logice
1. Lumină dinamică cu sens prestabilit............................................................................29
2. Lumină dinamică cu sens modificabil..........................................................................32
3. Aprinderea selectivă a LED-urilor folosind butoanele PS1 și PS2................................34
4. Utilizarea butoanelor PS1 și PS2 pe post de comutator..............................................36
5. Utilizarea unui singur buton pe post de comutator....................................................37
Laborator 4.....................................................................................................................................39
Instrucțiuni de salt condiționat și necondiționat
1. Comanda releelor cu ajutorul butoanelor PS1 și PS2..................................................44
2. Citirea tastaturii matriciale și utilizarea afișorului cu șapte segmente........................46
3. Afișarea tastei apăsate pentru o durată prestabilită...................................................49
Laborator 5.....................................................................................................................................51
Întreruperi
1. Controlul intensității luminoase folosind tehnica PWM..............................................55
2. Utilizarea TMR0 și a sistemului de întreruperi............................................................57
3. Comanda unui buzzer..................................................................................................58
4. Alarmă electronică.......................................................................................................60
Laborator 6.....................................................................................................................................62
Interfațarea cu afișajul alfanumeric
1. Afișarea unui text pe două rânduri..............................................................................68
2. Cronometru digital cu afișajul LCD 2x16 caractere......................................................70
Laborator 7.....................................................................................................................................73
Memoria EEPROM. Citirea și scrierea de date
1. Tastatură cu memorie permanentă.............................................................................75
Bibliografie.....................................................................................................................................79
CUVÂNT ÎNAINTE
Autorii
Microcontrolerul PIC16F84 – Aplicații practice
LABORATOR 1
Microcontrolerul PIC16F84,
platforma experimentală Z11/EV
și mediul de dezvoltare MPLAB X
Scopul lucrării
Lucrarea de laborator prezintă succint microcontrolerul PIC16F84, platforma experimentală
Z11/EV produsă de Elettronica Veneta care va fi utlizată În aplicațiile de laborator precum și
mediul de dezvoltare integrat MPLAB X cu care vor fi scrise secvențele de cod pentru
microcontroler.
Breviar teoretic
Un microcontroler este un dispozitiv electronic ce include într-un singur integrat toate
dispozitivele specifice unui sistem cu microprocesor cum ar fi:
• unitate centrală de calcul – ce interpretează şi execută instrucţiunile programului
• memorie PROM (Programabile Read-Only Memory) – ce memorează permanent
instrucţiunile programului rulat
• memorie RAM (Random Access Memory) – ce păstrează temporar variabilele de lucru
ale programului
• linii de intrare / ieşire – pentru comanda unor dispozitive externe sau citirea
informaţiilor de la senzori, butoane, etc.
PIC16F84 este un microcontroler cu arhitectură RISC (Reduced Instruction Set Computing)
construit pe o arhitectură Harvard cu instrucțiuni pe 14 biți și magistrală de date de 8 biți.
1
Microcontrolerul PIC16F84 – Aplicații practice
Diagrama pinilor pentru acest microcontroler conform [1] este reprezentată în fig.1, unde:
2
Microcontrolerul PIC16F84 – Aplicații practice
Un ciclu mașină este executat în patru impulsuri ale semnalului de ceas. Aceasta înseamnă că
pentru o frecvență a semnalului de ceas de 20 MHz se obține o durată de 200 ns pe ciclu
instrucțiune.
Memoria PROM (Programmable Read-Only Memory) pentru stocarea programului are
3
Microcontrolerul PIC16F84 – Aplicații practice
capacitatea de 1024 cuvinte de 14 biți (1k cuvânt). Conținutul acesteia este programabil printr-o
procedură specială și nu se șterge la întreruperea alimentării microcontrolerului.
Memoria RAM (Random Access Memory) de date este împărțită în două zone distincte. Prima
dintre ele conține octeții ce configurează modul de funcționare al microcontrolerului. Aceștia
poartă denumirea de regiștri cu funcții speciale (Special Function Registers). A doua zonă
conține octeții ce constituie memoria de uz general. Aceștia poartă numele de regiștri de uz
general (General Purpose Registers).
Viteza de scriere / citire a memoriei RAM este ridicată, dar conținutul acesteia se pierde la
întreruperea alimentării.
Pentru a putea accesa un spațiu de adresare mai mare, memoria RAM este organizată în două
4
Microcontrolerul PIC16F84 – Aplicații practice
bancuri. Fiecare banc permite adresarea unui număr de 128 de locații. Primele 12 locații din
fiecare banc sunt rezervate pentru regiștrii cu funcții speciale SFR. Restul locațiilor reprezintă
regiștrii de uz general GPR. Adresele primelor 68 de locații GPR din al doilea banc sunt mapate
în primul banc (conținutul lor este comun pentru ambele bancuri).Pentru stocarea permanentă
a unor informații, microcontrolerul dispunde și de o memorie EEPROM (Electrically Erasable
Programmable Read-Only Memory) cu o capacitate de 64 de octeți. Această memorie poate fi
accesată numai prin adresare indirectă. Viteza de scriere în această memorie este mult mai
lentă decât a memoriei RAM, dar conținutul se păstrează și după întreruperea alimentării.
Pentru interfațarea cu exteriorul PIC16F84 dispune de 13 pini de intrare/ieșire organizați în
două porturi: PORTA (5 biți) și PORTB (8 biți). Semnalele pe pinii de intrare/ieșire sunt reflectate
de conținutul regiștrilor PORTA și PORTB. La un moment dat fiecare dintre acești pini poate fi
doar intrare sau doar ieșire. Configurarea ca intrari sau ieșiri se face individual, utilizând regiștrii
cu funcții speciale TRISA și TRISB. Pentru fiecare bit din PORTA și PORTB îi corespunde un bit în
TRISA și TRISB ce stabilește modul de funcționare ca intrare sau ieșire pentru pinul asociat.
PIC16F84 dispune de un modul temporizator/numărător de 8 biți denumit TMR0 a cărui
conținut ce poate fi scris și citit. Acesta poate fi configurat să folosească drept intrare un semnal
de tact generat intern sau extern și dispune de un circuit divizor (prescaler) de 8 biți
programabil. Pentru semnalul de tact extern se poate configura utilizarea frontului crescător sau
descrescător și depășirea capacității de stocare pentru TMR0 poate genera o întrerupere.
Pe lângă TMR0 microcontrolerul dispune de încă un circuit temporizator independent WDT
(Watchdog Timer) programabil ce funcționează independent pe baza unui semnal de ceas
generat intern. Acesta este de regulă utilizat pentru resetarea microcontrolerului dacă acesta se
blochează din cauza diverselor condiții de funcționare.
Microcontrolerul PIC16F84 permite utilizarea a patru tipuri de întreruperi:
• apariția unui semnal pe pinul RB0/INT
• depășirea generată de TMR0
• schimbarea semnalelor la pinii RB4 - RB7
• terminarea inscripționării în memoria EEPROM
Detalii suplimentare referitoare la structura internă și funcționarea microcontrolerului PIC16F84
vor fi prezentate în cadrul lucrărilor de laborator următoare în funcție de specificul acestora.
Instrucțiunile recunoscute de microcontrolerul PIC16F84 pot fi grupate în funcție de
funcționalitatea lor în:
• instrucțiuni de transfer de date în memoria internă de date, memoria program sau stivă
• instrucțiuni de transfer de date în memoria externă
• instrucțiuni aritmetice
5
Microcontrolerul PIC16F84 – Aplicații practice
6
Microcontrolerul PIC16F84 – Aplicații practice
7
Microcontrolerul PIC16F84 – Aplicații practice
(()) – referire la conținutul unei locații de memorie a cărei adresă se află memorată într-
un registru
data8 – valoare reprezentată pe 8 biți
data16 – valoare reprezentată pe 16 biți
← – asignare
↑ – concatenare
8
Microcontrolerul PIC16F84 – Aplicații practice
În partea din dreapta jos, platforma experimentală mai include și un programator serial pentru
microcontrolerul PIC16F84. Pentru salvarea programului în memoria PROM microcontrolerul
trebuie plasat în soclul programatorului. După încheierea programării microcontrolerului, acesta
trebuie mutat în soclul central al plăcii experimentale pentru efectuarea lucrărilor de laborator.
Pentru alimentarea cu energie electrică este folosită sursa PSLC produsă tot de Elettronica
Veneta ce permite obținerea tensiunilor de ±5V și ±12V necesare plăcii Z11/EV.
Desfășurarea lucrării
Pentru scrierea programelor este utilizat mediul integrat de dezvoltare MPLab X produs de
Microchip (lucrarea de față face referire la versiunea 2.26). Codul sursă pentru lucrările de
laborator este prezentat în limbaj de asamblare și/sau în C. Mediul integrat de dezvoltare
(Integrated Development Environment) oferă suport nativ pentru limbajul de asamblare
(MPASM versiunea 5.59), pentru limbajul C fiind necesară instalarea suplimentară a
compilatorului MPLAB XC8 (lucrarea de față face referire la versiunea 1.33 a acestuia).
Pe lângă instrumentele necesare scrierii și compilării codului sursă acest IDE conține module
pentru depanarea codului, editarea biților de configurare ai microcontrolerelor, simularea
funcționării și monitorizarea memoriei acestora, accesarea cu ușurință a foilor de catalog
referitoare la microcontrolerele produse de Microchip și a altor materiale de informare. Pentru
accesarea acestora este necesară o conexiune la internet.
9
Microcontrolerul PIC16F84 – Aplicații practice
MPLab X este un mediu complex de dezvoltare și din acest motiv vor fi prezentate succint în
continuare doar etapele necesare scrierii codului sursă și compilării acestuia pentru
microcontrolerul PIC16F84.
În fereastra principală a IDE-ului (fig.5) vom observa în partea superioară meniul general și o
bandă cu butoane pentru comenzile frecvente. În partea centrală stânga vor fi afșate informații
referitoare managementul de proiect, gradul de ocupare al memoriei microcontrolerului cu care
se lucrează și alte informații utile legate de acestea. Regiunea centrală cea mai mare conține
inițial numeroase comenzi pentru crearea sau deschiderea unui nou proiect, accesarea unor
tutoriale referitoare la MPLab X și a altor resurse on-line. Tot în această zonă se va face și
editarea codului sursă. În partea de jos a ferestrei IDE-ului se află linia de stare ce va afișa în
funcție de context diverse informații referitoare la starea curentă a mediului de dezvoltare.
Orice aplicație scrisă pentru un microcontroler trebuie inclusă într-un proiect.
Crearea proiectului poate fi inițializată de pe pagina de start folosind comanda Create New
Project, cu ajutorul butonului specific din bara de unelte sau din meniul principal folosind File ->
New Project... (fig.6).
10
Microcontrolerul PIC16F84 – Aplicații practice
Pagina a doua a asistentului (fig.8) permite selectarea microcontrolerului căruia îi este dedicat
proiectul. La Device vom selecta PIC16F84 și apoi continuăm cu butonul Next.
MPLab X permite conectarea cu mai multe tipuri de programatoare și unelte hardware produse
de Microchip. A treia pagină a asistentului pentru proiecte (fig.9) permite selectarea unui
echipament hardware din această categorie. Deoarece placa experimentală Z11/EV este
echipată cu propriul programator ce nu este compatibil cu MPLab X, la Hardware Tools vom
selecta Simulator și vom continua cu butonul Next.
11
Microcontrolerul PIC16F84 – Aplicații practice
Pe pagina a patra a asistentului (fig.10) trebuie selectat compilatorul cu care vom lucra. Pentru
proiectele scrise în limbaj de asamblare vom selecta mpasm, iar pentru proiectele scrise în
limbajul C vom selecta XC8 și vom continua cu butonul Next.
În final (fig.11), trebuie specificat numele proiectului și directorul în care acesta va fi salvat.
Foarte important pe această pagină este să bifăm și opțiunea Set as main project. Aceasta
determină considerarea proiectului nou adăugat ca proiect principal. Finalizarea creării
proiectului se face apăsând pe butonul Finish.
Ca urmare a acestor operațiuni, în fereastra Projects va apare structura de directoare a
proiectului creat. Adăugarea unui fișier sursă în cadrul proiectului se poate realiza în mai multe
12
Microcontrolerul PIC16F84 – Aplicații practice
feluri. O variantă este utilizarea comenzii File -> New File... din meniul aplicației. Aceasta
conduce la deschiderea unei ferestre de asistență în care trebuie selectat tipul fișierului adăugat
(fig.12). Pentru adăugarea unui fișier sursă în asamblare vom alege categoria Assembler și tipul
de fișier AssemblyFile.asm. Pentru adăugarea unui fișier sursă C vom selecta categoria C și C
Source File la tipul fișierului. în continuare se apasă butonul Next.
Pe a doua pagină a asistentului trebuie specificat numele și locația fișierului sursă (fig. 13).
Finalizarea adăugării se face cu butonul Finish.
Fișierul sursă adăugat va apare în cadrul proiectului și va fi deschis automat pentru editare.
După scrierea codului sursă, compilarea acestuia se poate face fie cu comanda Run -> Clean and
13
Microcontrolerul PIC16F84 – Aplicații practice
Build Main Project din meniul principal, fie cu ajutorul butonului asociat din zona cu comenzi
rapide de sub meniul principal. Ca urmare a acestor operațiuni, în directorul în care a fost salvat
proiectul vor fi create mai multe subdirectoare suplimentare în care vor fi salvate diversele
fișiere generate la compilare (fig.14).
Pe lângă facilitățile pentru scrierea codului sursă, MPLAB X prezintă numeroase funcții utilitare
14
Microcontrolerul PIC16F84 – Aplicații practice
pentru urmărirea funcționării aplicației și depanarea codului sursă. Una dintre acestea este
simulatorul care permite analiza semnalelor la pinii microcontrolerului. Componentele acestuia
se pot activa din din meniul Window -> Simulator al mediului integrat de dezvoltare (fig.15).
Simulatorul permite modelarea unor semnale discrete pentru microcontrolerele din familia PIC
și dsPIC produse de Microchip și dispune de un generator de semnal și de un analizor logic.
Pentru programarea fișierului hex generat prin compilarea codului sursă în memoria
microcontrolerului, programatorul de pe placa experimentală Z11/EV trebuie conectat cu
ajutorul unui cablu de comunicații seriale la portul serial al calculatorului pe care a fost compilat
proiectul. În continuare va fi lansat utilitarul IC-Prog (fig.16) pentru încărcarea în memoria
PROM a microcontrolerului a fișierului hex.
După deschiderea IC-Prog se încarcă fișierul hex cu comanda File -> Open File... din meniul
principal. Se verifică să fie selectat microcontrolerul PIC16F84 în combo box-ul din dreapta sus a
ferestrei aplicației și în secțiunea Configuration se selectează XT pentru Oscillator și se șterg
toate bifele de la Fuses.
Se verifică poziționarea corectă a microcontrolerului în soclul programatorului (pinul 1 trebuie
să fie poziționat în stânga sus). În continuare se folosește comanda Command -> Program All din
meniul principal al utilitarului IC-Prog sau butonul asociat din bara de comenzi rapide. În finalul
operațiunii de programare va fi afișat un mesaj de confirmare a finalizării corecte sau un mesaj
de eroare.
15
Microcontrolerul PIC16F84 – Aplicații practice
Trebuie specificat faptul că utilitarul IC-Prog nu poate fi lăsat deschis dacă se dorește
modificarea codului sursă a proiectului inițial deoarece fișierul hex este blocat de către acesta,
iar compilatorul nu poate rescrie fișierul în aceste condiții.
16
Microcontrolerul PIC16F84 – Aplicații practice
LABORATOR 2
Instrucțiuni pentru transferul de date
Scopul lucrării
Lucrarea de laborator prezintă instrucțiunile de transfer de date specifice microcontrolerului
PIC16F84 și exemple practice de utilizare a acestora. Studenții vor dobândi cunoștințe de
utilizare a porturilor microcontrolerului cu ajutorul secvențelor de cod scrise atât în limbaj de
asamblare și în C.
Breviar teoretic
Instrucțiunile de transfer de date folosesc drept sursă și destinație registrul acumulator și ceilalți
regiștrii (regiștrii cu funcții speciale și cei de uz general). Microcontrolerul PIC16F84 nu are
instrucțiuni de transfer cu stiva. Tabelul 1 prezintă instrucțiunile de transfer de date la nivel de
octet și descrierea lor formală. În acest tabel cu w este simbolizat registrul acumulator, cu f este
simbolizat un registru de uz general, K este o valoare numerică imediată, iar d reprezintă
direcția transferului de date atunci când este vorba de instrucțiunea MOVF.
Mnemonic Descriere formală Timp de Indicatori
execuție (cicli) afectați
MOVF f,d d=0: (w) ← (f) 1 Z
d=1: (f) ← (w)
MOVWF f (f) ← (w) 1 Z
MOVLW K (w) ← K 1 -
CLRF f (f) ← 0 1 Z
CLRW (w) ← 0 1 Z
SWAPF f,d f(7:4) ← f(3:0) 1 -
f(3:0) ← f(7:4)
Tabelul 1: Instrucțiuni pentru transferul de date ([1])
17
Microcontrolerul PIC16F84 – Aplicații practice
Pe lângă registrul acumulator, registrul de stare STATUS este deasemenea foarte important în
funcționarea microcontrolerului. Biții acestuia semnalizează starea în care se află unitatea
aritmetică și logică a microcontrolerului după executarea fiecărei instrucțiuni, biții pentru
selecția bancului de menorie utilizat și starea semnalului Reset (fig. 17).
bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
IRP RP1 RP0 TO PD Z DC C
Fig. 17: Structura registrului STATUS
18
Microcontrolerul PIC16F84 – Aplicații practice
19
Microcontrolerul PIC16F84 – Aplicații practice
20
Microcontrolerul PIC16F84 – Aplicații practice
#define – directiva este utilizată pentru definirea unui text de substituire pentru eticheta
specificată; la compilarea codului sursă la fiecare apariție a etichetei asamblorul va
înlocui denumirea acesteia cu textul asociat acesteia
if ... else ... endif – directivele permit definirea unor zone de cod ce vor fi incluse în
funcție de valoarea logică a expresiei scrise după if; sunt acceptate și alternativele #if ...
#else ... #endif; directiva else poate lipsi
versiune equ 6
if versiune == 5
movlw 0x01
movwf PORTB
else
movlw 0x02
movwf PORTA
endif
ifdef ... else ... endif – directivele sunt asemănătoare cu if ... else ... endif cu diferența că
se ține seama doar de faptul că a fost specificat cu directiva #define un anumit simbol;
sunt acceptate și alternativele #ifdef ... #else ... #endif
#define debug
ifdef debug
movlw 0x01
movwf PORTB
21
Microcontrolerul PIC16F84 – Aplicații practice
else
movlw 0x02
movwf PORTA
endif
ifndef ... else ... endif – directivele sunt asemănătoare cu ifdef ... else ... endif cu
diferența că este inclusă secvența ce urmează după ifndef doar dacă simbolul nu a fost
definit; sunt acceptate și alternativele #ifndef ... #else ... #endif
include – directiva permite includerea unui fișier sursă
processor pic16f84
#undefine debug
variable – directiva este utilizată pentru a crea variabile ce pot fi utilizate în cadrul
codului sursă; variabilele pot fi modificate în cadrul codului; variabilele pot primi sau nu
valori inițiale
variable aprins = 1
variable arie
22
Microcontrolerul PIC16F84 – Aplicații practice
while ... endw - directiva permite repetarea secvenței de cod intercalate între while și
endw atâta timp cât expresia scrisă după while este adevărată; repetarea nu se face la
runtime (în timpul execuției programului), ci codul sursă este copiat de mai multe ori
inainte de compilare
variable i = 0
while i<3
movlw i
i += 1
endw
Pentru a introduce secvențe de cod scrise în limbaj de asamblare în cadrul programelor scrise în
limbajul C se pot utiliza directivele preprocesor #asm ... #endasm. Variabilele declarate în C pot
fi utilizate în cadrul secvenței scrise în limbaj de asamblare.
int a = 1;
#asm
movlw _a
addlw 0x10
movwf PORTB
#endasm
Desfășurarea lucrării
Pornind de la schema electronică din fig.18 ce reprezintă o porțiune simplificată din schema
plăcii experimentale Z11/EV, va fi realizat programul pentru aprinderea a două LED-uri atât în
limbaj de asamblare cât și în C. Se observă din schema electronică faptul că LED-urile sunt
conectate la portul B al microcontrolerului, și că pentru aprinderea acestora pinii trebuie să fie
în starea 1 logic. Vor fi utilizate doar LED-urile conectate la pinii RB0 și RB1.
Pentru funcționarea corectă a plăcii experimentale Z11/EV jumperul de configurare va fi pus pe
poziția J3.
Pentru ambele variante de scriere a codului sursă va fi utilizat mediul integrat de dezvoltare
MPLAB. După compilare, fișierul binar va fi încărcat în memoria program a microcontrolerului
folosind utilitarul IC-Prog conform procedurii detaliate în cadrul laboratorului 1.
23
Microcontrolerul PIC16F84 – Aplicații practice
#include<pic.h>
void main(){
TRISB=0x00; // seteaza pinii PORTB ca iesiri
while(1){ // bucla infinita
PORTB=0x03; // seteaza in 1 logic pinul 0 si 1 al portului B
}
}
24
Microcontrolerul PIC16F84 – Aplicații practice
Întrebări și aplicații
1. Scrieți în limbaj de asamblare și în C o aplicație pentru aplinderea alternativă a LED-urilor
(primul aprins, următorul stins, al treilea aprins, șamd). Programul va fi executat în buclă
infinită. Ce se observă?
2. La ce adresă se găsește PORTB și TRISB?
3. Care este rolul registrului TRISB? Dar al registrului PORTB?
25
Microcontrolerul PIC16F84 – Aplicații practice
LABORATOR 3
Instrucțiuni aritmetice și logice
Scopul lucrării
Lucrarea de laborator prezintă instrucțiuni aritmetico-logice și exemple de subrutine realizate cu
acestea. La sfârșitul laboratorului studenții vor avea noțiuni de programare a operațiilor
aritmetice și logice pentru microcontrolerul PIC16F84 atât în C cât și în limbaj de asamblare.
Breviar teoretic
Instrucțiunile aritmetice specifice limbajului de asamblare pentru microcontrolerul PIC16F84 se
regăsesc în tabelul 3. Rezultatul acestor instrucțiuni este salvat în registrul acumulator sau într-
un registru de uz general specificat în cadrul instrucțiunilor.
Mnemonic Descriere formală Timp de Indicatori
execuție (cicli) afectați
ANDWF f,d d=1: (f) ← (w) AND (f)
1 Z
d=0: (w) ← (w) AND (f)
ANDLW k (w) ← k AND (w) 1 Z
ADDWF f,d d=1: (f) ← (w) + (f)
1 C, DC, Z
d=0: (w) ← (w) + (f)
ADDLW k (w) ← k + (w) 1 C, DC, Z
SUBWF f,d d=1: (f) ← (w) - (f)
1 C, DC, Z
d=0: (w) ← (w) - (f)
SUBLW k (w) ← k - (w) 1 C, DC, Z
IORWF f,d d=1: (f) ← (w) OR (f)
1 Z
d=0: (w) ← (w) OR (f)
IORLW k (w) ← k OR (w) 1 Z
26
Microcontrolerul PIC16F84 – Aplicații practice
27
Microcontrolerul PIC16F84 – Aplicații practice
28
Microcontrolerul PIC16F84 – Aplicații practice
Desfășurarea lucrării
Un exemplu simplu de cod scris în limbaj de asamblare pentru ilustrarea unei operațiuni simple
de adunare a două valori numerice 35 (0x23) și 68 (0x44) este următorul:
29
Microcontrolerul PIC16F84 – Aplicații practice
Algoritmul pentru realizarea luminii dinamice cu sens prestabilit este redat în fig.20 în două
variante, în funcție de sensul dorit pentru deplasarea luminii.
Pentru realizarea întârzierilor există mai multe metode practice. În scop didactic, în cadrul
acestei aplicații temporizările sunt obținute software prin folosirea unor bucle cu contor.
Valoarea maximă pe care o poate avea variabila contor determină durata temporizării. În
aplicațiile ulterioare vor fi prezentate și alte modalități practice pentru obținerea unor
temporizări mai precise în cadrul algoritmilor.
Fig. 20: Algoritmul pentru lumină dinamică cu sens fix (deplasare spre stânga și deplasare spre dreapta)
Programul scris în limbaj de asamblare pentru deplasarea luminii dinamice de la dreapta spre
stânga (de la bitul 0 către bitul 7 al portului B) conform algoritmului reprezentat în prima
schemă logică din fig.20 este următorul:
30
Microcontrolerul PIC16F84 – Aplicații practice
; Initializare registri
init: org 0x0000
movlw 0x00
movwf TRISB
movlw 0xFF
movwf COUNT_1
movlw 0xFF
movwf COUNT_2
movlw 0x01
movwf IESIRE
; Program principal
main: movf IESIRE,0
movwf PORTB
call delay
bcf STATUS,C ; sterge bitul CARRY din registrul STATUS
rlf IESIRE ; deplaseaza spre stanga bitul in variabila IESIRE
btfss STATUS,C ; test bit de stare CARRY
goto main
movlw 0x01
movwf IESIRE
goto main
; Rutina de temporizare
delay: decfsz COUNT_1,1
goto delay
movlw 0xFF
movwf COUNT_1
decfsz COUNT_2,1
goto delay
movlw 0xFF
movwf COUNT_1
movlw 0xFF
movwf COUNT_2
return
end
#include <pic.h>
// procedura de temporizare
void delay(){
for(int i=0;i<5000; i++);
}
void main() {
TRISA = 0xFF; // portul A este programat ca intrari
31
Microcontrolerul PIC16F84 – Aplicații practice
while(1){
delay();
a=a<<1; // deplasare spre stanga
Cele două variante ale programului (în limbaj de asamblare și în C) pot fi modificate cu ușurință
pentru a realiza deplasarea spre dreapta a luminii dinamice (de la bitul 7 către bitul 0 al portului
B).
Se remarcă diferența lungimii codului sursă între varianta scrisă în limbaj de asamblare și cea
scrisă în C.
Se poate remarca din această schemă că apăsarea butoanelor PS1 și PS2 pune la masă pinii RA4
și respectiv RA3 ai portului A. Cu alte cuvinte, pentru detectarea apăsării acestor butoane este
necesară testarea valorii 0 logic la pinii RA4 și RA3 ai portului A ce trebuie configurați ca intrări
32
Microcontrolerul PIC16F84 – Aplicații practice
digitale.
Deplasarea luminii se face doar atunci când unul dintre butoane este apăsat. Dacă nici unul
dintre butoane nu este apăsat, sau dacă ambele butoane sunt apăsate, un singur LED va fi
aprins.
Schema logică a algoritmului pentru realizarea acestei aplicații este prezentată în fig.22.
#include <pic.h>
// procedura de intarziere
void delay(){
for(int i=0;i<5000; i++);
33
Microcontrolerul PIC16F84 – Aplicații practice
void main() {
TRISA=0xFF; // configureaza PortA ca intrari
TRISB=0x00; // configureaza PortB ca iesiri
char a=0b00000001; // variabila a memoreaza octetul ce va fi scris in PortB
while(1){
PORTB=a; // scrie a in PortB
delay(); // apeleaza functia de intarziere
34
Microcontrolerul PIC16F84 – Aplicații practice
#include <pic.h>
void main(){
TRISA=0xFF; // configureaza PortA ca intrari
TRISB=0x00; // configureaza PortB ca iesiri
while(1){
if(RA4==0)
PORTB=PORTB | 0xF0; // aprinde LED-urile MSB
else
PORTB=PORTB & 0x0F; // stinge LED-urile MSB
if(RA3==0)
PORTB=PORTB | 0x0F; // aprinde LED-urile LSB
else
PORTB=PORTB & 0xF0; // stinge LED-urile LSB
}
}
Practic aplicația testează permanent stările butoanelor PS1 și PS2 și în funcție de acestea
aprinde sau stinge LED-urile asociate.
35
Microcontrolerul PIC16F84 – Aplicații practice
Fig. 24: Algoritmul pentru utilizarea butoanelor PS1 și PS2 pe post de comutator
#include <pic.h>
void main(){
TRISA=0xFF; // configureaza PortA ca intrari
TRISB=0x00; // configureaza PortB ca iesiri
PORTB=0;
while(1){
if(RA4==0)
36
Microcontrolerul PIC16F84 – Aplicații practice
Fig. 25: Algoritmul pentru utilizarea unui singur buton pe post de comutator
Pentru a înlătura aceste dezavantaje, algoritmul reprezentat în fig.25 permite utilizarea unui
singur buton pentru îndeplinirea funcției de comutator. La prima apăsare a butonului PS1 LED-
urile vor fi aprinse până la o nouă apăsare a acestui buton. Algoritmul ia în considerare și faptul
37
Microcontrolerul PIC16F84 – Aplicații practice
#include <pic.h>
void main(){
TRISA=0xFF; // configureaza PortA ca intrari
TRISB=0x00; // configureaza PortB ca iesiri
PORTB=0;
int activ=0; // memoreaza starea anterioara a butonului
while(1){
if(activ==0){
if(RA4==0){
activ=1;
if(RB0==0)
PORTB=0xFF;
else
PORTB=0;
}
} else
if(RA4==1)
activ=0;
}
}
Întrebări și aplicații
1. Scrieți diferite secvențe de instrucțiuni pentru a exemplifica utilizarea instrucțiunilor
aritmetice și logice în limbaj de asamblare. Ce indicatori de stare sunt modificați în cazul
fiecărei secvențe în parte?
2. Modificați algoritmul aplicației 5 pentru a utiliza butonul PS1 pentru aprinderea și
stingerea a patru LED-uri și PS2 pentru aprinderea și stingerea celorlalte patru LED-uri.
3. Rescrieți aplicațiile 2, 3, 4 și 5 în limbaj de asamblare.
38
Microcontrolerul PIC16F84 – Aplicații practice
LABORATOR 4
Instrucțiuni de salt condiționat și necondiționat
Scopul lucrării
Lucrarea de laborator prezintă instrucțiuni de salt condiționat și necondiționat și exemple de
subrutine realizate cu acestea. La sfârșitul laboratorului studenții vor avea noțiuni de
programare a operațiilor de salt condiționat și necondiționat pentru microcontrolerul PIC16F84
atât în C cât și în limbaj de asamblare.
Breviar teoretic
Instrucțiunile de salt permit modificarea succesiunii de execuție a instrucțiunilor unui program.
Salturile pot fi efectuate în funcție de evaluarea logică a unor expresii și în acest caz este vorba
de instrucțiuni de salt condiționat sau pot fi realizate la întâlnirea unor instrucțiuni specifice
numite instrucțiuni de salt necondiționat.
În limbaj de asamblare instrucțiunile de salt condiționat recunoscute de PIC16F84 se regăsesc în
tabelul 9. Primele două instrucțiuni de salt condiționat testează valoarea unui bit dintr-un
registru și în funcție de valoarea acestuia execută sau nu saltul peste următoarea instrucțiune.
Ultimele două instrucțiuni din acest tabel decrementează sau incrementează valoarea unui
registru și dacă valoarea devine 0 programul va sări peste următoarea instrucțiune.
Instrucțiunile de salt necondiționat în limbaj de asamblare recunoscute de PIC16F84 se regăsesc
în tabelul 10.
Pentru a încheia prezentarea setului de instrucțiuni în limbaj de asamblare recunoscute de
PIC16F84 în tabelul 11 sunt specificate instrucțiunile ce nu pot fi încadrate în categoriile
prezentate anterior.
39
Microcontrolerul PIC16F84 – Aplicații practice
40
Microcontrolerul PIC16F84 – Aplicații practice
Instrucțiunea if
Instrucțiunea if permite implementarea unei structuri decizionale simple ce permite ramificarea
în două direcții diferite a execuției unui program în funcție de evaluarea unei expresii logice.
Structura generală a acestei instrucțiuni este:
if(condiție) {
secvență 1
} else {
secvență 2
};
Dacă la evaluarea logică a condiției aceasta este adevărată, atunci se execută secvența de
instrucțiuni notată cu secvență 1. Dacă rezultatul evaluării este fals, se execută secvența de
instrucțiuni notată cu secvență 2. Dacă o secvență conține o singură instrucțiune, acoladele ce o
încadrează pot lipsi. Deasemenea, un caz particular al acestei structuri presupune existența doar
a primei secvențe. Aceasta va fi executată doar dacă evaluarea condiției conduce la o valoare
adevărată:
if(condiție) {
secvență 1
};
Instrucțiunea switch
Instrucțiunea switch permite implementarea unei structuri decizionale multiple. Structura sa
generică este:
switch(expresie) {
case constantă 1:
secvență 1
break;
case constantă 2:
41
Microcontrolerul PIC16F84 – Aplicații practice
secvență 2
break;
case constantă n:
secvență n
break;
default:
secvență implicită
};
Structura acestei instrucțiuni are câteva particularități. După evaluarea expresiei dintre
paranteze rezultatul este comparat pe rând cu valorile constantelor specificate în clauzele case.
Dacă de exemplu expresia are valoarea constantei 1, se va executa secvența 1 de instrucțiuni.
Dacă nu, se compară valoarea sa cu constanta 2, și așa mai departe până este întâlnită o
egalitate. Dacă valoarea expresiei diferă de toate valorile constante declarate prin clauze case,
atunci se execută secvența implicită de instrucțiuni.
Existența instrucțiunii break este foarte importantă deoarece la întâlnirea sa execuția va fi
transferată instrucțiunii ce urmează structurii switch. Dacă instrucțiunea break lipsește, din
momentul în care s-a găsit o egalitate între valoarea expresiei și una dintre constantele
specificate, se vor executa toate secvențele de cod până la terminarea structurii switch (inclusiv
secvența implicită) sau până la întâlnirea primei instrucțiuni break.
Instrucțiunea while
Instrucțiunea while permite implementarea unei structuri repetitive (bucle) cu test inițial.
Structura sa generică este următoarea:
while(condiție) {
secvență
};
Secvența de instrucțiuni ce formează corpul buclei va fi repetată atâta timp cât condiția este
evaluată ca fiind adevărată din punct de vedere logic. Dacă la testarea inițială condiția este
falsă, secvența nu va fi executată nici măcar o singură dată.
Este imperativ ca instrucțiunile din corpul buclei să influențeze condiția testată pentru ca la un
moment dat aceasta să devină falsă și să se părăsească astfel structura repetitivă.
Trebuie menționat aici faptul că în limbajul C orice expresie evaluată numeric prin valoarea zero
este considerată falsă, în timp ce orice valoare numerică diferită de zero (pozitivă sau negativă)
este evaluată ca fiind adevărată.
42
Microcontrolerul PIC16F84 – Aplicații practice
Instrucțiunea do...while
Instrucțiunea do...while permite implementarea unei structuri repetitive (bucle) cu test final.
Structura sa generică este următoarea:
do {
secvență
} while(condiție);
Secvența de instrucțiuni ce formează corpul buclei va fi repetată atâta timp cât condiția este
evaluată ca fiind adevărată din punct de vedere logic. În această situație corpul buclei va fi
executat cel puțin o dată.
Este imperativ ca instrucțiunile din corpul buclei să influențeze condiția testată pentru ca la un
moment dat aceasta să devină falsă și să se părăsească astfel structura repetitivă.
Instrucțiunea for
Instrucțiunea for permite implementarea unei structuri repetitive (bucle) cu contor. Structura sa
generică este următoarea:
for(inițializare;condiție;modificare) {
secvență
};
Bucla for utilizează o variabilă cu ajutorul căreia se numără de câte ori se va repeta secvența ce
formează corpul buclei. Inițializarea acesteia se face de regulă printr-o instrucțiune de atribuire.
Secvența va fi repetată atâta timp cât condiția specificată este adevărată. Modificarea variabilei
contor se face prin specificarea unei expresii ce incrementează sau decrementează valoarea
acesteia. În cadrul parantezelor instrucțiunii, de la dreapta către stânga pot lipsi una, două sau
toate cele trei expresii, în schimb separatorii dintre acestea sunt obligatorii.
43
Microcontrolerul PIC16F84 – Aplicații practice
Desfășurarea lucrării
La apăsarea butonului PS1 releul RL1 se va închide și se va deschide periodic atâta timp cât
44
Microcontrolerul PIC16F84 – Aplicații practice
butonul este apăsat. În mod similar este implementată funcționarea pentru butonul PS2 și
releul RL2.
Pentru funcționarea acestei aplicații, jumperul de configurare al plăcii experimentale Z11/EV
trebuie pus pe poziția J3.
Programul scris în limbaj de asamblare pentru implementarea aplicației este următorul:
; Initializare
init: org 0x0000
bsf STATUS,RP0
movlw 0x00
movwf TRISB
movlw B'11111000'
movwf TRISA
bcf STATUS,RP0
movlw 0xFF
movwf COUNT_1
movlw 0xFF
movwf COUNT_2
movlw 0x00
movwf RLSTATUS ; RLSTATUS = 0
; Program principal
movf RLSTATUS,0
movwf PORTA
call DELAY
loop: btfss PORTA,P2
call RELE1
btfss PORTA,P1
call RELE2
movf RLSTATUS,0
movwf PORTA
call DELAY
goto loop
45
Microcontrolerul PIC16F84 – Aplicații practice
return
; intarziere
DELAY: decfsz COUNT_1,1
goto DELAY
movlw 0xFF
movwf COUNT_1
decfsz COUNT_2,1
goto DELAY
movlw 0xFF
movwf COUNT_1
movlw 0xFF
movwf COUNT_2
return
end
46
Microcontrolerul PIC16F84 – Aplicații practice
#include <pic.h>
void main() {
char tasta; // memoreaza tasta apasata
TRISA=0b00000000; // initializare semnale PortA
TRISB=0b11110000; // initializare semnale PortB
RB0=1; RB1=1; RB2=1; RB3=1; // toate coloanele matricii pe 1
while(1){
RB0=0; // testare taste de pe prima coloana
if(RB4==0) tasta=1;
if(RB5==0) tasta=4;
if(RB6==0) tasta=7;
if(RB7==0) tasta=14;
RB0=1;
RB1=0; // testare taste de pe a doua coloana
if(RB4==0) tasta=2;
if(RB5==0) tasta=5;
if(RB6==0) tasta=8;
if(RB7==0) tasta=0;
RB1=1;
RB2=0; // testare taste de pe a treia coloana
if(RB4==0) tasta=3;
if(RB5==0) tasta=6;
if(RB6==0) tasta=9;
if(RB7==0) tasta=15;
RB2=1;
RB3=0; // testare taste de pe a patra coloana
if(RB4==0) tasta=10;
if(RB5==0) tasta=11;
if(RB6==0) tasta=12;
47
Microcontrolerul PIC16F84 – Aplicații practice
if(RB7==0) tasta=13;
RB3=1;
; Initializare
bsf STATUS,RP0 ; selecteaza bancul 1
movlw B'11110000'
movwf TRISB ; seteaza PORTB pinii LSB ca iesiri si cei MSB ca intrari
movlw B'00000000'
movwf TRISA ; seteaza pinii PORTA ca iesiri
bcf STATUS,RP0 ; selecteaza bancul 0
bsf PORTB,0
bsf PORTB,1
bsf PORTB,2
bsf PORTB,3
; Programul principal
main
bcf PORTB,0
btfss PORTB,4
movlw D'1'
btfss PORTB,5
movlw D'4'
btfss PORTB,6
movlw D'7'
btfss PORTB,7
movlw D'14'
bsf PORTB,0
bcf PORTB,1
btfss PORTB,4
movlw D'2'
btfss PORTB,5
movlw D'5'
btfss PORTB,6
movlw D'8'
btfss PORTB,7
movlw D'0'
bsf PORTB,1
48
Microcontrolerul PIC16F84 – Aplicații practice
bcf PORTB,2
btfss PORTB,4
movlw D'3'
btfss PORTB,5
movlw D'6'
btfss PORTB,6
movlw D'9'
btfss PORTB,7
movlw D'15'
bsf PORTB,2
bcf PORTB,3
btfss PORTB,4
movlw D'10'
btfss PORTB,5
movlw D'11'
btfss PORTB,6
movlw D'12'
btfss PORTB,7
movlw D'13'
bsf PORTB,3
#include <pic.h>
void delay(){
for(int i=0;i<5000;i++)
for(int j=0;j<2;j++);
};
void main() {
char tasta; // memoreaza tasta apasata
TRISA=0x00; // initializare semnale PortA
TRISB=0xF0; // initializare semnale PortB
PORTB=0x0F; // toate coloanele matricii pe 1
while(1){
RB0=0; // testare taste de pe prima coloana
if(RB4==0) tasta=1;
49
Microcontrolerul PIC16F84 – Aplicații practice
if(RB5==0) tasta=4;
if(RB6==0) tasta=7;
if(RB7==0) tasta=14;
RB0=1;
RB1=0; // testare taste de pe a doua coloana
if(RB4==0) tasta=2;
if(RB5==0) tasta=5;
if(RB6==0) tasta=8;
if(RB7==0) tasta=0;
RB1=1;
RB2=0; // testare taste de pe a treia coloana
if(RB4==0) tasta=3;
if(RB5==0) tasta=6;
if(RB6==0) tasta=9;
if(RB7==0) tasta=15;
RB2=1;
RB3=0; // testare taste de pe a patra coloana
if(RB4==0) tasta=10;
if(RB5==0) tasta=11;
if(RB6==0) tasta=12;
if(RB7==0) tasta=13;
RB3=1;
if((tasta>=0)&&(tasta<=9)){
delay();
tasta=0xFF;
PORTA=tasta;
};
};
}
50
Microcontrolerul PIC16F84 – Aplicații practice
LABORATOR 5
Întreruperi
Scopul lucrării
Lucrarea de laborator prezintă sistemul de întreruperi al microcontrolerului PIC16F84 și exemple
practice de utilizare a acestuia. Studenții vor dobândi cunoștințe de programare a întreruperilor
cu ajutorul secvențelor de cod scrise atât în limbaj de asamblare și în C.
Breviar teoretic
Prin intermediul întreruperilor microcontrolerul poate detecta apariția unor evenimente
externe sau interne și poate executa secvențe de cod pentru tratarea acestor evenimente
(fig.28).
La apariția unei întreruperi execuția normală a programului rulat este întreruptă, adresa
51
Microcontrolerul PIC16F84 – Aplicații practice
următoarei instrucțiuni (conținutul registrului PC) este salvată în vârful stivei, în PC se încarcă
adresa vectorului de tratare a întreruperii (0004h), bitul de validare globală a întreruperilor GIE
este resetat și se continuă execuția de la adresa din PC (Program Counter). La terminarea rutinei
de tratare a întreruperii (pentru microcontrolerul PIC16F84 la execuția instrucțiunii RETFIE), este
setat la loc bitul GIE pentru activarea întreruperilor nemascate, în registrul PC se încarcă adresa
din vârful stivei și programul principal continuă de unde a rămas în momentul apariției
întreruperii.
PIC16F84 dispune de patru surse de întrerupere:
• apariția unei depășiri de capacitate pentru registrul circuitului temporizator TMR0
• apariția unui semnal extern pe pinul RB0/INT
• schimbarea nivelelor logice pe pinii RB7:RB4
• încheierea unui operațiunii de scriere în memoria internă EEPROM
Microcontrolerul PIC16F84 pune la dispoziţie o singură adresă pentru vectorul de întrerupere
(0004h).
Logica de tratare a întreruperilor este reprezentată în fig.29.
Registrul INTCON
Registrul cu funcții speciale dedicat sistemului de întreruperi este registrul INTCON. Cu ajutorul
52
Microcontrolerul PIC16F84 – Aplicații practice
acestuia programatorul poate activa sau dezactiva global sistemul de întreruperi sau fiecare tip
de întrerupere în parte. Biții ce semnalizează apariția unui anumit tip de întrerupere sunt setați
hardware prin mecanismul de generare a întreruperilor. Programatorul trebuie să reseteze
acești indicatori în rutina de tratare a întreruperii pentru a putea fi detectată apariția
următoarei întreruperi. Structura registrului INTCON este prezentată în fig.30.
bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
GIE EEIE T0IE INTE RBIE T0IF INTF RBIF
Fig. 30: Structura registrului INTCON
Registrul OPTION_REG
Un alt registru cu funcții speciale important ce permite configurarea modulului Timer0 este
registrul OPTION_REG a cărui structură este reprezentată în fig.31.
bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0
Fig. 31: Structura registrului OPTION_REG
53
Microcontrolerul PIC16F84 – Aplicații practice
RBPU (PORTB Pull-up Enable) - activează (0) sau dezactivează (1) rezistențele interne de
pull-up pentru portul B.
INTEDG (Interrupt Edge Select) - specifică dacă întreruperea este generată de frontul
crescător (1) sau descrescător (0) al semnalului de pe pinul RB0/INT.
T0CS (TMR0 Clock Source Select) - specifică daca TMR0 este incrementat de ceasul
intern (0) sau de schimbarea semnalului pe pinul RA4/T0CKI (1).
T0SE ( TMR0 Source Edge Select) - specifică dacă incrementarea TMR0 se face pe frontul
crescător (0) sau descrescător (1) al semnalului de pe pinul RA4/T0CKI.
PSA (Prescaler Assignment) - specifică dacă divizorul (prescaler) este asociat TMR0 (0)
sau WatchDog Timer (1).
PS2 - PS0 (Prescaler Rate Select) - specifică valoarea divizorului conform următorului
tabel:
Valoare PS2-PS0 Divizor Divizor
TMR0 WDT
000 1:2 1:1
001 1:4 1:2
010 1:8 1:4
011 1:16 1:8
100 1:32 1:16
101 1:64 1:32
110 1:128 1:64
111 1:256 1:128
54
Microcontrolerul PIC16F84 – Aplicații practice
Desfășurarea lucrării
Pentru realizarea acestei lucrări se utilizează tehnica de modulare în durată a impulsurilor sau
PWM (Pulse Width Modulation) cu ajutorul căreia poate fi controlată tensiunea aplicată unui
dispozitiv electric utilizând un semnal digital. Semnalul digital este schimbat alternativ din
starea OFF în ON și invers cu o frecvență ridicată.
Mărimile caracteristice pentru definirea semnalului PWM sunt perioada semnalului (duty cycle)
și factorul de umplere (fill factor). Perioada semnalului reprezintă cel mai mic interval de timp
după care semnalul se repetă. Factorul de umplere este raportul între durata cât semnalul este
în starea ON față de perioada semnalului. Factorul de umplere este exprimat de regulă
procentual.
Pentru calculul tensiunii medii la ieșirea generatorului PWM se poate folosi formula 1:
55
Microcontrolerul PIC16F84 – Aplicații practice
t ON
U= ⋅U cc (1)
t ON +t OFF
unde:
U tensiunea la ieșire (0 - Ucc)
tON durata cât semnalul este ON
tOFF durata cât semnalul este OFF
Ucc tensiunea de alimentare
Microcontrolerul PIC16F84 nu conține module PWM și de aceea această tehnică trebuie
simulată software.
Pentru realizarea temporizărilor se folosește funcția __delay_us existentă în bibliotecile
compilatorului de C. Aceasta primește ca parametru un întreg reprezentând numărul de
microsecunde cât trebuie întârziată execuția programului. Deoarece viteza de lucru a
microcontrolerului depinde de frecvența de tact a oscilatorului cu cuarț, este necesară definirea
variabilei _XTAL_FREQ pentru calibrarea întârzierii.
Programul în C pentru microcontroler este:
#include<pic.h>
#include<htc.h>
// functia de temporizare
void delay(unsigned int valoare){
for(int i=0;i<valoare;i++)
__delay_us(10);
};
void main(){
int maxOn = 10; // numarul de trepte de variere al factorului de umplere
int pas = 1; // pasul de variere al factorului de umplere
int ledOn = 0; // factorul de umplere curent
int cnt = 0; // variabila pentru periodicitatea de modificare a
// factorului de umplere
TRISA=0xFF; // initializare porturi
TRISB=0x00;
while(1){
PORTB=0xFF; // aprinde LED-urile
delay(ledOn); // temporizare ON
PORTB=0x00; // stinge LED-urile
delay(maxOn-ledOn); // temporizare OFF
cnt++;
if(cnt==500){ // dupa 500 de cicluri
56
Microcontrolerul PIC16F84 – Aplicații practice
57
Microcontrolerul PIC16F84 – Aplicații practice
Utilizarea TMR0 ca și numărător se face setând bitul T0CS din OPTION_REG. TMR0 va fi
incrementat fie pe frontul ascendent (T0SE=0) fie pe cel descendent (T0SE=1) al semnalului de
pe pinul RA4/T0CKI.
Atunci când TMR0 trece de la FFh la 00h (owerflow = depășire de capacitate de memorare) este
generată intern o întrerupere. Această depășire este semnalizată prin setarea (1) bitului T0IF din
registrul cu funcții speciale INTCON. Întreruperea poate fi dezactivată prin resetarea (0) bitului
T0IE din INTCON. Bitul T0IF trebuie resetat în soft de rutina de tratare a întreruperii pentru
Timer0. Întreruperea generată de modulul TMR0 nu poate trezi procesorul din starea de
consum redus (sleep) deoarece în această perioadă funcționarea TMR0 este întreruptă.
Codul sursă scris în C pentru realizarea luminii pulsatorii este:
#include <pic.h>
void initTimer(){
OPTION_REG &= 0xC0; // divizor 1:2
T0IE = 1; // TMR0 Overflow Interrupt Enable
GIE = 1; // Global Interrupts Enable
}
void main() {
TRISB = 0;
RB0 = 0;
initTimer();
while(1){
if (cnt>=245){ // 1 sec
cnt=0;
RB0 = ~RB0;
}
}
}
58
Microcontrolerul PIC16F84 – Aplicații practice
; initializare
init: org 0x0050
bsf STATUS,RP0 ; activeaza bancul 1 de memorie
bcf OPTION_REG,T0CS ; foloseste pentru TMR0 ceasul intern
bcf OPTION_REG,PSA ; asociaza divizorul la TMR0
bsf OPTION_REG,PS0 ; seteaza divizorul cu 011
bsf OPTION_REG,PS1 ; adica 1:16
bcf OPTION_REG,PS2 ;
movlw 0x00 ; configureaza PORTB ca iesiri
movwf TRISB
59
Microcontrolerul PIC16F84 – Aplicații practice
; program principal
main: nop
nop
goto main
end
4. Alarmă electronică
Pe baza schemei electronice din fig.35 se poate realiza o aplicație cu funcționalitate de alarmă
electronică. Codul scris în limbaj de asamblare este următorul:
; initializare
init: org 0x0050
bsf STATUS,RP0 ; activeaza bancul 1 de memorie
bcf OPTION_REG,T0CS ; foloseste pentru TMR0 ceasul intern
bcf OPTION_REG,PSA ; asociaza divizorul la TMR0
bsf OPTION_REG,PS0 ; seteaza divizorul cu 011
bsf OPTION_REG,PS1 ; adica 1:16
bcf OPTION_REG,PS2 ;
movlw 0x00 ; configureaza PORTB ca iesiri
60
Microcontrolerul PIC16F84 – Aplicații practice
movwf TRISB
movlw 0x18 ; configureaza PORTA cu 11000
movwf TRISA
bcf STATUS,RP0 ; activeaza bancul 0 de memorie
bsf INTCON,T0IE ; activeaza intreruperile de la TMR0
movlw SUNET1
movwf SUNET
movwf TMR0 ; preseteaza TMR0 cu valoarea SUNET1
movlw 0xFF
movwf COUNT_1
movlw 0xFF
movwf COUNT_2
bsf INTCON,GIE ; activeaza sistemul de intreruperi
; program principal
main: movlw SUNET1
movwf SUNET
call DELAY
call DELAY
movlw SUNET2
movwf SUNET
call DELAY
call DELAY
goto main
; rutina temporizare
DELAY
decfsz COUNT_1,1
goto DELAY
movlw 0xFF
movwf COUNT_1
decfsz COUNT_2,1
goto DELAY
movlw 0xFF
movwf COUNT_1
movlw 0xFF
movwf COUNT_2
return
end
61
Microcontrolerul PIC16F84 – Aplicații practice
LABORATOR 6
Interfațarea cu afișajul alfanumeric
Scopul lucrării
Lucrarea de laborator prezintă afișorul cu cristale lichide cu 2x16 caractere și modul de
conectare și comunicare a acestuia cu microcontrolerul. Studenții la sfârșitul laboratorului vor
avea noțiuni de programare a LCD-ului cu microcontrolerul PIC16F84.
Breviar teoretic
Afişajul 162B conţine un controler CMOS tip KS0070B pentru afişoare LCD [3]. Acesta este
capabil să afişeze 1 sau 2 linii cu caractere 5x7 puncte sau 1 linie cu caractere de 5x10 puncte.
Poate fi interfaţat cu microcontrolerul pe 4 sau 8 biţi. Setul de caractere cuprinde 192 de
simboluri 5x7 puncte şi 32 simboluri 5x10 puncte. Permite programarea unor simboluri definite
de utilizator prin folosirea generatorului de caractere.
Semnificația pinilor acestui integrat este următoarea:
DB0...DB3 - pini bidirecționali de date (nu se folosesc atunci când conectarea se face pe
4 pini)
DB4...DB7 - pini bidirecționali de date (DB7 se poate utiliza ca semnal BUSY)
RS (Register Select) - selectează registrul de instrucțiuni (0) sau registrul de date (1)
R/W (Read/Write) – stabilește sensul de transmitere al datelor (0 = scriere, 1 = citire)
E (Enable) - tranzitia HIGH → LOW a acestui semnal pornește scrierea la sau citirea de la
afișaj
VSS - masa
VDD - plusul tensiunii de alimentare
VEE - reglaj contrast afișaj
62
Microcontrolerul PIC16F84 – Aplicații practice
63
Microcontrolerul PIC16F84 – Aplicații practice
64
Microcontrolerul PIC16F84 – Aplicații practice
65
Microcontrolerul PIC16F84 – Aplicații practice
66
Microcontrolerul PIC16F84 – Aplicații practice
0 0 0 0 1 1 x x x x
|
Așteaptă minim 4,1ms
|
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 0 0 1 1 x x x x
|
Așteaptă minim 0,1ms
|
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 0 0 1 1 x x x x
|
RS R/W DB7 DB6 DB5 DB4 DB3 DB2 DB1 DB0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 1 I/D SH
|
Sfârșit inițializare
Desfășurarea lucrării
Placa experimentală Z11/EV dispune de un afișor LCD 2x16 caractere conectat la microcontroler
pe 8 biți. Schema electronică simplificată este reprezentată în fig.36. Pentru utilizarea acesteia
este necesar ca jumperul de configurare al plăcii experimentale să fie conectat pe poziția J2.
67
Microcontrolerul PIC16F84 – Aplicații practice
#include<pic.h>
// definire semnale pentru LCD
#define lcd_RS RA2 // Registry Select
#define lcd_RW RA1 // Read/Write
#define lcd_E RA0 // Enable
#define lcd_DATA PORTB // date
// subrutina de intarziere in ms
void delay(unsigned int a){
unsigned int i, j;
for(i=0;i<a;i++)
for(j=0;j<14;j++);
}
void main(){
68
Microcontrolerul PIC16F84 – Aplicații practice
// initializare LCD
void InitLCD(void){
delay(15);
SendCmd(0x30);
delay(5);
SendCmd(0x30);
delay(1);
SendCmd(0x30);
delay(1);
SendCmd(0x38);
SendCmd(0x0c);
SendCmd(0x01);
SendCmd(0x06);
}
69
Microcontrolerul PIC16F84 – Aplicații practice
while(*s)
SendData(*s++);
}
// sterge afisajul
void ClearLCD(void){
SendCmd(0x01);
delay(10);
}
#include <xc.h>
#include<stdio.h>
70
Microcontrolerul PIC16F84 – Aplicații practice
void SendData(char);
void WriteString(const char *);
void ClearLCD();
void main(){
int sec=0, min=0, ora=0;
TRISA=0; // initializare semnale PortA
TRISB=0; // initializare semnale PortB
InitLCD();
ClearLCD();
initTimer();
while(1){
if (cnt>=1000){
cnt=0;
sec++;
if(sec>=60){
min++;
sec=0;
};
if(min>=60){
min=0;
ora++;
};
if(ora>=24) ora=0;
char buffer[10];
sprintf(buffer, "%02i:%02i:%02i", ora, min, sec);
ClearLCD();
WriteString(buffer);
};
};
};
71
Microcontrolerul PIC16F84 – Aplicații practice
// initializare LCD
void InitLCD(void){
__delay_ms(16);
SendCmd(0x30);
__delay_ms(5);
SendCmd(0x30);
__delay_ms(1);
SendCmd(0x30);
__delay_ms(1);
SendCmd(0x38); //function set: 8 bit interface, 2 lines, 5x8 character
SendCmd(0x08); // display off
SendCmd(0x01); //clear display
SendCmd(0x06); // entry mode set: direction increment, do not shift display
// activare LCD
SendCmd(0x0C); // display on, cursor off, cursor blinking off
};
// sterge afisajul
void ClearLCD(void){
SendCmd(0x01);
};
72
Microcontrolerul PIC16F84 – Aplicații practice
LABORATOR 7
Memoria EEPROM. Citirea și scrierea de date
Scopul lucrării
Lucrarea de laborator prezintă memoria EEPROM și modul de citire și scriere a datelor. Studenții
la sfârșitul laboratorului vor avea noțiuni de programare a memoriei EEPROM din
microcontrolerul PIC16F84.
Breviar teoretic
Memoria EEPROM este formată dintr-o matrice de celule de memorie care, la rândul lor, sunt
formate din perechi de tranzistori ce au între ei un strat subţire de oxid izolator. Aceasta poate fi
ştearsă şi reprogramată (rescrisă) în mod repetat prin aplicarea unei tensiuni mai mari decât cea
generată de circuitul extern sau intern.
Microcontrolerul PIC16F84 conține intern 64 octeţi de date EEPROM în intervalul de adrese 00h
to 3Fh. Memoria de date EEPROM poate fi scrisă şi citită în timpul funcționării
microcontrolerului, dar nu este direct mapată în spaţiul regiștrilor de uz general, accesarea fiind
posibilă prin adresare indirectă cu ajutorul regiștrilor cu funcții speciale. Această memorie
rezistă la 10.000.000 de cicluri de scriere/ştergere. Informațiile inscripționate în memoria
EEPROM internă sunt păstrate pentru minim 40 de ani.
Regiștrii cu funcții speciale utilizați pentru programarea memoriei EEPROM sunt:
• EECON1 controlează procesul de scriere / citire
• EECON2 (registru neimplementat fizic)
• EEDATA stochează temporar octetul scris în sau citit din memoria EEPROM
• EEADR înregistrează adresa locaţiei EEPROM accesate. Pentru că pot fi accesate numai
64 locații de memorie, cei doi biți mai semnificativi vor fi întotdeauna 0 pentru a asigura
accesarea corectă a zonei de memorie.
73
Microcontrolerul PIC16F84 – Aplicații practice
La utilizarea acestei funcții trebuie ținut seama de faptul că funcția face doar inițializarea scrierii
și nu așteaptă finalizarea acestei operațiuni. De aceea, orice acces la memoria EEPROM trebuie
să testeze dacă nu cumva există o operațiune de scriere în curs prin testarea bitului WR din
registrul EECON1 astfel:
while(WR) continue;
Prototipul funcției pentru citirea din memoria EEPROM de date este următorul:
Ca și în cazul operațiunii de scriere, înaintea citirii din EEPROM trebuie testat dacă nu există o
74
Microcontrolerul PIC16F84 – Aplicații practice
Desfășurarea lucrării
75
Microcontrolerul PIC16F84 – Aplicații practice
#include <pic.h>
void afiseaza_buffer()
{
for(unsigned char i=0;i<10;i++){
if(buffer_taste[i]==0xFF) break;
PORTA = buffer_taste[i];
__delay_ms(500);
PORTA=0xFF; // sterge afisajul
__delay_ms(250);
};
PORTA=0xFF; // sterge afisajul
};
void sterge_buffer()
{
for(pz_buffer=0;pz_buffer<10;pz_buffer++)
buffer_taste[pz_buffer]=0xFF;
pz_buffer=0;
};
void scrie_EEPROM()
{
for(unsigned char i=0;i<10;i++){
while(WR) continue; // asteapta terminarea ciclului de scriere anterior
eeprom_write(i, buffer_taste[i]);
};
};
void citeste_EEPROM()
{
76
Microcontrolerul PIC16F84 – Aplicații practice
void main() {
unsigned char tasta; // memoreaza codul ultimei taste apasate
unsigned char tasta_apasata=0; // semnalizeaza daca a fost deja apasata o tasta
TRISA=0b00000000; // initializare semnale PortA
TRISB=0b11110000; // initializare semnale PortB
RB0=1; RB1=1; RB2=1; RB3=1; // toate coloanele matricii pe 1
PORTA=0xFF; // sterge afisajul
sterge_buffer();
while(1){
tasta=20; // nici o tasta valida apasata
RB0=0; // testare taste de pe prima coloana
if(RB4==0) tasta=1;
if(RB5==0) tasta=4;
if(RB6==0) tasta=7;
if(RB7==0) tasta=19; // tasta invalida
RB0=1;
RB1=0; // testare taste de pe a doua coloana
if(RB4==0) tasta=2;
if(RB5==0) tasta=5;
if(RB6==0) tasta=8;
if(RB7==0) tasta=0;
RB1=1;
RB2=0; // testare taste de pe a treia coloana
if(RB4==0) tasta=3;
if(RB5==0) tasta=6;
if(RB6==0) tasta=9;
if(RB7==0) tasta=19; // tasta invalida
RB2=1;
RB3=0; // testare taste de pe a patra coloana
if(RB4==0) tasta=10; // tasta A (afisare buffer_taste)
if(RB5==0) tasta=11; // tasta B (stergere buffer_taste)
if(RB6==0) tasta=12; // tasta C (scrie buffer_taste in EEPROM)
if(RB7==0) tasta=13; // tasta D (citeste buffer_taste din EEPROM)
RB3=1;
// daca tasta nu a fosta eliberata nu se mai face tratarea acesteia
if((tasta!=20) && (tasta_apasata==1)) continue;
switch(tasta){
case 20: // semnalizeaza elibeararea tastei
tasta_apasata=0;
break;
case 10: // afisare buffer_taste
tasta_apasata=1;
afiseaza_buffer();
77
Microcontrolerul PIC16F84 – Aplicații practice
break;
case 11: // stergere buffer_taste
tasta_apasata=1;
sterge_buffer();
break;
case 12: // scrie buffer_taste in EEPROM
tasta_apasata=1;
scrie_EEPROM();
break;
case 13: // citeste buffer_taste din EEPROM si afiseaza
tasta_apasata=1;
citeste_EEPROM();
afiseaza_buffer();
break;
default: // tratare cifra valida
tasta_apasata=1;
if(pz_buffer<10) buffer_taste[pz_buffer++]=tasta;
PORTA = tasta;
if((tasta>=0)&&(tasta<=9)){
__delay_ms(500);
PORTA=0xFF; // sterge afisajul
};
};
};
}
78
Microcontrolerul PIC16F84 – Aplicații practice
BIBLIOGRAFIE
1: Microchip, PIC16F8X 18-pin Flash/EEPROM 8-Bit Microcontrollers, 2002
2: Milan Verle, PIC Microcontrollers, 2008, http://www.mikroe.com/products/view/11/book-
pic-microcontrollers/
3: Displaytech, 162B LCD Module
4: M. Hnatiuc, Microcontrolere CISC si RISC. Arhitecturi si principii de programare, Editura
Nautica, Constanta, 2013, ISBN: 978-606-681-014-2
5: Cătălin J. Iov, Mircea B. Slănină, Proiectarea electronică cu PADS, Editura Nautica, Constanţa,
2014, ISBN: 978-606-681-043-2
6: Cătălin J. Iov, Mircea B. Slănină, High speed issues in electronics: Mentor Graphics HyperLynx,
Proceedings of ISEEE 2008, Galaţi, September 12-13, pag. 159 – 164, 2008, ISSN:1842-8046
79
Tiparul executat în
TIPOGRAFIA
UNIVERSITĂȚII MARITIME
Constanța