SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455
119
7. TEMPORIZĂRI SOFTWARE
Cuprins
Introducere
Obiective
7.1 TIMPII DE EXECUŢIE AI INSTRUCŢIUNILOR
7.2 IMPLEMENTAREA ÎNTÂRZIERILOR
7.2.1 Temporizare de 1 microsecundă
7.2.2 Temporizare de 1 milisecundă
Concluzii
Întrebări de autoevaluare
Termeni esenţiali
TEMPORIZĂRI SOFTWARE
120
Introducere
Realizarea temporizărilor este esenţială în cadrul oricărui sistem de calcul
bazat pe microcontrolere. În contextul în care microcontrolerele
funcţionează la nivel de microsecundă, obţinerea unor temporizări chiar la
nivel de milisecundă are mai multe posibilităţi de implementare.
Cea mai simplă modalitate de realizare a unei temporizări este prin
utilizarea instrucţiunilor, sau mai bine zis a timpului de execuţie al
acestora. În acest capitol se vor studia mecanismele prin care se pot
genera temporizări la nivelul milisecundelor sau chiar al secundelor
utilizând instrucţiuni care izolate nu necesită mai mult de 0.2
microsecunde pentru execuţie.
Obiective
După parcurgerea acestui capitol cursantul va trebui:
- să înţeleagă principiul pe baza căruia se obţin întârzierile software;
- să poată implementa rutine de întârziere cu diferite durate;
- să poată adapta rutinele de întârziere prezentate pentru alte valori
ale frecvenţei de lucru;
- să utilizeze rutinele de întârziere în diferite aplicaţii care necesită
temporizări.
7.1 TIMPII DE EXECUŢIE AI INSTRUCŢIUNILOR
Timpul de execuţie al unei instrucţiuni este direct proporţional cu frecvenţa de lucru.
Aceeaşi instrucţiune se va executa mai repede pe sisteme care dispun de o frecvenţă de lucru
mai mare. Tactul de execuţie al instrucţiunilor şi de funcţionare al modulelor interne este
generat pe baza frecvenţei de oscilaţie produsă fie de un oscilator extern (ex. cristal de cuarţ)
conectat la pinii microcontrolerului, fie de oscilatorul intern al microcontrolerului, selectat
prin registrul OSCCON. În ambele cazuri, tactul de oscilaţie este divizat cu 4 pentru asigurarea
celor 4 microcicluri de prelucrare a instrucţiunilor (vezi Capitolul 1).[8]
Arhitectura bazată pe pipeline-ul de două nivele pentru execuţia instrucţiunilor asigură
faptul că durata unui ciclu instrucţiune este egală cu 4 tacţi de oscilaţie.
OSCOSCC F
TT 44 ==
Majoritatea instrucţiunilor microcontrolerului se executâ într-un timp egal cu durata
unui ciclu instrucţiune TC. Există totuşi câteva excepţii care necesită un timp de execuţie mai
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455
121
lung. Aceste excepţii cuprind instrucţiunile care modifică valoarea numărătorului de program
(ex. instrucţiunile de salt) sau instrucţiunile lungi (reprezentate pe 4 octeţi) care nu pot fi
extrase din memorie într-o singură fază. Pentru aceste instrucţiuni timpul de execuţie poate fi
egal cu două sau trei cicluri instrucţiune.
În Tabelul 7.1 sunt prezentate instrucţiunile al căror timp de execuţie este variabil sau
este mai mare decât TC. Durata timpilor de execuţie pentru toate instrucţiunile este cuprinsă în
tabelele prezentate în Capitolul 2.
Tabel 7.1.Timpii de execuţie ai instrucţiunilor
Instrucţiune Timp de execuţie Descriere
Instrucţiuni de mutare
MOVFF 2TC Instrucţiune lungă de 32 de biţi
LFSR 2TC Instrucţiune lungă de 32 de biţi
Instrucţiuni de comparaţie şi salt
CPFSEQ TC sau 2TC sau 3TC
CPFSGT TC sau 2TC sau 3TC
CPFSLT TC sau 2TC sau 3TC
DECFSZ TC sau 2TC sau 3TC
DCFSNZ TC sau 2TC sau 3TC
INCFSZ TC sau 2TC sau 3TC
INFSNZ TC sau 2TC sau 3TC
TSTSFZ TC sau 2TC sau 3TC
BTFSC TC sau 2TC sau 3TC
BTFSS TC sau 2TC sau 3TC
TC – fără salt;
2TC – cu salt peste instrucţiune de 16 biţi
3TC – cu salt peste instrucţiune de 32 biţi
Instrucţiuni de salt
BC TC sau 2TC
BN TC sau 2TC
BNC TC sau 2TC
BNN TC sau 2TC
BNOV TC sau 2TC
BNZ TC sau 2TC
BOV TC sau 2TC
BZ TC sau 2TC
TC – fără salt;
2TC – cu salt
BRA 2TC Salt necondiţionat
GOTO 2TC Instrucţiune lungă de 32 de biţi. Salt necondiţionat
Instrucţiuni de apel de subrutină
CALL 2TC Instrucţiune lungă de 32 de biţi cu salt / apel
RCALL 2TC Apel de subrutina = salt la o adresă din memorie
TEMPORIZĂRI SOFTWARE
122
Tabel 7.1.Timpii de execuţie ai instrucţiunilor (continuare)
Instrucţiune Timp de execuţie Descriere Instrucţiuni de revenire din subrutină
RETURN 2TC
RETFIE 2TC
RETLW 2TC
Instrucţiuni tabelare
Revenire din subrutină = salt la adresa de
revenire din subrutină (se modifică PC)
TBLRD* 2TC C1: citire memorie, C2: scriere TABLAT
TBLWT* 2TC C1: citire TABLAT, C2: scriere memorie
Analizând Tabelul 7.1 se poate observa că instrucţiuni simple precum MOLW, BSF sau
CLRF se execută într-un timp egal cu durata unui ciclu instrucţiune TC, pe când instrucţiunile
lungi, cele de salt necondiţionat, cele de apel şi revenire din subrutină şi instrucţiunile tabelare
se execută într-un timp dublu egal cu durata a două cicluri instrucţiune 2TC. Pe de altă parte
există o serie de instrucţiuni care realizează salturi condiţionate ale căror timpi de execuţie
depind de context. Cazul unei asemenea instrucţiuni va fi analizat în exemplul următor.
Exemplu
Să analizăm timpul de execuţie al instrucţiunii CPFSEQ. Se consideră cele trei
cazuri posibile evidenţiate în Fig. 7.1.
Fig. 7.1. Timpii de execuţie ai instrucţiunii CPFSEQ
În cazul a. condiţia de salt nu este îndeplinită, iar instrucţiunea CPFSEQ se
execută într-un timp TC.
În cazul b. condiţia de salt este îndeplinită, trebuie să se realizeze saltul peste
o instrucţiune scurtă (ex. BCF), iar instrucţiunea CPFSEQ se execută într-un
timp 2TC.
În cazul c. condiţia de salt este îndeplinită, trebuie să se realizeze saltul peste
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455
123
o instrucţiune lungă (ex. GOTO), iar instrucţiunea CPFSEQ se execută într-un
timp 3TC.
După cum s-a menţionat anterior, durata unui ciclu instrucţiune depinde de frecvenţa
de lucru a microcontrolerului. Fără a cunoaşte cu exactitate această frecvenţă de oscilaţie nu
putem calcula cu exactitate durata unui ciclu instrucţiune TC şi astfel nu putem şti care este
timpul necesar execuţiei instrucţiunilor.
Întrucât microcontrolerele suportă numeroase frecvenţe de lucru vom analiza două
valori frecvent întâlnite în practică: FOSC=4MHz, respective FOSC = 20MHz. Pornind de la
aceste două valori rezultă următoarea durată a unui ciclu instrucţiune:
sMHzF
TT
sMHzF
TT
OSCOSCC
OSCOSCC
μ====
μ====
2.020
444
14
444
În aceste condiţii, în cazul unui microcontroler care dispune de un oscilator cu
frecvenţa de oscilaţie de 20MHz, instrucţiunea CPFSEQ, analizată anterior va fi executată în
0.2μs, 0.4μs sau 0.6μs în funcţie de contextul în care aceasta este executată. Având
posibilitatea de a calcula timpul necesar execuţiei fiecărei instrucţiuni putem proiecta
subrutine sau secţiuni de cod care se vor executa într-un anumit timp, implementând astfel
întârzieri software.
7.2 IMPLEMENTAREA ÎNTÂRZIERILOR
În contextul celor prezentate anterior, în aceast paragraf se vor prezenta câteva
exemple pentru implementarea unor temporizări uzuale.
7.2.1 Temporizare de 1 microsecundă
În cazul unei frecvenţe de lucru de 4MHz, temporizarea de 1 microsecundă poate lua
forma unui apel a instrucţiunii NOP. Această instrucţiune nu realizează nici o operaţie,
execuţia ei nu modifică nici un registru, ci doar consumă timpul procesorului.
Din cauza setului de instrucţiuni disponibil o temporizare la nivel de microsecundă are
moduri multiple de implementare. Practic, în cazul FOSC=4MHz orice instrucţiune scurtă se va
executa în timp de 1μs.
TEMPORIZĂRI SOFTWARE
124
De regulă, se recomandă ca o temporizare să poată fi utilizată cât mai uşor şi să
asigure o interfaţă care să ascundă detaliile legate de implementare. Astfel, de obicei
temporizarea trebuie să ia forma unei rutine. Astfel, un exemplu de rutină care produce o
întârziere de 1 microsecundă în cazul unei frecvenţe de lucru de 20MHz este următorul:
Delay1us:
NOP ;0.2us RETURN ;0.4us […] CALL Delay1us ;0.4us
În exemplul anterior, timpul necesar execuţiei rutinei Delay1us se calculează în
felul următor:
∆(Delay1us) = ∆(CALL) + ∆(NOP) + ∆(RETURN) = 0.4μs + 0.2μs + 0.4μs = 1μs
În rutina Delay1Micro s-a utilizat instrucţiunea NOP deoarece aceasta nu afectează
nici un registru. Astfel, rutina creată poate fi utilizată în orice context de execuţie. Desigur, în
locul instrucţiunii NOP se poate utiliza orice altă instrucţiune care să se execute în 0.2μs, dacă
se iau în considerare şi efectele posibile ale instrucţiunii incluse în rutină.
Exemplu
Să se genereze în mod repetat pe PORTA<0> un tren de impulsuri de forma
urmatoare:
Fig. 7.2. Tren de impulsuri
Pentru a rezolva această cerinţă, trebuie configurat portul A, astfel încât
bitul 0 să fie de ieşire. Mai este necesară definirea unor subrutine pentru
temporizările implicate. Apelul acestor subrutine, corelat cu seterea şi
resetarea bitului de ieşire conduc la obţinerea funcţionalităţii dorite.
Următorul cod sursă cuprinde rezolvarea acestei probleme.[8]
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455
125
#include “P18F4455.INC” ORG 0x800 ;salt peste suburutine la programul principal
GOTO Main Delay1us: ;0.2us+0.4us+CALL = 1us
NOP RETURN
Delay2us: ;1us+0.2us+0.4us+CALL = 2us
CALL Delay1us NOP RETURN
Delay3us: ;2us+0.2us+0.4us+CALL = 3us
CALL Delay2us NOP RETURN
Delay5us: ;1us+3us+0.2us+0.4us+CALL = 5us
CALL Delay1us CALL Delay3us NOP RETURN
Main: ; iniţializare port
CLRF PORTA BCF TRISA, 0
Bucla_main: ;Generarea impulsurilor
BSF PORTA, 0 CALL Delay2us BCF PORTA, 0 CALL Delay2us BSF PORTA, 0 CALL Delay3us BCF PORTA, 0 CALL Delay1us BSF PORTA, 0 CALL Delay1us BCF PORTA, 0 CALL Delay1us BSF PORTA, 0 CALL Delay5us BCF PORTA, 0 CALL Delay1us GOTO Bucla_main ;Reluarea ciclului
END
TEMPORIZĂRI SOFTWARE
126
7.2.2 Temporizare de 1 milisecundă
După cum s-a văzut până acum implementarea unei întârzieri software constă pur şi
simplu din consumarea timpului procesorului prin lipsa unor operaţii pe durata de timp dorită.
O altă modalitate de a realiza acest lucru constă în consumarea timpului cu decrementarea
unei variabile de la o valoare prestabilită spre 0, după cum se poate vedea în Fig. 7.3. Prin
alegerea unei valori adecvate pentru valoarea iniţială, se poate obţine întârzierea dorită.
Bineînţeles, această întârziere depinde de frecvenţa de lucru a microcontrolerului. Pentru acest
exemplu vom considera FOSC = 4MHz care determină un ciclu instrucţiune cu durata TC=1μs.
Fig. 7.3. Întârziere de o milisecundă obţinută prin decrementarea unui contor
Subrutina următoare conţine implementarea întârzierii cu durata de 1 milisecundă în
cazul FOSC = 4MHz.
N EQU d’249’ Delay1ms:
MOVLW N ;1us Bucla1ms:
DECF WREG ;N*1us NOP ;N*1us BNZ Bucla1ms ;(N-1)*2us+1us RETURN ;2us
[…]
CALL Delay1ms ;2us
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455
127
Timpul necesar execuţiei rutinei Delay1ms se calculează în felul următor:
∆(Delay1ms)= ∆(MOVLW) + N·(∆(DECF)+ ∆(NOP)) +(N-1)·∆(BNZ)cu salt + ∆(BNZ)fără salt
+ ∆(RETURN) + ∆(CALL) = 1μs+249·(1μs+1μs)+248·2μs+1μs+2μs+2μs=1000μs=1ms
Pentru a ajunge la o temporizare de 1 milisecundă în cazul FOSC = 20MHz se poate
utiliza codul următor:
N EQU d’217’ Delay1ms:
MOVLW N ;0.2us Bucla1ms:
CALL Delay1us ;N*1us CALL Delay1us ;N*1us CALL Delay1us ;N*1us CALL Delay1us ;N*1us DECFSZ WREG,W ;(N-1)*0.2us+0.6us GOTO Bucla1ms ;(N-1)*0.4us NOP ;0.2us NOP ;0.2us NOP ;0.2us NOP ;0.2us RETURN ;0.4us
[…]
CALL Delay1ms ;0.4us
Durata întârzierii atinse se calculează în felul următor:
∆(Delay1ms) = ∆(MOVLW) + (N-1)·( 4·∆(Delay1us) + ∆(DECFSZ)fără salt + ∆(GOTO) ) +
4·∆(Delay1us) + ∆(DECFSZ)cu salt + 4·∆(NOP) + ∆(RETURN)+ ∆(CALL) = 0.2μs + (217 -
1)·(4·1μs + 0.2μs + 0.4μs) + 4·1μs + 0.6μs + 4·0.2μs + 0.4μs + 0.4μs = 1000μs=1ms
În implementarea subrutinei de mai sus s-a considerat definită în prealabil subrutina
Delay1us conform celor prezentate în paragraful 4.2.1.
Pornind de la rutina care implementează întârzierea de o milisecundă se pot
implementa alte subrutine pentru obţinerea unor temporizări cu durată mai mare. În funcţie de
specificul aplicaţiilor implementate, aceste temporizări pot fi mai mult sau mai puţin exacte.
Exemplul următor detaliază acest lucru.
TEMPORIZĂRI SOFTWARE
128
Exemplu
Se doreşte implementarea unei subrutine care realizează o temporizare cu
durata de 100ms. În mod obişnuit o asemenea temporizare s-ar putea obţine
prin apelul repetat de o sută de ori al subrutinei Delay1ms implementată
anterior, conform Fig. 7.4.
Fig. 7.4. Întârziere de 100ms
Subrutina următoare ar putea reprezenta o soluţie la această problemă
Contor EQU 0x00 Delay100ms:
MOVLW d’100’ ;0.2us MOVWF Contor ;0.2us
Bucla100ms: CALL Delay1ms ;100*1ms DECFSZ Contor, F ;(100-1)*0.2us+0.6us GOTO Bucla ;(100-1)*0.4us RETURN ;0.4us
[…]
CALL Delay100ms ;0.4us
Calculând durata întârzierii obţinute prin utilizarea acestei subrutine
obţinem ∆(Delay100ms)=100061.2μs=100.0612ms. Întârzierea astfel
obţinută nu este într-u totul exactă, dar abaterea faţă de valoarea dorită este
nesemnificativă. În general, asemenea abateri nu influenţează aplicaţiile
care necesită temporizări cu un astfel de ordin de mărime (zeci, sute de
milisecunde).
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455
129
Una din problemele frecvent întâlnite în aplicaţiile pentru microcontrolere este
problema eliminării oscilaţiilor apărute la apăsarea sau eliberarea unui buton în vederea
detectării frontului crescător sau descrescător.
Detectarea apăsării unui buton necesită o atenţie deosebită deoarece o serie de
elemente fizice influenţează direct semnalul rezultat. Întrucât contactele unui buton (sau
releu) nu se închid perfect instantaneu la fiecare apăsare, semnalul rezultat va prezenta foarte
multe zgomote / oscilaţii imediat după apăsare, zgomote care sunt percepute de
microcontroler ca apăsări succesive ale butonului.
În Fig. 7.5 se exemplifică acest fenomen.
Fig. 7.5. Oscilaţii la apăsarea / eliberarea butoanelor
Intervalul de stabilizare al semnalului poate varia foarte mult în funcţie de tipul
butonului şi caracteristicile apăsării efectuate (ex. o apăsare lentă sau una rapidă). Tocmai din
această cauză, înainte de a trece la implementare, se recomandă determinarea acestui interval
de stabilizare cu ajutorul unui osciloscop (Fig. 7.6). De regulă butoanele uzuale au acest
interval cuprins între 200μs şi 10ms.
Fig. 7.6. Vizualizarea pe osciloscop a oscilaţiilor apărute la eliberarea unui buton
TEMPORIZĂRI SOFTWARE
130
Eliminarea oscilaţiilor din intervalul de stabilizare se face prin program relativ simplu.
Ideea de bază este de a citi periodic (eşantiona) semnalul care provine de la buton şi de a filtra
zgomotele produse. Există mai multe abordări privind rezolvarea acestei probleme. Una dintre
ele presupune utilizarea unui contor pentru a determina durata de timp în care semnalul a fost
în stare logică ‘0’. Dacă semnalul respectiv a fost ’0’ continuu o anumită durată de timp,
atunci acel semnal poate fi considerat stabil, iar butonul apăsat. Practic, la apariţia unui front
de apăsare se aşteaptă un timp ∆t în care alte fronturi nu se iau în considerare. După expirarea
acestui interval se poate considera că a avut loc o apăsare.
Exemplul următor oferă o soluţie la această problemă.
Exemplu
Se consideră un buton conectat la PORTD<0> al unui microcontroler cu
frecvenţa de lucru FOSC=20MHz. La apăsarea butonului, pe pinul portului se
va citi valoarea 0 logic. Se consideră intervalul de stabilizare al semnalului
provenit de la buton având durata ∆t=10ms. De asemenea, se mai consideră
ca fiind definite anterior: subrutina de iniţializare a portului Init_port,
subrutina de o microsecundă Delay1us şi subrutina de o milisecundă
Delay1ms.
Se cere să se determine apariţia frontului ca urmare a apăsării butonului şi
să se elimine oscilaţiile apărute.
Fig. 7.7. Eliminarea oscilaţiilor din intervalul de stabilizare
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455
131
În Fig. 7.7 se prezintă algoritmul utilizat pentru eliminarea oscilaţiilor
apărute în intervalul de stabilizare a semnalului provenit de la buton ca
urmare a apăsării acestui.
Programul va sta într-o buclă de testare / eşantionare a semnalului provenit
de la buton până se va detecta o apăsare (semnalul va fi 0 logic). Dacă după
∆t=10ms butonul continuă să fie apăsat, atunci apăsarea se va considera ca
fiind validă, iar programul va continua. Dacă după ∆t=10ms butonul nu este
apăsat (semnalul este 1 logic) atunci se consideră că la prima testare au fost
detectate doar niste oscilaţii care nu trebuie interpretate ca fiind apăsări
valide ale butonului.
Programul utilizează o variablilă denumită Front utilizată pentru a marca
starea semnalului de intrare de pe port între cele două testări succesive. La
apariţia unei apăsări valide variabila Front se va schimba din 0x00 în
0xFF, în caz contrar îşi va păstra starea avută iniţial.
Front EQU 0x00 Contor10ms EQU 0x01
GOTO Main ;salt peste subrutine […]
Delay10ms: ;subrutina de 10ms
MOVLW d’10’ MOVWF Contor10ms
Bucla10ms: CALL Delay1ms DECFSZ Contor10ms,F GOTO Bucla10ms RETURN […]
Main: ;programul principal
CALL Init_port ;iniţializare porturi CLRF Front ;Front=0x00
Test_btn: ;testare buton
BTFSS PORTD,0 GOTO Buton_apasat GOTO Test_btn
Buton_apasat:
CALL Delay10ms ;aştept ∆t=10ms MOVF Front, W ;salvez starea anterioară
TEMPORIZĂRI SOFTWARE
132
BTFSS PORTD,0 ;a 2-a testare a butonului SETF Front ;apăsare validă. Front=0x00 CLRF Front ;apăsare invalidă. Front=0xFF
Test_front: ;testare front CPFSGT front GOTO Front_detectat GOTO Test_btn
Front_detectat:
[…] ;acţiuni efectuate la ;detectarea unei apăsări ;valide
Concluzii
Una dintre cele mai accesibile metode de a reliza temporizări presupune
utilizarea timpului de execuţie al instrucţiunilor. Dacă se cunoaşte durata
acestui timp se pot proiecta subrutine sau secţiuni de cod care
implementează întârzieri software cu diferite durate.
Întârzierile software reprezintă o soluţie de realizare a temporizărilor care
este disponibilă în cazul tuturor microcontrolerelor pentru care se
cunoaşte timpul de execuţie al instrucţiunilor.
1. Ce este o întârziere software?
2. În ce condiţii timpul de execuţie al instrucţiunii DECFSZ este TC,
sau 2TC sau 3TC?
3. Care este durata unui ciclu instrucţiune în cazul utilizării unei
frecvenţe de lucru de 48MHz?
4. Cum s-ar implementa o subrutină care implementează o întârziere
cu durata de 1μs în cazul utilizării unei frecvenţe de lucru de
48MHz?
5. În cazul subrutinei de 100ms implementată în acest curs, cât ar fi
abaterea obţinută dacă instrucţiunea Delay1us ar implementa de
fapt o întârziere de 1.2μs?
6. De ce apar oscilaţii la apăsarea butoanelor?
Întrebări de autoevaluare
7. De ce instrucţiunea MOVFF se execută într-un timp de 2TC?
SISTEME CU MICROPROCESOARE. MICROCONTROLERUL PIC18F4455
133
Termeni esenţiali
Ciclu instrucţiune
Durata de timp egală cu 4TOSC a fazelor instrucţiunii
Instrucţiuni
Comenzi codificate binar pe care le execută UCP
Întârziere software
Temporizare realizată pe baza timpului de execuţie al instrucţiunilor
Pipeline
Tehnică utilizată pentru a creşte numărul de instrucţiuni care pot fi
executate în unitatea de timp. Pipeline-ul nu reduce timpul necesar
execuţiei unei instrucţiuni, ci creşte numărul de instrucţiuni care pot fi
procesate simultan
Subrutină
Structură de organizare a programelor care ia forma unor instrucţiuni
cuprinse între o etichetă şi o instrucţiune de revenire din subrutină.
Unitate independentă de program, plasată în memorie în altă zonă decât
programul principal