Saltar al contenido

Multiplexación Display de 7 Segmentos con PIC

En esta entrada aprenderás paso a paso a usar la Multiplexación del display 7 segmentos con PIC, que es una técnica muy común en electrónica digital que nos permite conectar displays 7 segmentos de 2 dígitos, 4 dígitos o los dígitos que desees a nuestro microcontrolador.

Antes que nada te hago la invitación para que veas todo el curso completo y gratuito de Microcontroladores PIC.

Y que te suscríbas al canal de YouTube para seguir aprendiendo como programar microcontroladores:

Multiplexar Display 7 Segmentos PIC C


En muchas ocasiones se requiere mostrar números en el display de más de un dígito, es decir, 2, 3, o 4 dígitos. En la entrada pasada vimos como usar un único 👉 display de 7 segmentos con PIC, en esta entrada vamos a generalizarlo para la cantidad de displays que queramos colocarle a nuestro proyecto. Quizas te pueda interesar como usar el 👉 display 7 segmentos con Arduino.

Notemos que si se pretende controlar cada display, se necesitan siete (7) líneas del microcontrolador por cada uno, esto ocuparía todas las líneas disponibles en cada puerto del microcontrolador, sin embargo existe una técnica llamada multiplexación que consiste en conectar a las mismas 7 líneas los 2,3 o 4 display e ir encendiendo uno a uno los display, a través de un transistor, tan rápidamente que parece encenderse todos al mismo tiempo.

Cualquier elemento que se encienda y apague con una frecuencia mayor a 25Hz es imperceptible para el ojo humano, éste lo verá encendido en todo momento.

Display 7 Segmentos de vários Dígitos con PIC

A continuación vemos un esquemático para Multiplexar 2 Display 7 Segmentos con PIC, sin embargo lo podemos extender para el numero de displays que queramos, puedes usarlo para multiplexar 3 display de 7 segmentos con pic, para multiplexar 4 display de 7 segmentos con pic, etc.

Multiplexacion con display 7 segmentos

Nota: los segmentos de cada display van unidos entre sí, es decir a con a, b con b, hasta el g con g, por cada display adicional se necesita un transistor y sólo una línea más del microcontrolador. También es importante que entiendas que en el mercado ya venden displays de varios digitos, como el caso del display de 4 digitos.

displays 7 segmentos varios digitos

En este diagrama se asume que las unidades están en el display de la derecha y las decenas en el display de la izquierda.

A continuación veremos un ejemplo para multiplexar display 7 segmentos con PIC C, que muestra como multiplexar 2 display de 7 segmentos con PIC, pero el mismo ejemplo lo puedes usar para controlar 4 display 7 segmentos con PIC. La única diferencia es aumentar el numero de displays y repetir en la linea de código los mismo para las centenas y millares.

Es importante destacar que para la construcción de nuestros proyectos electrónicos con microcontroladores podemos comprarlos también desde la comodidad de nuestra casa en Amazon que tiene envios para cualquier lugar de latinoamerica y para europa:

Display 7 Segmentos Tabla en Hexadecimal

A continuación te dejo la tabla del Display 7 Segmentos Hexadecimal para Cátodo y Ánodo común:

Cátodo Común

Display 7 Segmentos Catodo Común

Para manejar una estructura en C, lo único que se debe hacer es añadir la estructura al encabezado.

Para Cátodo Común adicionar el siguiente arreglo:

Byte CONST display[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};

La conexión a cátodo común se realiza a través de transistores NPN llevando el común del display a tierra como se observa en la siguiente ilustración:

Display de 7 Segmentos Catodo común

Ánodo Común

Display 7 Segmentos Anodo Común

Para Ánodo Común adicionar el siguiente arreglo:

Byte CONST display[10]= {0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x18};

El número 10 indica la cantidad de posiciones de la estructura, los códigos 7 segmentos están en hexadecimal.

La conexión a ánodo común se realiza a través de transistores PNP llevando el común del display a VCC como se observa en la siguiente ilustración:

Display 7 Segmentos Anodo Común

Display 7 Segmentos de 2 Dígitos – Ejemplo

Realizar un temporizador con display de 7 segmentos de 0 a 99 que incremente cada segundo.

Multiplexación con PIC

