Sunteți pe pagina 1din 10

Ministerul Educatiei al Republicii Moldova

Universitatea Tehnica a Moldovei


Facultatea Calaculatoare, Informatica si Microelectronica
Catedra Microelectronica si Ingineria Biomedicala

Raport
La disciplina: Microprocesoare
Lucrare de laborator Nr.6

Tema: Modulul periferic TIMER.


Afisor 7x8 segmente.Ceas digital

A efectuat: str.gr.MN-131,Ignat Ion

A verificat: lec. as., Eugeniu Lazari

2015
Scopul lucrarii:
1) Studiera modulului timer.
2) Aplicarea modulului timer in practica.
Definiia problemei:
S se realizeze o aplicaie pe MCU, unde va fi realizat un cias reprezentat pe 8 indicatoare pe 7 segmente.
Schimbarile indicatoarelor trebuie sa fie efectuate cu ajutorul modulului Timer0 setat la overflow, la o
frecventa 8 Hz. Codul trebuie sa fie mixat intre limbajele de programare C.

Date teoretice:

Modulul Timer-Timer-ul 0 este un timer de uz general pe 8 bii care are urmtoarea


schem bloc:
n cazul de fa NLC-ul este reprezentat de registrul TCNT0 la care avem acces de citire i scriere. Sursa
semnalului care incrementaz NLC-ul poate fi extern(T0) sau intern(semnalul de tact al
microcontrolerului) care poate fi prescalat.La fiecare tact clkT0 numrtorul TCNT0 este incrementat:

Figura1. Incrementarea registrului TCNT0

Registrul TCCR0 are rolul de a selecta i prescala susra semnalului de tact, el avnd forma:

Figura2. Registrul TCCR0

Din acest registru vom folosi numai ultimii 3 bii (CS02, CS01, CS00) pentru setare.Valorile pe
care le poate lua i seminificaiile lor sunt urmtoarele:
000 nu se selecteaz nici o surs de tact;
001 folosete ceasul intern fr prescalare;
010 folosete ceasul intern cu prescalarea 8 (clkT0/8);
011 folosete ceasul intern cu prescalarea 64 (clkT0/64);
100 folosete ceasul intern cu prescalarea 256 (clkT0/256);
101 folosete ceasul intern cu prescalarea 1024 (clkT0/1024);
110 folosete o surs extern de tact la pinul T0.Se ia n considerare frontul descresctor;
111 folosete o surs extern de tact la pinul T0.Se ia n considerare frontul cresctor;
Pentru a se putea genera o cerere de ntrerupere a timer-ului 0 trebuie ca cel mai semnificativ bit
al registrului SREG(bitul I) s fie 1 i cel mai nesemnificativ bit al registrului TIMSK, bitul TOIE0 s fie tot
1.

Figura3. Regitru TIMSK


Cererea de ntrerupere este semnalizat n registrul TIFR n cel mai nesemnificativ
bit,TOV0.Dac registrul TCNT0 a fost umplut,TOV0 devine 0 i atunci sistemul va genera o ntrerupere
executndu-se codul de la adresa 0x009.
n majoritatea aplicaiilor cu timere se folosete prescalarea sursei de tact.

Modul de lucru:

1) Formarea schema bloc de functionare a programului.

Figura4. Schema bloc functia main Figura5.Schema bloc pentru functia de intrerupere

Figura6. Schema bloc pentru functia Port_init Figura7.Schema bloc pentru functia TIMER0_init()
Determinare()
;

Fals counter >= Adevar


199

time[7] ++;

time[7] > 9
Fals Adevar

time[7] = 0;time[6] ++;

Fals Adevar
time[6] > 5

time[6] = 0;time[5] ++;

Fals time[5] > 9 Adevar

time[5] = 0;time[4] ++;

time[4] > 5
Fals Adevar
time[4] = 0;time[3] ++;

Fals Adevar
time[3] > 3

time[3] = 0;time[2] ++;

Fals time[2] > 1 Adevar

time[2] = 0;time[1] ++;

time[1] > 6
Fals Adevar
time[1] = 0;

retur
Figura8.Schema bloc pentru functia Determinare()
n
TablouInitiere(secunde,
minute, ore, zile)

Secunde >=10 Adevar

Fals i++;secunde = secunde - 10;

time[6] = i;i =0;

Secunde >=1
Fals Adevar
i++;secunde = secunde - 1;

time[7] = i;i =0;

Fals Adevar
minute >=10

i++;minute = minute - 10;

time[4] = i;i =0;

minute >= 1 Adevar

Fals i++; minute = minute - 1;

time[5] = i;i =0;


Fals Adevar
ore >= 10

i++; ore = ore 10;

time[2] = i;i =0;

Fals Adevar
ore >= 1

i++; ore = ore 1;

time[3] = i;i =0;

zile >= 1 Adevar

Fals i++; zile = zile - 1;

time[1] = i;i =0;

Figura9.Schema bloc pentru functia TablouInitiere()


retur
n
Afisare();

