C1 - Display de 7 segmentos
MicrocontroladorPICPIC16F887MPLABX-XC8SimulIDE 2021-04-25Display 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 |
---|
![]() |
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 |
---|
![]() |
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, f
conforme mostrado na Figura 1.3.
Figura 1.3: Dígito 0 (zero) |
---|
![]() |
É 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) |
---|
![]() |
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) |
---|
![]() |
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 |
---|
![]() |
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 |
---|
![]() |
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.
Operador Unário
(condição) ? valor se a condição é verdadeira : valor se a condição é falsa ;Alterando o Display de PORT
Figura 3: Display 7 segmntos no PORT B |
---|
![]() |
/*
* 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»