A continuación te dejo el código para que lo puedas copiar y pegar en tu compilador y de esta manera puedas reproducirlo en tu computador. Recuerda que para ver el código solo debes compartir el contenido de este post. Gracias por apoyar la página.

#INCLUDE <16F887.h>
//#USE DELAY(CLOCK=4000000) //Reloj interno 4MHz
#use delay(clock=4000000,crystal)//Crystal Externo 4MHz
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
Byte CONST display[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};
#BYTE PORTB= 6
#BYTE PORTC= 7
#DEFINE TUNI PORTC,0 //Definición de variables
#DEFINE TDEC PORTC,1 //Definición de variables

INT CONT;   //Declarar la variable CONT como
            //un entero, es decir de 8 bits
LONG CONTRET;  //Declarar la variable CONTRET
               //como long, es decir de 16 bits
               
               
VOID MOSTRAR( ) //Rutina mostrar
{
   INT UNI,DEC;   //Declarar las variables UNI, DEC
                  //como un entero, es decir de 8bits
   DEC=CONT/10;
   UNI=CONT%10;
   PORTB=(DISPLAY[UNI]);   //Muestra lo que hay en unidades
                           //en el display
   BIT_SET (TUNI);         //Enciende el display de unidades
   DELAY_MS(1);            //Retardo de 1 milisegundos
   BIT_CLEAR(TUNI);        //Apaga el display de unidades
   PORTB=(DISPLAY[DEC]);   //Muestra lo que hay en unidades
                           //en el display
   BIT_SET (TDEC);         //Enciende el display de decenas
   DELAY_MS(1);            //Retardo de 1 milisegundos
   BIT_CLEAR(TDEC);        //Apaga el display de decenas
   
}


VOID RET1SEG() //Rutina RET1SEG
{
   CONTRET=500; //Cargue con 500 la variable CONTRET
   WHILE (CONTRET>0) //Mientras que la variable CONTRET sea mayor que cero
   {
      MOSTRAR();        //Llamar la rutina MOSTRAR
      CONTRET--;        // Decremente la variable CONTRET
   }
}

void MAIN()
{
   SET_TRIS_B(0); //El puerto B esta configurado como salida
   SET_TRIS_C(0); // El puerto C esta configurado como salida
   CONT=0;  //la variable CONT se inicializa con cero

   WHILE(TRUE) //Haga por siempre
   {
      CONT=0;
      WHILE(CONT<100) //mientras la variable CONT es menor que 100
      {
         RET1SEG( ); //Llama la rutina RET1SEG
         CONT++; //Incrementa la variable CONT
      }
      
   }
}

En el ejemplo anterior se utilizan funciones, que son pequeños subprogramas que se pueden llamar desde el programa principal (MAIN). Se debe digitar antes del programa principal que es quien las llama.

Las dos funciones empleadas son: «MOSTRAR» que es una pequeña rutina que se encarga de hacer la multiplexación entre los dos displays. Y la otra funcion es «RET1SEG» que es una rutina de retardo de 1 segundo, que va llamando en todo momento a multiplexación para que de este modo mientras se está esperando a que el retardo de 1 segundo se cumpla, vaya mostrando el valor del temporizador actual.

Si la función no retorna ningún valor se pone la directiva VOID antes del nombre de la función indicando que no retorna ningún valor.

Eso es todo por la entrada del dia de hoy, espero les haya gustado y hayan aprendido algo nuevo. Si te ha servido el contenido de esta entrada, de los videos y los códigos de implementación y deseas apoyar mi trabajo invitandome a un café super barato, puedes hacerlo en el siguiente link:

👉 Invitar a Sergio a un Café ☕️

Que esten muy bien, nos vemos en la siguiente entrada.

Entradas relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Comentarios (17)

hola buenos días quería hacer una consulta yo hice un programa con multiplexacion,interrupciones en mplab y me salta un error de guardado. Sin embargo también me salta un error de carpetas :

1 warning and 2 errors generated.
(908) exit status = 1
make[2]: Leaving directory ‘/home/projects/prueba’
make[1]: Leaving directory ‘/home/projects/prueba’
make[2]: *** [nbproject/Makefile-default.mk:104: build/default/production/newmain.p1] Error 1
make[1]: *** [nbproject/Makefile-default.mk:85: .build-conf] Error 2
make: *** [nbproject/Makefile-impl.mk:39: .build-impl] Error 2

