Está en la página 1de 13

UNIVERSIDAD PRIVADA ANTENOR ORREGO

ESCUELA PROFESIONAL DE INGENIERÍA


ELECTRÓNICA

TALLER DE MICROCONTROLADORES Y PLACAS IMPRESAS

“Diseño e implementación de un contador con display multiplexado


utilizando el microcontrolador PIC18F57Q43 y técnicas de
interrupción”

PROFESOR: Kalun José Lau Gan

INTEGRANTES DEL GRUPO:

1. Cerna Castillo, Bruno Alfonso

Semestre 2023-I
Índice
Introducción.............................................................................................................................. 2
Objetivos....................................................................................................................................2
Materiales.................................................................................................................................. 3
Desarrollo.................................................................................................................................. 3
I. Diseño de hardware...........................................................................................................3
II. Desarrollo del algoritmo en diagrama de flujo.................................................................. 5
III. Codificación del diagrama de flujo en lenguaje de programación XC8........................... 7
IV. Pruebas de validación....................................................................................................11
Conclusiones...........................................................................................................................11
Recomendaciones y comentarios finales............................................................................ 12
Referencias bibliográficas..................................................................................................... 12

1
Introducción

El presente proyecto detalla el desarrollo, diseño e implementación de un contador


utilizando el microcontrolador PIC18F57Q43 y un display de 7 segmentos de ánodo
común, junto con otros componentes necesarios para su correcto funcionamiento. El
objetivo principal de este proyecto es crear una aplicación que permita realizar el conteo y
visualización de forma precisa y eficiente. Para lograrlo, se emplean diversas técnicas,
como la multiplexación, tablas de conversión y asignación de vectores de interrupción. El
desarrollo completo de la aplicación se divide en cuatro ítems principales. En el primer
ítem, se presenta el diseño del hardware, incluyendo el diagrama esquemático y fotografías
de la implementación física. En el segundo ítem, se detalla el algoritmo utilizado,
presentado en un diagrama de flujo que muestra claramente la secuencia de operaciones. El
tercer ítem abarca el código completo de la aplicación, desarrollado en el lenguaje de
programación XC8, e incluye las configuraciones de los bits necesarios para el correcto
funcionamiento de las interrupciones. Por último, el ítem 4 proporciona evidencia visual
del funcionamiento exitoso de la aplicación a través de pruebas fotográficas que muestran
la visualización de la cuenta en el display.

Objetivos

1. Diseñar e implementar un contador utilizando el microcontrolador PIC18F57Q43 que


permita la visualización de valores desde 0000 a 9999 en un display de 7 segmentos
multiplexado.

2. Utilizar de manera efectiva las interrupciones externas INT0, INT1 e INT2 disponibles
en el microcontrolador PIC18F57Q43 con vectores de interrupción para gestionar
eventos múltiples y realizar acciones específicas en respuesta a ellos.

3. Emplear tablas de conversión y decodificación de datos para facilitar la correcta


visualización de la información en el display de 7 segmentos.

2
Materiales
Nombre Cantidad Observación

Transistor 2N3906 04 Tipo: PNP

Resistencia 1k Ω 04 Potencia: 1/4W

Resistencia 330 Ω 07 Potencia: 1/2W

Capacitor 0,1uF 03 Encapsulado cerámico

Display ánodo común 01 Cuatro dígitos multiplexados,


color rojo

Microcontrolador 01 Microcontrolador de 8 bits


PIC18F57Q43

Pulsador 03 Tipo: Normalmente Abierto


(NA)

Protoboard 02 830 puntos

Cable de conexión 38 22 AWG

Desarrollo
I. Diseño de hardware
Para el diseño de hardware se ha seleccionado el microcontrolador
PIC18F57Q43. Además, se han incluido tres pulsadores normalmente abiertos (NA)
con sus correspondientes capacitores de 0.1 uF para evitar el rebote. Estos pulsadores
están conectados entre los puertos de interrupción externa INT0 - INT2 y tierra. Se ha
utilizado un módulo de display rojo de cuatro dígitos con ánodo común. Para la
conexión de los segmentos del display, se han empleado siete resistencias de 330 ohm
que actúan como intermediarias entre los pines RF0 - RB6 y los segmentos. Asimismo,
se han utilizado cuatro transistores PNP 2N3906 para habilitar los cuatro dígitos del
display, conectando el colector del transistor con el ánodo del display. Para la conexión
de los transistores, se han utilizado cuatro resistencias de 1K ohm. Estas resistencias
actúan como intermediarias entre los pines RA0 - RA3 y la base de los transistores para
limitar la corriente, mientras que el emisor se conecta a 3.3 V.

3
Diagrama esquemático del circuito

Implementación: Completo

4
Implementación: Pulsadores

Implementación: Display

II. Desarrollo del algoritmo en diagrama de flujo


