C1 - Display de 7 segmentos

MicrocontroladorPICPIC16F887MPLABX-XC8SimulIDE

Display de 7 segmentos

O display de 7 segmentos é uma das formas mais comuns de exibir um número, que pode representar o “peso” (massa) em uma balança, horas, minutos e segundos em um relógio ou cronômetro ou um simples contador de objetos em um processo qualquer.

Objetivo

Acionar um display de 7 segmentos para exibir os 16 dígitos hexadecimais:

0,1,2,3,4,5,6,7,8,9,A,B,C,D,E e F;

1. Circuito (Hardware)

O display de 7 segmentos basicamente é um conjunto de LEDs dispostos de forma a cada um deles iluminar um segmento no encapsulamento. Existem vários modelos para diferentes necessidades, mas aqui usamos o mais comum.

O display, além dos sete segmentos possui ainda um ponto, que pode ser utilizado para sinalizar um ponto decimal (vírgula) ao associar vários displays para mostrar um número fracionário ou qualquer separação entre dois dígitos. Nesse projeto o ponto não será utilzado.

Para o acionamento do display foi utilizado o PORTD conforme mostrado na Figura 1.1.

Figura 1.1: Display de 7 segmentos catodo comum
circuito

Existem dois modelos de display, Anodo comum e Catodo comum, que se referem aos terminais conectados em comum, conforme exemplo da Figura 1.2.

Figura 1.2: Segmentos do display
circuito

Cada segmento recebe uma identificação em letra minúscula de a a g e o p. O display possui um terminal para cada segmento do display.

Cada pino do PORTD está conectado a um segmento do display.

Note que cada segmento, composto por um LED, necessita de um resistor para limitar a corrente que percorre ele. Como cada pino do uC fornece uma tensão de 5V para acionar o segmento. A queda de tensão no LED é de \(2V\), aproximadamente. Pode-se assim calcular o valor do resistor limitador de corrente:

\[R = \frac{ V_{pino}-V_{LED}}{I_{LED}} = \frac{5-2}{0,020} = 150\Omega\]

O circuito apresenta um conjunto de resistores em um mesmo encapsulamento, mas poderia ser um resistor individual para cada segmento.

O display aqui utilizado é do tipo catodo comum, assim basta acionar os pinos do PORTD que correspondam aos segmentos a serem acionados para formar o dígito que se deseja exibir.

Para mostrar o dígito 0(zero), aciona-se os segmento a, b, c, d, e, fconforme mostrado na Figura 1.3.

Figura 1.3: Dígito 0 (zero)
circuito

É importante notar a sequência de pinos do display e do PORT utilizado, pois uma alteração de ordem muda o que é exibido no display.

Para o dígito 1(um) é necessário ligar apenas os segmentos b e c, mantendo os demais desligados.

Figura 1.4: Dígito 1 (um)
circuito

Para o dígito 2(dois) é mais fácil perceber os dígitos desligados, pois estão em menor quantidade, sendo o c e o f desligados e os demais ligados (exceto o ponto como já foi citado).

Figura 1.5: Dígito 2 (um)
circuito

A Figura 1.6 mostra uma tabela com todas as combinações para os dígitos decimais e seus valores correspondentes em hexadecimal. Ao atribuir ao PORTD um dos valores em hexadecimal da tabela, o digito correspondente deve ser mostrado no display.

Figura 1.6: Dígitos e equivalência em hexadecimal
circuito

Estão faltando os dados dos dígitos que completam o conjunto hexadecimal, que podem te servir como exercícios. Bom trabalho!

2. Programa (Firmware)

O programa pode ser escrito todo em um único arquivo, main.c, mas esta é uma forma não conveniente pois dificulta a manuteção e a organização do código. Assim, cada arquivo .c deve possuir somente funções correlatas ao nome desse arquivo. Por exemplo: todas as funções de manipulação do display de 7 segmentos estão contidas em disp7seg.c.

Para poder executar as funções do display no programa principal é necessário incluir o cabeçalho delas que está contido em#include "disp7seg.h".

Figura 2: Árvore de diretório do projeto
circuito

Programa principal

/*
 * File:   main.c
 * Author: josewrpereira
 *
 * Created on 5 de Agosto de 2020, 20:21:59
 * 
 * -------------------------------------------------
 *          MAPA DE ENTRADAS E SAIDAS
 * -------------------------------------------------
 *  Pinos   |nº     |Conexão
 * ---------|-------|-------------------------------
 *  RD0     |19     | Segmento a
 *  RD1     |20     | Segmento b
 *  RD2     |21     | Segmento c
 *  RD3     |22     | Segmento d
 *  RD4     |27     | Segmento e
 *  RD5     |28     | Segmento f
 *  RD6     |29     | Segmento g
 *  RD7     |30     | Segmento p
 * -------------------------------------------------
 */