PORTD |= (1<<1);
Da PORTA = cifra[time[indicator]]; break;
7 PORTD &= ~(1<<2);
NU
(1<<1);
PORTD |= (1<<2);
6 Da PORTA==cifra1[time[indicator]];
PORTA cifra[time[indicator]]; break;
6 ~(1<<2);
PORTD &= ~(1<<3);
Nu
PORTD |= (1<<3);
(1<<1);
5 Da PORTA
PORTA==cifra[time[indicator]];
cifra[time[indicator]]; break;
5 PORTD &= ~(1<<4);
~(1<<2);
Nu
PORTD |= (1<<4);
Da PORTA = cifra[time[indicator]]; break;
4 PORTD &= ~(1<<5);
Nu
PORTD |= (1<<5);
Da PORTA = cifra[time[indicator]]; break;
3 PORTD &= ~(1<<6);
Nu
PORTD |= (1<<6);
Da PORTA = cifra[time[indicator]]; break;
2 PORTD &= ~(1<<7);
Nu
PORTD |= (1<<7);
Da PORTA = cifra[time[indicator]]; break;
1 PORTD &= ~(1<<0);
Nu
PORTD |= (1<<0);
Da PORTA = cifra[time[indicator]]; break;
0 PORTD &= ~(1<<1);

Fals Adevar
indicator <=
0

indicator = 8;

retur
Figura10.Schema
n bloc pentru functia Afisare ()
2) Proiectam schema electrica pentru simulare in PROTEUS

Figura11 Shema electrica simulata in proteus

3) Scriem codul programului

Codul Programului:

#include <avr/io.h>
#include <avr/interrupt.h>

#define F_CPU 1000000


#define DIV 8
#define F_T0 F_CPU/DIV
#define F_INT 800
#define TCNT0_init (256 - F_T0/F_INT)
unsigned char cifra1[10]= {253,97,219,243,103,183,191,225,255,247};
unsigned char cifra[10]= {252,96,218,242,102,182,190,224,254,246};
unsigned char time[8] = {0,0,0,0,0,0,0,0};
unsigned char counter = 0;
unsigned char indicator = 8;
void TablouInitiere(unsigned char secunde,unsigned char minute,unsigned char ore,unsigned
char zile)
{
unsigned char i = 0;
while (secunde >= 10)
{
i++;
secunde = secunde - 10;
}
time[6] = i;
i =0;
while (secunde >= 1)
{
i++;
secunde = secunde - 1;
}
time[7] = i;
i =0;
while (minute >= 10)
{
i++;
minute = minute - 10;
}
time[4] = i;
i =0;
while (minute >= 1)
{
i++;
minute = minute - 1;
}
time[5] = i;
i =0;
while (ore >= 10)
{
i++;
ore = ore - 10;
}
time[2] = i;
i =0;
while (ore >= 1)
{
i++;
ore = ore - 1;
}
time[3] = i;
i =0;
while (zile >= 1)
{
i++;
zile = zile - 1;
}
time[1] = i;
i =0;
}
void Afisare()
{
switch (indicator)
{
case 0:
PORTD |= (1<<1);
PORTA = cifra[time[indicator]];
PORTD &= ~(1<<2);
break;
case 1:
PORTD |= (1<<2);
PORTA = cifra1[time[indicator]];
PORTD &= ~(1<<3);
break;
case 2:
PORTD |= (1<<3);
PORTA = cifra[time[indicator]];
PORTD &= ~(1<<4);
break;
case 3:
PORTD |= (1<<4);
PORTA = cifra1[time[indicator]];
PORTD &= ~(1<<5);
break;
case 4:
PORTD |= (1<<5);
PORTA = cifra[time[indicator]];
PORTD &= ~(1<<6);
break;
case 5:
PORTD |= (1<<6);
PORTA = cifra1[time[indicator]];
PORTD &= ~(1<<7);
break;
case 6:
PORTD |= (1<<7);
PORTA = cifra[time[indicator]];
PORTD &= ~(1<<0);
break;
case 7:
PORTD |= (1<<0);
PORTA = cifra[time[indicator]];
PORTD &= ~(1<<1);
break;

}
if (indicator <= 0)
{
indicator = 8;
}
indicator--;
asm("nop");

}
void Determinare()
{
if (counter >= 199)
{
time[7] ++;
if (time[7] > 9)
{
time[7] = 0;
time[6]++;
if (time[6] > 5)
{
time[6]=0;
time[5]++;
if (time[5] > 9)
{
time[5] =0;
time[4]++;
if (time[4] > 5)
{
time[4] = 0;
time[3]++;
if (time[3] > 3)
{
time[3] = 0;
time[2]++;
if (time[2] > 1)
{
time[2] = 0;
time[1]++;
if (time[1] > 6)
{
time[1] = 0;
}
}
}
}
}
}
}
}
}
ISR(TIMER0_OVF_vect)
{
TCNT0 = TCNT0_init;
Determinare();
Afisare();
counter ++;
if (counter > 199)
{
counter = 0;
}
asm("nop");
}

void Port_init()
{
DDRA = 0xff;
PORTA = 0b00000000;
DDRB = 0b11111111;
PORTB = 0b11111100;
DDRC = 0b00000000;
PORTC = 0b11111111;
DDRD = 0Xff;
PORTD = 0b11111111;
}
void TIMER0_init()
{
TCNT0 = TCNT0_init;
TIMSK |= (1<<TOIE0);
TCCR0 |= (1 << CS01);

int main(void)
{
Port_init();
TIMER0_init();
unsigned char secunde = 22;
unsigned char minute = 49;
unsigned char ore = 15;
unsigned char zile = 05;
TablouInitiere(secunde, minute,ore,zile);
sei();
while(1)
{
asm("nop");
}
}

Concluzie: In acest laborator am studiat modulul periferic Timer,l-am setat la intreruperea


overflow.In concluzii putem spune ca modulul Timer este foarte comod de utiliza din cauza ca
Timerul se incrementeaza independent fara implicatiile procesorului, doar cheama functia de
intrerupere care citeste datele modulului.

S-ar putea să vă placă și