Sunteți pe pagina 1din 6

Universitatea Tehnic a Moldovei

Facultatea Informatic Calculatoare i Microelectronic


Catedra Microelectronica i Dispozitive Semiconductoare

RAPORT
Proiectarea microsistemelor
Lucrare de laborator 2
TEMA: Proiectarea unui sistem de detecie a tastelor i
afiare a cifrei apsate pe un indicator cu apte segmente.

A elaborat:

st.gr.ME-071

A verificat:

Lector superior
Prac Valeriu
Chisinau 2010

Scopul lucrrii: s se elaboreze un sistem care v-a detecta tasta apsat de la o tastatur
telefonic, codul tastei se v-a aduga ntr-un tablou de memorie, la un indicator pe 7
segmente s se afieze acest tablou. Sistemul v-a permite adugarea elementelor n
tablou, tergerea i curarea ecranului.
Descrierea general
Sistemul sprelaborare v-a fi alctuit dintr-un controller ATMEGA16, un afior pe
7 segmente cu 8 cifre i o tastatur telefonic. Controllerul are funcia de scanare a
tastaturii i detectarea tastei apsate, acest lucru s-a implementat cu ajutorul ntreruperii
externe INT0 de pe controller. O a doua funcie a controllerului este afiarea la indicator
a cifrelor apsate, tergerea unei cifre sau curarea ecranului.
Evident sistemul este alctuit din dou module principale: modulul de detectare a
tastei apsate i modulul de afiare a cifrelor la indicatorul cu apte segmente. Global
sunt declarate dou tablouri unidimensionale: char digits[11] i char display[8] . n tabloul digits
sunt stocate codurile pe 7 segmente a cifrelor de la 0 la 9 i caracter null (nu se afieaz
nimic). n tabelul al doilea display se stoceaz ce cifr trebuie afiat n fiecare digit al
indicatorului.
Modulul de detectare a tastei apsate
La apsarea oricrei din taste de pe tastatura telefonic, se creaz o ntrerupere i
anume INT0 care cheam funcia void int0_isr(void) , care cere funciei char getcmd() s detecteze
dac a fost apsat o cifr sau una din tastele de comand DELETE sau CLEAR.
Detectarea codului tastei apsate o ndeplinete funcia char getkey() care trimite pe rnd pe
fiecare linie a tastaturii zero logic (detectnd numrul liniei) i citete valorile aprute pe
fiecare coloan detectnd nr butonului apsat de pe linia curent. Cnd este gsit butonul
apsat aceast funcie returneaz codul butonului. Funcia getcmd() const dintr-un
switch care detecteaz dac a fost apsat o cifr sau o comand, returnnd rezultatul
funciei chemate de ntrerupere. Mai departe funcia int0_isr n dependen de comanda
primit cheam funciile respective: delete() terge ultimul caracter introdus, clear()
terge ntreg ecranul, putch(char ch) care transport toate cifrele introduse mai anterior
n tabel cu o poziie nainte, iar n poziia zero introduce cifra apsat la moment.
Modulul de afiare la indicator cu 7 segmente
Acest modul este bazat pe un timer configurat la o frecven de generare a
ntreruperilor de 1kHz, deajuns pentru ca cifrele chiar dac sunt afiate pe rnd s apar
un efect de prezen permanent a lor pe indicator. Timerul folosit este timer0 prezent pe
controller care la generarea ntreruperii de overflow cheam funcia void timer0_ovf_isr(void) care
cu ajutorul variabilei globale show_index de fiecare dat afieaz la ecran codul cifrei
curente din tabelul display.

Schema principial:

Codul surs:
//ICC-AVR application builder : 3/29/2010 11:48:48 PM
// Target : M16
// Crystal: 4.0000Mhz
#include <iom16v.h>
#include <macros.h>
#define DELETE 11 // comanda de shtergere a unei cifre
#define CLEAR 12 // comanda de curare a ecranului
#define NOCHAR 10
// tabelul cu codurile cifrelor in siste de 7 segmente
char digits[11] = {0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0x00};
// tabelul cu cifrele ce trebuie afiate
char display[8] = {NOCHAR,NOCHAR,NOCHAR,NOCHAR,NOCHAR,NOCHAR,NOCHAR,NOCHAR};
// cifra curent ce trebuie afiat
char show_index = 0;
// cifra curent introdus
char index = 0;
// initializarea porturilor
void port_init(void)
{
PORTA = 0x00;
DDRA = 0xFF;
PORTB = 0x00;
DDRB = 0xFF;
PORTC = 0x70; //m103 output only
DDRC = 0x8f;
PORTD = 0xff;
DDRD = 0x00;
}
//TIMER0 initialize - prescale:64
// WGM: Normal
// desired value: 1KHz
// actual value: 1.008KHz (0.8%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0xC2; //set count
OCR0 = 0x3E; //set compare
TCCR0 = 0x03; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:10
{
TCNT0 = 0xC2; //reload counter value
PORTB = 0x00; // stingerea tuturor segmentelor
PORTA = ~(1<<(7-show_index)); // conectarea cifrei curente
PORTB = digits[display[show_index]]; // afiarea cifrei curente
if(++show_index>7)show_index=0;
}

// returneaz codul cifrei apsate


char getkey()
{
char code = NOCHAR;
PORTC = 0xFE; // prima linie
if(~(PINC|0x8F)>0)code = (~(PINC|0x8F))+0x0E;
PORTC = 0xFD; // linia 2
if(~(PINC|0x8F)>0)code = (~(PINC|0x8F))+0x0D;
PORTC = 0xFB; // linia 3
if(~(PINC|0x8F)>0)code = (~(PINC|0x8F))+0x0B;
PORTC = 0xF7; // linia 4
if(~(PINC|0x8F)>0)code = (~(PINC|0x8F))+0x07;
PORTC = 0xf0; // restabilirea strii liniilor
return code;
}

// detectat buton de pe prima linie


// detectat buton de pe linia 2
// detectat buton de pe linia 3
// detectat buton de pe linia 4

char getcmd()
{
char key = getkey();
switch(key)
{
case 0x4E: return 1;
case 0x2E: return 2;
case 0x1E: return 3;
case 0x4D: return 4;
case 0x2D: return 5;
case 0x1D: return 6;
case 0x4B: return 7;
case 0x2B: return 8;
case 0x1B: return 9;
case 0x47: return CLEAR; // comanda clear
case 0x27: return 0;
case 0x17: return DELETE; // comanda delete
default: return key;
}
}
// terge ultima cifr introdus
void delete()
{
char i;
if(index==0)return;
for(i=0; i<index; i++)
{
display[i] = ((i+1)<8)?display[i+1]:NOCHAR;
}
index--;
}
// cur ntreg ecranul
void clear()
{
char i;
for(i=0; i<8; i++)
{
display[i] = NOCHAR;
}
index = 0;
}

// adaug n display cifra apsat


void putch(char ch)
{
char i;
if(index>7)return;
for(i = index; i>0; i--)
{
display[i]=display[i-1];
}
display[0] = ch;
index++;
}
// generat la apsarea oricrui buton
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
char cmd;
CLI();
//external interupt on INT0
cmd = getcmd(); // detectarea comenzii
if(cmd==DELETE)delete(); // comanda delete
else if(cmd==CLEAR)clear(); // comanda clear
else putch(cmd); // adaugarea cifrei
GIFR |= (1<<INTF0); // curarea flagului INTF0
SEI();
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
MCUCR = 0x02;
GICR = 0x40;
TIMSK = 0x01; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
//
void main(void)
{
init_devices();
//insert your functional code here...
while(1) {} // ciclu infinit
}

Concluzie:
n lucrarea dat de laborator am elaborat un sistem de interaciune cu controllerul
prin intermediul unei taste telefonice. Ce ne permite s implementm sisteme mai
interactive.

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