Responder

Hola es que estamos realizando una multiplexión para ajustarlo a un contador con tres displays solo que los dos primeros deben llegar a 59 y el tercero a tres; sin embargo al momento de hacer los ajustes me marca error a partir de conteo con el segundo display ya que no me aparece completo el digito.

Responder

Hola Sergio, gracias por tu aporte de conocimiento.
Por favor un tutorial para aprender el manejo de una matriz led con su respectivo max7219
gracias por tu atención.

Responder

Que tal Sergio, muy bueno el curso y te quiero agradecer porque aprendí bastante, mi problema es que no tengo ni tweeter ni facebook por eso no puedo desbloquear el código de implementación, Gracias de todas formas

Responder

otra pregunta, por que le ponemos 500 a la variable contret ?

Responder

Fue un calculo que hice, para que diera aproximado 1 segundo. Pero si deseas precisión entonces debes usar los Timers que están explicados en otra entrada. Saludos.

Responder

Que tal, excelente video, y admiro muchisimo que te des el tiempo de repartir tu conocimiento, pero una pregunta por que tengo que hacer esa operacion en dec y uni (INT UNI,DEC;

DEC=CONT/10;
UNI=CONT%10;) ?
espero con ansias tu respuesta, muchas gracias

Responder

Si, para dos dígitos sería asi.

Responder

Hola, tengo una duda… si quiero hacer el mutiplexeo con 4 displays como debe ser mi código en la parte de mostar para cen y mil?