El algoritmo consta de cuatro diagramas de flujo. El primero describe el
funcionamiento normal del microcontrolador y se encarga de multiplexar la cuenta en el
display. El segundo diagrama denominado INT0_ISR describe la interrupción por INT0
que aumenta en uno el contador. El tercer diagrama denominado INT1_ISR describe la
interrupción por INT1 que disminuye en uno el contador. Por último, el cuarto
diagrama denominado INT2_ISR describe la interrupción por INT2 que reinicia a cero
el contador.

5
Diagrama de flujo de la aplicación

6
III. Codificación del diagrama de flujo en lenguaje de programación XC8
Descripción general del código
En la función configuro(), se configuran los registros y los pines del
microcontrolador para establecer las direcciones de entrada/salida, los niveles de
prioridad de las interrupciones y las configuraciones específicas del hardware.

La función multiplex() se encarga de multiplexar el display de 7 segmentos.


Selecciona cada dígito de la cuenta y muestra su correspondiente valor en el display,
habilitando y deshabilitando los transistores PNP en los pines correspondientes.

Las funciones incrementar_cuenta(), decrementar_cuenta() y reiniciar_cuenta()


son utilizadas para realizar operaciones en la cuenta. La función incrementar_cuenta()
incrementa el valor de una cifra de la cuenta y, si alcanza el valor 10, reinicia esa cifra a
0 y llama recursivamente a la función para incrementar la siguiente cifra. La función
decrementar_cuenta() hace lo contrario: decrementa el valor de una cifra y, si alcanza 0,
establece esa cifra en 9 y llama recursivamente a la función para decrementar la
siguiente cifra. La función reiniciar_cuenta() establece todas las cifras de la cuenta en 0.

En el bucle principal while(1), se llama a la función multiplex() de forma


continua para mostrar la cuenta en el display.

Además, se definen tres interrupciones: INT0_ISR(), INT1_ISR() e


INT2_ISR(). Estas interrupciones son activadas por eventos externos, como pulsadores,
y realizan acciones específicas. La `INT0_ISR()` incrementa las unidades de la cuenta,
la INT1_ISR() las decrementa y la INT2_ISR() reinicia la cuenta a 0. Cada interrupción
realiza su operación correspondiente llamando a las funciones adecuadas.

Bits de configuración.-
// CONFIG1
#pragma config FEXTOSC = OFF // External Oscillator Selection (Oscillator not enabled)
#pragma config RSTOSC = EXTOSC // Reset Oscillator Selection (EXTOSC operating per FEXTOSC bits (device
manufacturing default))

// CONFIG2
#pragma config CLKOUTEN = OFF // Clock out Enable bit (CLKOUT function is disabled)
#pragma config PR1WAY = ON // PRLOCKED One-Way Set Enable bit (PRLOCKED bit can be cleared and set
only once)
#pragma config CSWEN = ON // Clock Switch Enable bit (Writing to NOSC and NDIV is allowed)
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)

// CONFIG3
#pragma config MCLRE = EXTMCLR // MCLR Enable bit (If LVP = 0, MCLR pin is MCLR; If LVP = 1, RE3 pin
function is MCLR )

7
#pragma config PWRTS = PWRT_16 // Power-up timer selection bits (PWRT set at 16ms)
#pragma config MVECEN = ON // Multi-vector enable bit (Multi-vector enabled, Vector table used for
interrupts)
#pragma config IVT1WAY = ON // IVTLOCK bit One-way set enable bit (IVTLOCKED bit can be cleared and
set only once)
#pragma config LPBOREN = OFF // Low Power BOR Enable bit (Low-Power BOR disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled)

// CONFIG4
#pragma config BORV = VBOR_1P9 // Brown-out Reset Voltage Selection bits (Brown-out Reset Voltage (VBOR)
set to 1.9V)
#pragma config ZCD = OFF // ZCD Disable bit (ZCD module is disabled. ZCD can be enabled by setting the
ZCDSEN bit of ZCDCON)
#pragma config PPS1WAY = ON // PPSLOCK bit One-Way Set Enable bit (PPSLOCKED bit can be cleared and
set only once; PPS registers remain locked after one clear/set cycle)
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (HV on MCLR/VPP must be used for
programming)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Extended Instruction Set and Indexed
Addressing Mode disabled)

// CONFIG5
#pragma config WDTCPS = WDTCPS_31// WDT Period selection bits (Divider ratio 1:65536; software control of
WDTPS)
#pragma config WDTE = OFF // WDT operating mode (WDT Disabled; SWDTEN is ignored)

// CONFIG6
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software
control; keyed access not required)
#pragma config WDTCCS = SC // WDT input clock selector (Software Control)

