Display 8x7 segmente

Să se proiecteze un sistem care ar perimite afişarea unui set de caractere definit din memoria RAM pe un display format din 8 afişoare a câte 7 segmente.

Afişorul 8x7seg 
Controlul segmentelor este comun pentru toate cele 8 cifre disponibile pe placă. Asta înseamnă că toate segmentele de pe aceeaşi poziţie din toate cele 8 cifre sunt legate la acelaşi pin (altfel spus, toate cifrele active la un anumit moment de timp vor afişa aceeaşi valoare). Activarea sau dezactivarea unei cifre se face tot pe logică negată, folosind pinii legați la dispozitivele CC8 - CC0. Prin urmare, modulul care controlează afişajul pe 7 segmente va avea, pe lângă ieşirea de 8 biți necesară controlului segmentelor, încă o ieşire de 8 biți care va controla starea fiecărei cifre (activată sau dezactivată).
Afişorul va fi activat la aplicarea 0 logic la catodul comun (CC).



Vom utiliza proprietatea ochiului de a memoriza temporar imaginea. Ochiul nu este sensibil la toate mişcările rapide. El menţine imaginea în memorie cîteva milisecunde.
Frecvenţa de comfort de reînoire a afişorului.
Luînd în consideraţie experimentul din televiziune vom spune ca frecvenţa minimală de comfort este 50-100Hz.
Aplicînd o frecvenţă din acest diapazon vom avea imaginea ca toate afişoarele luminează concomitent.
Perioada de înoire a unui cadru va trebui să aprindem consecutiv toate afişoarele. O afişare completă a display-lui o vom numi cadru.

Frecvenţa de afişare: 
Schema de mai sus permite printr-o comandă sucesivă, repetitivă a catozilor de a afişa pe cele 8 cifre lucruri diferite. Pentru ca fiecare afişor să apară utilizatorului ca fiind corespunzător (ca luminozitate) şi continuu iluminat fiecare din cele 8 cifre (digits) trebuie să fie activă (aprinsă) la un interval de timp (refresh preiod) cuprins între 1 ms şi 16 ms. Cu alte cuvinte trebuie să fie între 1 kHz şi 60 Hz.
De exemplu dacă viteza de împrospătare este de 60 Hz fiecare cifră va fi aprinsă (într-un ciclu de 16 ms, pentru 8 afişoare) pentru un interval de 2 ms (digit period).
Utilizatorul trebuie să asigure periodizarea şi secvenţierea corectă a comenzilor pentru catozi şi segmente.
Mai jos este prezentat un exemplu pentru afisor de 7 segmente 4 digit:


Pentru 1 afisor: T=8/50-8/100Hz.
fc-frecvenţa de cadru
fs-frecvenţa de selecţie
Frecvenţa de selecţie pentru problema dată o vom realiza cu ajutorul întreruperii de supraîncarcare a contorului setînd frecvenţa întreruperii cu frecvenţa de selecţie.
În cadrul unei subrutine de prelucrare a acestei întreruperi va trebui:
1 să aplicăm date pe anoduri
2 selectarea afişorului destinat caracterului.

;calcularea fină a valorii pentru TIMER
;=======================================
.equ XTAL = 2000000
.equ FRECVDORITA = 670
.equ PRESCALER = 64
.equ XVAL = XTAL/(PRESCALER*FRECVDORITA)
.equ TIMERVAL = 255 - XVAL
;=======================================

Schemele bloc:
1) Schema bloc generală

2) Schema bloc pentru InitTab(X)
3) Schema bloc pentru subrutina de prelucrarea a întreruperii overflow de la TIMER0
4) Schema bloc pentru driverul de afişare

//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;
}

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]);
}