Numărător de cicluri mașină și numărător de evenimente
Microcontrolere din familia PIC18F au cinci module de numărare. Acestea pot funcționa în
două moduri distincte, și anume: numărător de cicluri mașină (timer) sau numărător de
evenimente (counter).
În ambele moduri dispozitivul poate fi utilizat pentru generarea unei întârzieri sau contorizarea
timpului, fie prin numărarea ciclurilor mașină, fie prin numărarea evenimentelor din exteriorul
microcontrolerului.
1.1 Numărătorul 0
Numărătorul 0 poate fi configurat să lucreze în cele două moduri prezentate atât pe 8 cât și pe
16 biți. De asemenea, acesta dispune de un divizor de frecvență programabil (prescaler),
precum și de o sursă de ceas selectabilă (internă sau externă).
Configurarea numărătorului se realizează prin intermediul registrului T0CON:
unde:
TMR0ON – bit de activare/dezactivare
o 1 – activează numărătorul
o 0 – dezactivează numărătorul
T08BIT – bit care determină selectarea registrelor de lucru
o 1 – numărător pe 8 biți
o 0 – numărător pe 16 biți
T0CS – bit care permite selectarea modului de lucru
o 1 – numărător de evenimente – tranziții la pinul T0CKI
o 0 – numărător de cicluri mașină
T0SE – bit care determină numărarea evenimentelor
o 1 – evenimentele sunt numărate pe frontul descrescător
o 0 – evenimentele sunt numărate pe frontul crescător
PSA – bit pentru asignarea divizorului de frecvență
o 1 – divizorul de frecvență este inactiv
o 0 – divizorul de frecvență este activ
T0PS<2÷0> - biți pentru stabilirea raportului de divizare
o 111 – raport 1:256
o 110 – raport 1:128
o 101 – raport 1:64
o 100 – raport 1:32
o 011 – raport 1:16
o 010 – raport 1:8
o 001 – raport 1:4
o 000 – raport 1:2
Pentru configurarea numărătorului se parcurg următorii pași:
Se alege modul de lucru prin bitul T0CS,
Se stabilește numărul de biți corespunzători numărătorului prin bitul T08BIT,
Dacă este necesar se configurează divizorul de frecvență, cu raportul dorit prin biții PSA
și T0PS<2÷0>,
Dacă se alege modul numărător de evenimente externe trebuie configurat și bitul T0SE,
Se activează întreruperea pentru numărătorul 0 prin bitul TMR0IE din registrul INTCON,
Se dezactivează bitul de tip fanion TMR0IF din registrul INTCON,
Se inițializează registrele TMR0L și TMR0H,
Se activează numărătorul prin bitul TMR0ON.
Dacă se dorește generarea unei anumite întârzieri, atunci numărul de umpleri ale registrelor
TMR0H:TMR0L se poate determina cu relația:
Nr. . ț
∗ : ∗ ∗
unde:
Nr. biți – reprezintă numărul biților pe care se lucrează (8 sau 16)
𝑇𝑀𝑅0𝐻: 𝑇𝑀𝑅0𝐿 - reprezintă valorile de inițializare ale celor două registre
𝐷𝑖𝑣 – reprezintă raportul de divizare
𝑓 – reprezintă frecvența semnalului generat
Prin urmare, sunt necesare, în acest caz 61 de umpleri ale registrului TMR0L (numărări de la 0 la
FFh) pentru a genera o întârziere de jumătate de secundă.
1.2 Numărătorul 1
Numărătorul 1 poate funcționa în trei moduri, și anume: numărător de cicluri mașină,
numărător sincron de evenimente și numărător asincron de evenimente.
Acesta poate fi configurat să lucreze pe 16 biți, cu sau fără divizor de frecvență. O facilitate
importantă a acestui numărător este posibilitatea de generare a unui ceas de timp real prin
intermediul cristalului de frecvență joasă, încorporat.
Configurarea numărătorului se realizează prin intermediul registrului T1CON, cu următoarea
structură:
unde:
RD16 – bit de activare a modului de citire/scriere pe 8 sau 16 biți
o 1 – activează scrierea/citirea registrele de lucru într-o singură operație pe 16 biți
o 0 – activează scrierea/citirea registrele de lucru în două operații pe 8 biți
T1RUN – bit pentru stabilirea sursei de ceas
o 1 – ceasul este generat de oscilatorul numărătorului 1
o 0 – ceasul este generat prin intermediul altor surse
T1CKPS<1:0> – biți pentru stabilirea raportului de divizare
o 11 – raport 1:8
o 10 – raport 1:4
o 01 – raport 1:2
o 00 – raport 1:1
T1OSCEN – bit de activare a oscilatorului numărătorului 1
o 1 – oscilatorul este activat
o 0 – oscilatorul este dezactivat
T1SYNC – bit pentru intrarea de sincronizare a ceasului extern
o Dacă bitul TMR1CS = 1:
1 – nu se realizează sincronizarea intrării ceasului extern
0 – se realizează sincronizarea intrării ceasului extern
o Dacă bitul TMR1CS = 0:
Numărătorul folosește ceasul intern, iar acest bit este ignorat
TMR1CS – bit pentru selectarea sursei de ceas
o 1 – ceas extern prin pinii RC0/T1OSO/T13CKI
o 0 – Ceas intern (𝐹 /4)
TMR1ON – bitul de activare a numărătorului 1
o 1 – numărător activat
o 0 – numărător dezactivat
1.3 Numărătorul 2
Numărătorul 2 este un dispozitiv ce lucrează doar la nivel de octet. Dispune de două registre
denumite PR2 și TMR2. De asemenea, numărătorul este prevăzut cu două divizoare de frecvență,
unul pentru frecvența semnalului de intrare (în eng. prescaler) și celălalt pentru frecvența
semnalului de ieșire (în eng. postscaler).
Structura registrului de configurare este:
unde:
T2OUTPS<3:0> – biți pentru stabilirea raportului de divizare a frecvenței semnalului
de ieșire (postscalor)
o 0000 – raport 1:1
o .....
o 1111 – raport 1:16
TMR2ON – bitul de activare a numărătorului 2
o 1 – numărător activat
o 0 – numărător dezactivat
T2CKPS<1:0> – biți pentru stabilirea raportului de divizare a frecvenței semnalului de
intrare (prescalor)
o 00 – raport 1:1
o 01 – raport 1:4
o 1x – raport 1:16
Funcționarea presupune înscrierea unei valori în registrul PR2, și numărarea în registrul TMR2
de la valoarea inițială 00h. Viteza de numărare este 𝐹 /4, dacă nu este folosit un divizor cu
rapoartele 1:4 sau 1:16. Verificarea celor două registre se realizează la fiecare ciclu mașină, și
atunci când conținutul celor două registre coincide se va genera un semnal de „potrivire”.
Semnalul are rolul de a reinițializa registrul TMR2. Semnalul generat va reprezenta intrarea într-
un comparator, și respectiv într-un divizor pe 4 biți cu factorii 1:1 până la 1:16. Acest divizor
va genera o întrerupere la depășire, semnalizată prin intermediul activarea fanionului TMR2IF.
Activarea întreruperii se realizează prin setarea bitului TMR2IE din registrul PIE1.
Aplicații:
1. Aplicația permite modificarea nivelului primei linii a portului D (RD0) folosind întreruperea
numărătorului 0. În acest caz numărătorul este utilizat în modul timer și va introduce o
întârziere de 500 ms. Se consideră pentru această aplicație următoarele date de pornire:
F 4 MHz
Div 1: 32
Nr. biți 8
TMR0L 0
1
f 2 Hz
0.5
Conform relației (3), rezultă:
4 ∗ 10
Nr. ≅ 61
4∗ 2 0 ∗ 32 ∗ 2
#include <xc.h>
#pragma config OSC = HS
int i = 0;
void init()
{
LATD = 0x0;
TRISD = 0x0;
OSCCON = 0x62;
[Link] = 1;
T0CONbits.T08BIT = 1;
T0CONbits.T0CS = 0;
[Link] = 0;
T0CONbits.T0PS2 = 1;
T0CONbits.T0PS1 = 0;
T0CONbits.T0PS0 = 0;
INTCONbits.TMR0IE = 1;
INTCONbits.TMR0IF = 0;
TMR0L = 0;
T0CONbits.TMR0ON = 1;
}
void interrupt t0()
{
if(INTCONbits.TMR0IF == 1)
{
i++;
if(i == 61)
{
LATDbits.LATD0 = ~LATDbits.LATD0;
i = 0;
}
INTCONbits.TMR0IF = 0;}
}
void main(void)
{
init();
while (1);
}
Pentru această aplicație, schema de simulare în mediul Proteus (figura 1) cuprinde următoarele
elemente:
Microcontroler PIC18F8722 cu F 4 MHz,
Un LED conectat la linia de ieșire RD0,
Un osciloscop ce va înregistra semnalul transmis pe liniile de ieșire.
Fig. 1 Schema de implementare în mediul Proteus.
Rezultatul înregistrat pe osciloscop, în mediul Proteus este prezentat în Figura 2. Se poate
observa modificarea nivelului la intervale egale cu 500 ms.
Fig. 54 Semnal înregistrat pe osciloscop în mediul Proteus.
O metodă alternativă de programare a numărătorului de cicluri mașină, constă în determinarea
valorilor de inițializare a registrelor de numărare.
Astfel, în cazul considerat, 𝐹 1𝑀𝐻𝑧, divizor de frecvență: 1:32, prin urmare, F
31250Hz, atunci, T 32 μs.
Pentru o întârziere de 500 ms., vom avea:
∗
15625 3𝐷09 .
Valoarea de inițializare a celor două registre de numărare este:
𝑇𝑀𝑅0𝐻: 𝑇𝑀𝑅0𝐿 𝐹𝐹𝐹𝐹 3𝐷09 𝐶2𝐹6
#include <xc.h>
#pragma config OSC = HS
void init()
{
T0CON = 0x04;
TMR0H = 0xC2;
TMR0L = 0xF6;
}
void del()
{
init();
T0CONbits.TMR0ON = 1;
while(INTCONbits.TMR0IF == 0);
T0CONbits.TMR0ON = 0;
INTCONbits.TMR0IF = 0;
}
void main()
{
LATD = 0x0;
TRISD = 0x0;
OSCCON = 0x62;
while(1)
{
LATDbits.LATD0 = ~LATDbits.LATD0;
del();
}
}
2. Se dorește modificarea nivelului pe liniile portului D (liniile RD0 și RD1) folosind întreruperile
numărătoarelor 1 și 2. Numărătorul 2 se găsește pe nivel de prioritate ridicată, în timp ce
numărătorul 1 se găsește pe nivel de prioritate scăzută.
Alte specificații funcționale:
F 8 MHz, raport de divizare pentru numărătorul 1 – 1:2, raport de divizare pentru
numărătorul 2 – 1:1.
Dimensionarea numărătoarelor se va realiza astfel:
Numărător 1:
F 8 MHz
f 4 Hz
Div 2
TMR1 0
8 ∗ 10
𝑁𝑟. ≅4
4∗ 2 𝑇𝑀𝑅1 ∗ 2 ∗ 4
Numărător 2:
F 8 MHz
Div 1
F
F 2 MHz
4
1
T 0.5 μs
F
PR2 255
250 ms
Nr. ≅ 1961
0.5 µs ∗ PR2 ∗ Div
#include <xc.h>
#pragma config OSC = HS
#define _XTAL_FREQ 8000000
int i = 0, j = 0;
void ext1();
void ext2();
void init()
{
LATD = 0x0;
TRISD = 0x0;
OSCCON = 0x72;
T1CON = 0x10;
PIE1bits.TMR1IE =1;
PIR1bits.TMR1IF = 0;
IPR1bits.TMR1IP = 0;
TMR1H = 0;
TMR1L = 0;
T2CON = 0x0;
PIE1bits.TMR2IE = 1;
PIR1bits.TMR2IF = 0;
IPR1bits.TMR2IP = 1;
TMR2 = 0;
PR2 = 255;
[Link] = 1;
[Link] = 1;
[Link] = 1;
[Link] = 1;
T1CONbits.TMR1ON = 1;
T2CONbits.TMR2ON = 1;
}
void interrupt high_priority ex1()
{
if(PIR1bits.TMR2IF == 1) {ext2();}
}
void interrupt low_priority ex2()
{
if(PIR1bits.TMR1IF == 1) {ext1();}
}
void ext1()
{
i++;
if(i == 4)
{
LATDbits.LATD0= ~LATDbits.LATD0;
i = 0;
}
PIR1bits.TMR1IF = 0;
}
void ext2()
{
j++;
if(j == 1961)
{
LATDbits.LATD1 = ~LATDbits.LATD1;
j = 0;
}
PIR1bits.TMR2IF = 0;
}
void main(void)
{
init();
while (1);
}
Fig. 3 Schema de implementare în mediul Proteus.
Schema Proteus utilizată pentru simularea aplicației (vezi figura 3) va conține:
Microcontroler PIC18F8722 cu F 8 MHz,
Două LED-uri conectate la liniile RD0 și RD1,
Un osciloscop virtual.