VOID MOSTRAR(){
INT UNI, DEC, CEN, MIL;
UNI=CONT%10;
DEC=CONT/10;
CEN=???
MIL=???

Responder

Hay varias formas de hacerlo, dependiendo de la lógica de programación, por ejemplo:

int dig[4]; //Declarar las variables
// básicamente es una división con residuo solo se toma el residuo
dig[3]=(CONT / 1000); //Dígito Millar
dig[2]=(CONT % 1000)/100; //Dígito Centena
dig[1]=(CONT % 100)/10; //Dígito Decena
dig[0]= CONT % 10; //Dígito Unidad

Responder

Hola, una pregunta. Puedo multiplexar los display sin usar los transistores?

Responder

Hola Eduardo, no es recomendable que lo hagas sin transistores, porque le estarías inyectando mucha corriente a un unico pin del PIC y lo puedes quemar, por eso siempre la mejor práctica para multiplexar es usar transistores para este fin.

Responder

Holaa, quiero hacer un voltimetro con 7 segmento y el pic16f876, pero estoy empezando ahora, me ayudas ?

Responder

Hola Carlos, siguiendo el curso que tenemos en la pagina puedes conseguir hacer tu voltimetros. Dale un vistazo a la entrada de conversión analogo digital. Éxitos

Responder

me explico mejor disculpe que le responda hasta ahorita, ya vi el video e intento realizar una comvinacion de los 2 del primero el final con el contacto y del segundo pero no hallo como realizar el multiplexado con el pulsador

osea me explico estoy haciendo un contador sumador y que resta con una pantalla led de 2 digitos necesito que cada vez que entra alguien(que se oprime el pulsador 1) suba un digito, y cuando salga alguien (que se oprime el pulsador 2) reste un digito, cuando se oprime el pulsador 3 resetee el conteo

tambien hice este
pero este solo funciona con un digito, no entendi bien lo del multiplexaje a la final hablas de dos formulas pero no se como funcionan, lo que entendi es que mostrar es la que muestra los dos digitos, y la conrec da un retardo que no entendi, pero para colocarle un pulsador para que este suba un solo digito tira error e invierte como se ve la pantalla(osea los leds que deberian prender permanecen apagados y los que estan apagados permanecen prendidos)

#INCLUDE
#FUSES XT,NOLVP,NOWDT,PUT
#USE DELAY(CLOCK=4000000)
Byte CONST display[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};
#DEFINE SWENTRADA PORTC,0
#DEFINE SWSALIDA PORTC,1
#DEFINE SWRESET PORTC,3
#DEFINE LEDENTRADA PORTD,0
#DEFINE LEDSALIDA PORTD,1
#DEFINE TUNI PORTA,0 //Definición de variables
#DEFINE TDEC PORTA,1 //Definición de variables
#BYTE PORTA = 5
#BYTE PORTB = 6
#BYTE PORTC = 7
#BYTE PORTD = 8

INT CONT; //Declarar la variable CONT como
//un entero, es decir de 8 bits
LONG CONTRET; //Declarar la variable CONTRET
//como long, es decir de 16 bits

VOID MOSTRAR( ) //Rutina mostrar
{
INT UNI,DEC; //Declarar las variables UNI, DEC
//como un entero, es decir de 8bits
DEC=CONT/10;
UNI=CONT%10;
PORTB=(DISPLAY[UNI]); //Muestra lo que hay en unidades
//en el display
BIT_SET (TUNI); //Enciende el display de unidades
DELAY_MS(1); //Retardo de 1 milisegundos
BIT_CLEAR(TUNI); //Apaga el display de unidades
PORTB=(DISPLAY[DEC]); //Muestra lo que hay en unidades
//en el display
BIT_SET (TDEC); //Enciende el display de decenas
DELAY_MS(1); //Retardo de 1 milisegundos
BIT_CLEAR(TDEC); //Apaga el display de decenas

}

VOID RET1SEG() //Rutina RET1SEG
{
CONTRET=500; //Cargue con 500 la variable CONTRET
WHILE (CONTRET>0) //Mientras que la variable CONTRET sea mayor que cero
{
MOSTRAR(); //Llamar la rutina MOSTRAR
CONTRET–; // Decremente la variable CONTRET
}
}

void main (){
SET_TRIS_A(0B00000000);
SET_TRIS_B(0B00000000);
SET_TRIS_C(0B11111111);
SET_TRIS_D(0B00000000);
CONT=0;
while(TRUE) // Haga por siempre
{
if(BIT_TEST(SWENTRADA)) // Si SW esta activado
{
BIT_SET(LEDENTRADA); // Active el led
DELAY_MS(200);
while(BIT_TEST(SWENTRADA));
CONT++;
PORTB= display[CONT];
if (CONT==10)
{
CONT=0;
}
else // Sino, es decir si SW esta desactivado
{
BIT_CLEAR(LEDENTRADA); // Apagar led
}
}

if(BIT_TEST(SWSALIDA)) // Si SW esta activado
{
BIT_SET(LEDSALIDA); // Active el led
DELAY_MS(200);
while(BIT_TEST(SWENTRADA));
CONT–;
PORTB= display[CONT];
if (CONT<0)
{
CONT=0;
}
}
else // Sino, es decir si SW esta desactivado
{
BIT_CLEAR(LEDSALIDA); // Apagar led
}

}
}

estoy confundido si puedes dar una pequeña explicacion de como se usaria un pulsador como tal para que este sume 1 digito

Responder

Cristopher es lo siguiente: Si quieres usar un pulsador para hacer el conteo, debes saber que este es un dispositivo mecanico el cual genera un rebote (Un ruido) que puede generar conflicto. En esta entrada te enseño como colocar pulsadores en el PIC y justamente la misma entrada explica un poco lo que quieres hacer solo que con un único Display: Display con Pulsador (Click aca).

Aqui puedes ver todas las entradas que hay en la pagina de microcontroladores (Click Aca)

Ahora como vas a usar 2 displays, debes hacer una multiplexación. Lo que quiere decir que vas a conectar los 2 displays en un UNICO puerto, (El Puerto B) por ejemplo y con dos transistores los vas a encender y apagar. Entonces por el puerto B mandas el numero de las unidades osea que con el transistor unicamente enciendes el display de las unidades, luego apagas este display y mandas por el puerto B el numero de las decenas y con el otro transistor prendes el display de las decenas. La clave es que como prendes y apagas los displays a una velocidad muy elevada, el ojo humano no lo percibe y piensa que ve los dos displays encendidos al tiempo.

En resumen, basicamente debes juntar el código de la entrada del pulsador y la entrada de la multiplexación. Cuando presiones los botones debes ir almacenando la cuenta en una variable que va a ser tu contador y luego debes mostrarla en el display, con la funcion MOSTRAR();

Saludos

Responder

Muy bueno migo

Responder