// CONFIG7
#pragma config BBSIZE = BBSIZE_512// Boot Block Size selection bits (Boot Block size is 512 words)
#pragma config BBEN = OFF // Boot Block enable bit (Boot block disabled)
#pragma config SAFEN = OFF // Storage Area Flash enable bit (SAF disabled)
#pragma config DEBUG = OFF // Background Debugger (Background Debugger disabled)

// CONFIG8
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block not Write protected)
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers not Write
protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not Write protected)
#pragma config WRTSAF = OFF // SAF Write protection bit (SAF not Write Protected)
#pragma config WRTAPP = OFF // Application Block write protection bit (Application Block not write protected)

// CONFIG10
#pragma config CP = OFF // PFM and Data EEPROM Code Protection bit (PFM and Data EEPROM code
protection disabled)

Main.-
#include <xc.h>
#include <pic18f57q43.h>
#include "cabecera.h"
#define _XTAL_FREQ 4000000UL

unsigned char cuenta[] = // Array de la cuenta


{
0, 0, 0, 0 // unidad, decena, centena, millar
};

unsigned char decode[] = // TABLA DE CONVERSIÓN DECIMAL -> 7 SEGMENTOS


{
0x81, 0xCF, 0x92, // 0, 1, 2,
0x86, 0xCC, 0xA4, // 3, 4, 5,
0xA0, 0x8F, 0x80, // 6, 7, 8,
0x84 // 9

8
};

void configuro(void){ // Función para configurar registros y el PIC

OSCCON1 = 0x60; // Usando HFINTOSC y divisor de 1:1


OSCFRQ = 0x02; // HFINTOSC a 4MHz
OSCEN = 0x40; // HFINTOSC habilitado

TRISA = 0xF0; // RA0-RA3 salidas


ANSELA = 0xF0; // RA0-RA3 digital

TRISB = 0xFF; // RB0-RB8 entradas


ANSELB = 0xF8; // RB0-RB2 digital
WPUB = 0x07; // RB-RB2 con weak pull-up

TRISF = 0x80; // RF0-RF6 salidas


ANSELF = 0x80; // RF0-RF6 digital

INTCON0bits.GIEH = 1; // Interrupciones high-priority habilitadas


INTCON0bits.GIEL = 1; // Interrupciones low-priority habilitadas
INTCON0bits.IPEN = 1; // Niveles de prioridad de interrupciones habilitados

INTCON0bits.INT0EDG = 0; // INT0 por flanco de bajada


INTCON0bits.INT1EDG = 0; // INT1 por flanco de bajada
INTCON0bits.INT2EDG = 0; // INT2 por flanco de bajada

PIE1bits.INT0IE = 1; // INT0 habilitado


PIE6bits.INT1IE = 1; // INT1 habilitado
PIE10bits.INT2IE = 1; // INT2 habilitado

IPR1bits.INT0IP = 1; // INT0 en high-priority


IPR6bits.INT1IP = 0; // INT1 en low-priority
IPR10bits.INT2IP = 0; // INT2 en low-priority
}

void multiplex(void){ // Función para multiplexar

LATF = decode[cuenta[0]]; // Decodifica el carácter de unidades


LATAbits.LATA0 = 0; // Habilita la conducción del transistor PNP en el display 1
__delay_ms(1); // Espera 1 ms
LATAbits.LATA0 = 1; // Deshabilita la conducción del transistor en el display 1

LATF = decode[cuenta[1]]; // Decodifica el carácter de decenas


LATAbits.LATA1 = 0; // Habilita la conducción del transistor PNP en el display 2
__delay_ms(1); // Espera 1 ms
LATAbits.LATA1 = 1; // Deshabilita la conducción del transistor en el display 2

LATF = decode[cuenta[2]]; // Decodifica el carácter de decenas


LATAbits.LATA2 = 0; // Habilita la conducción del transistor PNP en el display 3
__delay_ms(1); // Espera 1 ms
LATAbits.LATA2 = 1; // Deshabilita la conducción del transistor en el display 3

LATF = decode[cuenta[3]]; // Decodifica el carácter de decenas


LATAbits.LATA3 = 0; // Habilita la conducción del transistor PNP en el display 4
__delay_ms(1); // Espera 1 ms
LATAbits.LATA3= 1; // Deshabilita la conducción del transistor en el display 4
}

void incrementar_cuenta(int pos){ // Función para incrementar una cifra de la cuenta, con variable local de la cifra a
aumentar

if (pos == 4) { // Si ya se evaluaron los millares


return; // Se termina la función
}

cuenta[pos]++; // Incrementa en 1 el valor de la cifra seleccionada


if (cuenta[pos] == 10) { // Si el valor de la cifra seleccionada es 10

9
cuenta[pos] = 0; // Reinicia a 0 el valor de la cifra
incrementar_cuenta(pos + 1); // Llamada recursiva para incrementar la cifra siguiente
}
}

