Rotina eficiente para display de 7 segmentos ( mapeado em pinos do uC )

Autor: andre_luis • Categoria: Microchip PIC • Postado em 04 Ago 2016 10:00 • Visualizado: 1901x

De um modo geral, sempre tentamos mapear os pinos de um display de 7 segmentos em uma porta do microcontrolador bit-a-bit na mesma sequencia do LSB ao MSB, de modo a espelhar o conteúdo do registrador/variável do programa sem necessidade de processamento adicional da CPU. Porém, há casos de projetos onde os pinos disponiveis estão dispersos em diferentes portas, e isso complica a programação.

Por exemplo, no caso do programa abaixo, onde os pinos foram mapeados da seguinte forma:

Code: Selecionar todos
#define DISP7_A       PIN_A7
#define DISP7_B       PIN_A6
#define DISP7_C       PIN_A5
#define DISP7_D       PIN_A4
#define DISP7_E       PIN_B3
#define DISP7_F       PIN_B4
#define DISP7_G       PIN_C6

O primeiro impulso foi implementar algo do tipo:

cpp code
void Display7seg ( char number )
{
switch(number)
{
case 0 : // escreve caracter "0" do display de 7 segmentos
output_HIGH(DISP7_A);
output_HIGH(DISP7_B);
output_HIGH(DISP7_C);
output_HIGH(DISP7_D);
output_HIGH(DISP7_E);
output_HIGH(DISP7_F);
output_LOW (DISP7_G);
break ;
case 1 :
output_LOW (DISP7_A);
output_HIGH(DISP7_B);
output_HIGH(DISP7_C);
output_LOW (DISP7_D);
output_LOW (DISP7_E);
output_LOW (DISP7_F);
output_LOW (DISP7_G);
break ;
case 2 :
output_HIGH (DISP7_A);
output_HIGH (DISP7_B);
output_LOW (DISP7_C);
output_HIGH (DISP7_D);
output_HIGH (DISP7_E);
output_LOW (DISP7_F);
output_HIGH (DISP7_G);
break ;
case 3 :
output_HIGH (DISP7_A);
output_HIGH (DISP7_B);
output_HIGH (DISP7_C);
output_HIGH (DISP7_D);
output_LOW (DISP7_E);
output_LOW (DISP7_F);
output_HIGH (DISP7_G);
break ;
case 4 :
output_LOW (DISP7_A);
output_HIGH (DISP7_B);
output_HIGH (DISP7_C);
output_LOW (DISP7_D);
output_LOW (DISP7_E);
output_HIGH (DISP7_F);
output_HIGH (DISP7_G);
break ;
case 5 :
output_HIGH (DISP7_A);
output_LOW (DISP7_B);
output_HIGH (DISP7_C);
output_HIGH (DISP7_D);
output_LOW (DISP7_E);
output_HIGH (DISP7_F);
output_HIGH (DISP7_G);
break ;
case 6 :
output_LOW (DISP7_A);
output_LOW (DISP7_B);
output_HIGH (DISP7_C);
output_HIGH (DISP7_D);
output_HIGH (DISP7_E);
output_HIGH (DISP7_F);
output_HIGH (DISP7_G);
break ;
case 7 :
output_HIGH (DISP7_A);
output_HIGH (DISP7_B);
output_HIGH (DISP7_C);
output_LOW (DISP7_D);
output_LOW (DISP7_E);
output_LOW (DISP7_F);
output_LOW (DISP7_G);
break ;
case 8 :
output_HIGH (DISP7_A);
output_HIGH (DISP7_B);
output_HIGH (DISP7_C);
output_HIGH (DISP7_D);
output_HIGH (DISP7_E);
output_HIGH (DISP7_F);
output_HIGH (DISP7_G);
break ;
case 9 :
output_HIGH (DISP7_A);
output_HIGH (DISP7_B);
output_HIGH (DISP7_C);
output_HIGH (DISP7_D);
output_LOW (DISP7_E);
output_HIGH (DISP7_F);
output_HIGH (DISP7_G);
break ;
}
}


Porém isso consumiu bastante memória "ROM", e resolvi fazer diferente.
Criei um array para os numeros, e um mapa com os segmentos:

cpp code
const int DISPLAY_PINS [] = { 
DISP7_A,
DISP7_B,
DISP7_C,
DISP7_D,
DISP7_E,
DISP7_F,
DISP7_G } ;

cpp code
const char SEGMENTCHARS [] = { 
0b00000000,
0b01100000,
0b11011010,
0b11110010,
0b01100110,
0b10110110,
0b00111110,
0b11100000,
0b11111110,
0b11110110 } ;


Depois implementei uma função que escaneava cada bit dentro de cada numero:

cpp code
#define FIRST_SEGMENT    0b10000000  // apenas para parametrizar

void Display7seg ( char value )
{
char pin=0 ;
while ( pin< 8 )
{
if ( SEGMENTCHARS[value ] & ( FIRST_SEGMENT >> pin) )
output_high ( DISPLAY_PINS[pin] ) ;
else
output_low ( DISPLAY_PINS[pin] ) ;
pin++ ;
}
}


Sendo que a chamada á essa função dentro do programa é feita assim:

cpp code
Display7seg (number);  // argumento é numero inteiro de 0 a 9


Testado e aprovado, reduziu bastante o consumo de memória...

Adicionar comentário

Registrar or Efetue login para comentar

cron

x