#include <xc.h>
#include "config.h"
#include "delay.h"
#include "disp7seg.h"

void main(void) 
{
    char cont = 0;
    
    disp7seg_init();
    
    while( 1 )
    {
        disp7seg( cont );
        delay(500);
        cont = ++cont % 16;
    }
    return;
}

O laço de repetição que compõe a execução do programa possui apenas três instruçẽos:

  • Exibição da variável de contagem;
  • Atraso de 500ms, para que o valor da contagem permaneça em exibição por esse tempo;
  • Incremento seguido de uma delimitação da contagem utilizando a operação mod ou %, que é o operador que tem como resultado o resto da divisão. cont assume apenas valores entre 0 e 15.

Sub-rotinas

Trechos de programa, que podem ser executados com parâmetros diferentes, porém que executam a mesma ação levando em conta os argumentos da função.

Display 7 segmentos

#include <xc.h>
#include "config.h"
#include "delay.h"

char digitos7seg[16] = {    0x3F, 0x06, 0x5B, 0x4F, 
                            0x66, 0x6D, 0x7D, 0x07, 
                            0x7F, 0x6F, 0x77, 0x7C, 
                            0x39, 0x5E, 0x79, 0x71  };

void disp7seg_init( void )
{
    TRISD = 0x00;

    PORTD = 0xFF;    delay(500);
    PORTD = 0x00;    delay(500);
    PORTD = 0xFF;    delay(500);
    PORTD = 0x00;    delay(500);
}

void disp7seg( unsigned char num )
{
    PORTD = (num < 16) ? digitos7seg[num] : 0;
}

O vetor digitos7seg[16] contém todos os valores que correspondem aos caracteres de representação hexadecimal, associados diretamente com a posição de cada valor, sendo o valor que corresponde ao dígito 0 na posição 0 do vetor, o dígito 1 na posição 1, e assim por diante, com todos os demais valores.

O procedimento disp7seg_init além de inicializar o PORTD, também faz um teste de diagnóstico do display, fazendo o acionamento e desligando todos os segmentos de forma alternada, possibilitando a verificação da integridade de todas as vias, segmentos e conexões envolvidas.

A função disp7seg possui um argumento, que é o número correspondente ao dígito a ser exibido pelo display. Somente são exibidos dígitos hexadecimais entre os valores 0 e F. Valores fora deste intervalo o display fica apagado.


Alterando o Display de PORT

Figura 3: Display 7 segmntos no PORT B
circuito
/*
 * File:   main.c
 * Author: josewrpereira
 *
 * Created on 24 April 2021, 20:45
 * 
 * IDE:                 MPLAB X IDE v5.45
 * Compiler:            XC8 v2.31
 * Operating System:    Debian GNU/Linux bullseye/sid
 * Kernel:              Linux 5.10.0-5-amd64
 * Architecture:        x86-64
 * 
 * Objetivo: 
 *      Exibir um contador de 0..F através de um display de 7 segmentos.
 * 
 * nº Pinos| PORT |Conexão
 *  11,32  | VDD  | Alimentação (Vcc/+5V)
 *  12,31  | VSS  | Alimentação (GND/0V)
 * 
 *  40     | RB7  | Segmento a (Catodo Comum)
 *  39     | RB6  | Segmento b
 *  38     | RB6  | Segmento c
 *  37     | RB6  | Segmento d
 *  36     | RB6  | Segmento e
 *  35     | RB6  | Segmento f
 *  34     | RB6  | Segmento g
 *  33     | RB6  | Ponto 
 * 
 */

#include "config.h"
#include <xc.h>
#include "delay.h"
#include "display7segmentos.h"

void main(void)
{
    char cont = 0;
    disp7seg_init();

    while( 1 )
    {
        disp7seg( cont );
        delay(500);
        cont = ++cont % 16;
    }
}

Alteração da biblioteca do display

#include <xc.h>
#include "delay.h"

const char disp7seg_digitos[16] = 
{   0xFC, 0x60, 0xDA, 0xF2, 
    0x66, 0xB6, 0xBE, 0xE0, 
    0xFE, 0xF6, 0xEE, 0x3E, 
    0x9C, 0x7A, 0x9E, 0x8E
};

void disp7seg_init( void )
{
    ANSELH = 0;
    TRISB = 0;
    PORTB = 0;
}

void disp7seg( unsigned char num )
{
    PORTB = (num < 16) ? disp7seg_digitos[num] : 0;
}

Agora é a sua vez!

Crie o seu projeto, copie o código, execute-o, procure os erros, arrume-os, seja resiliente, leia novamente a explicação, busque outras fontes, pergunte, responda, explique, faça alterações conscientes no código, explore, divirta-se.

Ficou com alguma dúvida, entre em contato.

Bom trabalho!


« C1 - Partida Estrela/Triângulo « C1 - Display de 7 segmentos » C1 - 2 Displays de 7 segmentos»

Voltar