void decrementar_cuenta(int pos){ // Función para decrementar una cifra de la cuenta, con variable local de la cifra a
aumentar

if (pos == 4) { // Si ya se evaluaron los millares


return; // Se termina la función
}

if (cuenta[pos] == 0) { // Si el valor de la cifra seleccionada es 0


cuenta[pos] = 9; // Establece en 9 el valor de la cifra
decrementar_cuenta(pos + 1); // Llamada recursiva para decrementar la cifra siguiente
} else{
cuenta[pos]--; // Decrementa en 1 el valor de la cifra seleccionada
}
}

void reiniciar_cuenta(void){ // Función para reiniciar la cuenta a 0

for(int i = 0; i < 4; i++){ // Bucle de que se repite 4 veces


cuenta[i] = 0; // Reinicia a 0 la cifra de la posición i
}
}

void main(void) {

configuro(); // Configura el los registros y el PIC con la función configuro()

while(1){
multiplex(); // Multiplexa el display con la función multiplex()
}
}

void __interrupt(irq(INT0), high_priority) INT0_ISR(void){ // Interrupción por INT0

PIR1bits.INT0IF = 0; // Baja la bandera de INT0


incrementar_cuenta(0); // Incrementa en 1 las unidades de la cuenta con la función incrementar_cuenta
}

void __interrupt(irq(INT1), low_priority) INT1_ISR(void){ // Interrupción por INT1

PIR6bits.INT1IF = 0; // Baja la bandera de INT1


decrementar_cuenta(0); // Decrementa en 1 las unidades de la cuenta con la función decrementar_cuenta
}

void __interrupt(irq(INT2), low_priority) INT2_ISR(void){ // Interrupción por INT2

PIR10bits.INT2IF = 0; // Baja la bandera de INT2


reiniciar_cuenta(); // Reinicia a 0 la cuenta con la función reiniciar_cuenta
}

10
IV. Pruebas de validación
Para las pruebas se tomaron imágenes en diferentes valores de la cuenta. Estos
son el valor máximo (9999), el valor mínimo (0000) y un valor entre los posibles de la
cuenta (0240).

Conclusiones
1. Se diseñó e implementó de manera física un contador utilizando el microcontrolador
PIC18F57Q43 que permite la visualización de valores de 0000 a 9999 en un display de
7 segmentos multiplexado.

2. Se utilizaron de manera efectiva las interrupciones externas INT0, INT1 e INT2


disponibles en el microcontrolador PIC18F57Q43 con vectores de interrupción para
gestionar los eventos de aumento, disminución y reinicio del contador.

3. Se emplearon tablas de conversión y decodificación de datos para facilitar la correcta


visualización de la información en el display de 7 segmentos.

11
Recomendaciones y comentarios finales
1. Las tablas de conversión y la elección de materiales, como los transistores, están
específicamente diseñados para su compatibilidad con el tipo de display seleccionado,
en este caso, un display de ánodo común. Si se decide utilizar otro tipo de display, se
requerirán modificaciones tanto en el código como en la implementación para
garantizar la compatibilidad y el correcto funcionamiento.

2. Es importante tener en cuenta que las funciones de aumentar y disminuir la cuenta


actualmente utilizan llamadas recursivas. Aunque en la implementación actual estas
llamadas se limitan a un máximo de 4 veces debido a los 4 dígitos del contador, es
importante destacar las posibles desventajas asociadas. En caso de trabajar con números
que contengan más cifras, existe el riesgo de asignar una cantidad excesiva de memoria
y que se produzca un desbordamiento de pila, conocido como stack overflow. Por lo
tanto, al utilizar estas funciones en un contexto más amplio o con números de mayor
magnitud, es recomendable realizar ajustes en el código para evitar posibles problemas
de desbordamiento de pila y asegurar un rendimiento óptimo del programa.

Referencias bibliográficas
1. Microchip Technology Inc. (2022). MPLAB XC8 C Compiler User's Guide for PIC MCU
(DS50002737G). Recuperado de
https://ww1.microchip.com/downloads/aemDocuments/documents/DEV/ProductDocuments/Us
erGuides/MPLAB-XC8-C-Compiler-Users-Guide-for-PIC-DS50002737.pdf

2. Microchip Technology Inc. (2023). PIC18F27/47/57Q43 28/40/44/48-Pin, Low-Power,


High-Performance Microcontroller with XLP Technology (DS40002147G). Recuperado de
https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ProductDocuments/
DataSheets/PIC18F27-47-57Q43-Microcontroller-Data-Sheet-XLP-DS40002147.pdf

3. Microchip Technology Inc. (2020). PIC18F57Q43 Curiosity Nano Hardware User Guide
(DS40002186B). Recuperado de
https://ww1.microchip.com/downloads/en/DeviceDoc/PIC18F57Q43-Curiosity-Nano-HW-User
Guide-DS40002186B.pdf

12

También podría gustarte