Sarcina:
I) sa se proiecteze un sistem
bazat pe microcontroler care ar permite afişarea conţinutului unui tablou
unidimensional de caractere ASCII la un set de afişoare cu 7 segmente;
II) sa se proiecteze un ceas utilizand modulul periferic TIMER1, valoarea
curenta a carui va fi reinnoita in tabloul pentru afişare in forma de caractere
ASCII.
Microcontrollerele familiei AVR au de la 2
la 4 contoare de timp de uz general, în dependenţă de model
Timer/contor-ul T1 de asemenea poate fi utilizat pentru numărarea
intervalelor de timp şi ca contor al evenimentelor externe. În afară de aceea,
el poate memora starea sa în dependenţă de semnale externe. Ca şi timer/contor-ul
T0, el poate lucra în regim PWM, dar deja cu o rezoluţie variabilă şi cu mai
multe canale (numărul de canale depinde de model).
Timer/contor-ul T2 e absolut analogic timer/contor-ului T0. Dacă în
microcontroller sunt prezenţi ambii timer/contori, unul poate lucra în regim
asincron, altul – în calitate de contor a evenimentelor externe.
Timer/contor-ul T3 după posibilităţile funcţionale e identic timer/contor-ului
T1.
Întreruperea TIMER
Modulul de întrerupere timer este un modul periferic inclus în
majoritatea controllerelor seriei AVR, care la rândul său poate conţine de la 1
până la 3 module TIMER.
Modulul TIMER de regulă se foloseşte pentru măsurarea timpului. În cazul
când avem nevoie de măsurat frecvenţa, generarea unui semnal de o anumită
frecvenţă şi alte efecte ce presupun folosirea timpului, se recomandă aplicarea
modului TIMER. Componen ţa principală al acestui modul este registrul
numărător TCNT.
Modulele Timer/Conters
Modulul de timer este cel mai fregvent modul utilizat. Un microntroller
poate conţine de la 1 – 3 timere. Un modul timer are la bază un numărător care
incrementează un registru, acest registru numărător poate fi de 8 sau 16 biţi.
Modulul timer 0 se poate utiliza pentru formarea intervalelor între generarea
întreruperii de timp.
Situaţia de întrerupere va fi provocată la supraîncărcarea registrului
contor. Odată întreruperea generată poate chema o funcţie de prelucrare a ei.
ATmega16 dispune de două numărătoare/timere de uz general, unul de 8
biţi şi unul de 16 biţi. Fiecăruia i se poate selecta o valoare individuală
pentru prescaler din acelaşi prescaler de 10 biţi. Ambele module pot fi
folosite ca timere cu un clock generat intern sau ca numărătoare cu un clock
extern de la un pin I/O. Cele 4 valori pentru prescaler sunt CK/8, CK/64,
CK/256 şi CK/1024 unde CK este clock-ul dat de oscilatorul extern. Ambele
timere pot genera întreruperi ale căror biţi de validare se află în registrul
Timer/Counter Interrupt Mask Register (TIMSK) şi ale căror flaguri de
întrerupere se află in registrul Timer/Counter Interrupt Flag Register (TIFR).
Timer/Counter0 este un numărător pe 8 biţi. Registrul de
control al acestuia este Timer/Counter0 Control Register (TCCR0) din care se
setează valoarea prescalerului, ceasul intern sau extern şi starea pornit/oprit
a modulului. La trecerea din 0xFF în 0x00 flagul overflow este setat şi este
generată întreruperea TMR0_OVR dacă aceasta este validată. Ceasul extern este
sincronizat cu oscilatorul microcontrollerului. Pentru a asigura o numărare
corectă a impulsurilor externe, durata dintre două tranziţii ale clock-ului
extern trebuie să fie mai mare ca perioada oscilatorului microcontrolerului.
Timer/Counter1 este un numărător pe 16 biţi. Registrele de
control ale acestuia sunt Timer/Counter1 Control Registers (TCCR1A and TCCR1B).
Diferite flaguri de stare (overflow, captura unui eveniment, etc) se află în
registrul Timer/Counter Interrupt Flag Register (TIFR). De asemenea ceasul
extern trebuie să îndeplinească condiţia ca perioada dintre două tranziţii să
fie mai mare decât perioada oscilatorului microcontrollerului pentru a asigura
o funcţionare corectă a modulului.
Modulul Timer/Counter1 suportă funcţia de
comparare folosind registrele Output Compare Register 1 A şi B (OCR1A şi OCR1B)
pe care le compară cu registrul TCNT1. Funcţiile de comparare includ resetarea
numărătorului la egalitatea cu registrul OCR1A sau alte acţiuni pe pinii de
ieşire la egalitatea cu ambele registre A şi B. Modulul poate fi utilizat şi ca
modulator de impulsuri în durată pe 8, 9 sau 10 biţi. De asemnea funcţia Input
Capture poate salva conţinutul TCNT1 în registrul Input Capture Register (ICR1)
la apariţia unui eveniment extern pe pinul de captură ICP. Setările
evenimentului de captură sunt definite de registrul Timer/Counter1 Control
Registers B (TCCR1B). În plus modulul Analog Comparator poate genera
evenimentul de captură.
Pentru configurarea modulului Timer/Counter 0 se utilizează registrul
TCCR0, iar pentru a configura frecvenţa apariţiilor situaţiilor de întrerupere
se va seta prescalerul ce se află în TCCR0.
CS02, CS01, CS00 - cu ajutorul lor vom seta viteza de progresie a
timerului.
Tabelul de adevăr:
Situaţia de întrerupere va fi generată la supraîncărcarea registrului
TCNT0.
Fig.1 Prezentarea
grafică a funcţionării Timerului.
Pentru a configura fregvenţa apariţiei situaţiei de intrerupere se va
seta prescalerul care se configura în TCCR0.
Pentru a seta mai fin întreruperea trebuie de reiniţializat registrul
TCNT la fiecare întrerupere.
Pentru a
organiza un sistem care va utiliza întreruperea de Timer trebuie să:
- validăm utilizarea modulului întreruperii din
registrul TIMSK;
- înregistrăm în vectorul de întreruperi chemarea
funcţiei de prelucrare a întreruperii;
- descriem subrutina de prelucrare a întreruperii;
Fiecare
modul periferic are regiştri in spaţiu de 64 I/O. Comunicaţia modulelor
periferice are loc prin intermediul acestor regiştri. Există
3 tipuri de regiştri periferice:
- TCNT0 - de date (transfer de date dintre nucleu
şi periferie)
- TCCR0 - de configurare (se utilizează pentru
configurarea modulului periferic)
- TIFR, TIMSK - de fanioane(reprezintă starea
curenta a modulului periferic)
Regiştri de multe ori sunt combinaţi cei de configurare şi fanioane.
Registrul TCNT (timer counter) conţine 8 biţi. Trecerea valorii registrului de
numărare de la valoarea maximală în zero, se numeşte supraîncărcare/depăşire
(overflow). Evenimentul de supraîncărcare este legat cu modulul de întrerupere
a timer-ului. Când are loc depăşirea , se setează un bit TIFR.TOUF0 în 1.
Frecvenţa apariţiei întreruperii Timer overflow poate fi reglată prin:
- Reglarea prin setarea divizorului de la semnalul
de clock pentru sursa de încrementare.
- Setarea
valorii iniţiale.
Regimurile
de lucru ale Modulul TIMER
Modulul
TIMER poate lucra în mai multe regimuri:
1)
Numărător – destinat
lucrului cu timpul.
2) Imput Capture – capturarea intrării care presupune
determinarea apariţiei unui eveniment extern. Principala sarcină a unităţii de
capturare la intrare este de a pune la dispoziţie suficientă memorie din cea a
procesorului pentru apariţia de evenimente eventuale. Timpul dintre două
evenimente este critic. Dacă procesorul nu a citit valoarea asociată capturii
în Registrul ICR1, înainte de apariţia unui nou eveniment ICR1 va fi suprascris
cu o nouă valoare. În acest caz valoarea asociată capturii va fi incorectă.
Utilizând input capture interrupt, registrul ICR1 poate fi citit înaintea
producerii rutinei întreruperilor. Chiar dacă input capture interrupt are
prioritate ridicată, timpul maxim de răspuns la întrerupere depinde de numărul
maxim de cicluri necesare tratării unei cereri de întrerupere. Durata unui
ciclu pentru un semnal extern impune ca declanşatorul de nivel să fie schimbat
după fiecare captură.
3) Output Capture – modul în care se poate genera un semnal extern
la coincidenţa registrului timer cu o valoare prestabilită. Comparatorul pe 16
biţi compară TCNT1 cu ieşirea registrului Output Compare Register (OCR1x). Dacă
TCNT este egal cu OCR1x comparatorul semnalizează o potrivire. Aceasta setează
Output Compare Flag (OCF1x) pentru următorul ciclu de ceas. Dacă OCIE1x =1,
Output Compare flag generează o ieşire output compare interrupt. OCF1x flag
este dezactivat automat atunci când se execută o întrerupere. OCF1x flag poate
fi de asemenea dezactivat prin trecerea în ‘1’ logic a bitului I/O. Ţinând cont
că scrierea lui TCNT1 în orice mod de operare va bloca orice comparare pentru
un singur ciclu de ceas, există riscuri la schimbarea unuia din canalele output
compare ale lui TCNT1 indiferent dacă Timer/Counter este pornit sau oprit. Dacă
TCNT1 este egal cu OCR1x rezultatul comparării va fi pierdut, generându-se o
formă de undă greşită.
4) Puls Width Modulation (PWM) – modulaţia impulsurilor de durată. Permite
modularea unui semnal cu bandă reglabilă, modulată.
Watch Dog Timer
Microcontrollerul seriei AVR are inclus în componenţa sa modulul Watch
Dog, ce permite resetarea sistemului în caz de un comportament de ciclare al
său.
Mersul lucrării:
I ) sa se proiecteze un sistem bazat pe microcontroler care ar permite
afişarea conţinutului unui tablou unidimensional de caractere ASCII la un set
de afişoare cu 7 segmente;
Schema Bloc:
Codul sursă:
#include
<avr\io.h>
#include
<avr\interrupt.h>
#include
<avr\delay.h>
char data[]="04122013";
int i=0;
void test(void){
int k=0;
while (k<2){
for (int i=0; i<6;i++){
PORTC=0b00000000;
PORTA=(1<<i);
_delay_ms(100);
}
k++;}
PORTA=0xFF;
_delay_ms(200);
PORTA=0x00; }
//Functia DECOD
char decod(char c){
switch (c){
case '0': {c=0b00111111; break;
}
case '1': {c=0b00000110; break; }
case '2': {c=0b01011011; break; }
case '3': {c=0b01001111; break; }
case '4': {c=0b01100110; break; }
case '5': {c=0b01101101; break; }
case '6': {c=0b01111101; break;
}
case '7': {c=0b00000111; break;
}
case '8': {c=0b01111111; break; }
case '9': {c=0b01101111; break;
}
default: c=0x00;
}
return c;
}
//
Functia MAIN
void main(void){
// Waveform Generation Mode setarea
regimului Normal
TCCR0=(0<<CS00)|(1<<CS01)|(0<<CS02)|(0<<WGM01)|(0<<WGM00); // CK/8
TIMSK = (1<<TOIE0); // permiterea
intrerupeti in situatia de owerflov a TCNT0
DDRA=0xFF;
DDRC=0xFF;
PORTA=0x00;
PORTC=0x00;
test();
sei(); //
permitera intreruperi
while(1){ }
}
ISR(TIMER0_OVF_vect){
if ((i<7) & (i>=0))
i++;
else i=0;
PORTC=~(1<<i);
if (i==1)
PORTA=decod(data[i])|(1<<7);
else if (i==3)
PORTA=decod(data[i])|(1<<7);
else PORTA=decod(data[i]);
}
II ) sa se proiecteze un ceas utilizand
modulul periferic TIMER1, valoarea curenta a carui va fi reinnoita in tabloul
pentru afişare in forma de caractere ASCII.
Schema bloc:
Codul sursă:
#include
<avr/delay.h>
#include
<avr/io.h>
#include
<avr/interrupt.h>
#define
DEL _delay_ms(1)
char tab[7];
char decod( char digit){
char retval;
switch (digit){
case 0:
{retval=0b00111111; break;
}
case 1:
{retval=0b00000110; break;
}
case 2:
{retval=0b01011011; break;
}
case 3:
{retval=0b01001111; break;
}
case 4:
{retval=0b01100110; break;
}
case 5:
{retval=0b01101101; break;
}
case 6:
{retval=0b01111101; break;
}
case 7:
{retval=0b00000111; break;
}
case 8:
{retval=0b01111111; break;
}
case 9:
{retval=0b01101111; break;
}
default :retval=0b00000000;
}
return retval;
}
//**********************************************************
void afis(void){
for (int i=0; i<6; i++){
PORTC=~(1<<i);
if (i==2) PORTA=decod(tab[i])|(1<<7);
else if (i==4)
PORTA=decod(tab[i])|(1<<7);
else PORTA=decod(tab[i]);
DEL;
}
}
//***********************************************************
void main(void){
DDRA=0xFF;
PORTA=0x00;
DDRC=0x3F;
PORTC=0xFF;
TCCR1B = (1<<CS12)|(1<<CS10)|(1<<WGM12); //
/1024 regim CTC
OCR1A = 976;
TIMSK = 1<<OCIE1A; //permitera intrerupeti ‚egalitate’
sei();
while (1){
afis(); } }
//********************************************************
ISR(TIMER1_COMPA_vect)
{
//secunde
tab[0]++;
if (tab[0]>9) { tab[0]=0;
tab[1]++;}
//
minute
if (tab[1]>5) {tab[2]++;
tab[1]=0;}
if (tab[2]>9) {tab[3]++;
tab[2]=0; }
if (tab[3]>5) {tab[4]++;
tab[3]=0;} // ore
if (tab[4]>4) {tab[5]++;
tab[4]=0;}
if (tab[5]>2) {tab[5]=0;}
}