Está en la página 1de 17

UNIVERSIDAD ESTATAL DE SONORA

Unidad Académica Hermosillo

Práctica No. 3
Contador ascendente

Display de 7 segmentos a 2 dígitos

Ingeniero en Mecatrónica
Microcontroladores
Profesor: Dr. Jesús Raúl Martínez Sandoval

Estudiante:

Diaz Sixto Jesus


Hermosillo, Sonora, México, 17 octubre de
2023.
1. Introducción

Investigar y desarrollar los conceptos.


1) EQU.
En el lenguaje ensamblador, la directiva EQU se utiliza para asignar un nombre simbólico
al valor de una expresión. Por ejemplo1:
COLUMNAS EQU 80
FILAS EQU 25
PANTALLA EQU FILAS*COLUMNAS
En este caso, COLUMNAS y FILAS son nombres simbólicos asignados a los valores 80 y
25 respectivamente PANTALLA es otro nombre simbólico que se asigna al resultado de la
expresión FILAS*COLUMNAS, es decir, al producto de los valores asignados a FILAS y
COLUMNAS.

2) incf y decf.

incf: La instrucción incf se utiliza en lenguajes de programación de bajo nivel como el


ensamblador para incrementar el valor de un registro o variable en 1. por ejemplo:

incf contador,w

En este caso, se toma el valor del registro contador, se le suma 1 y el resultado se guarda
en el registro w.

decf: Aunque no encontré una fuente específica que defina decf, por convención en
lenguajes de programación de bajo nivel como el ensamblador, decf sería la instrucción
opuesta a incf, disminuyendo el valor del registro o variable en 1. por ejemplo:

decf contador,f

En este caso, se toma el valor del registro contador, se le resta 1 y el resultado se guarda
en el mismo registro contador.

3) call y return.
Call:
La instrucción "call" es una instrucción de lenguaje de programación que se utiliza
comúnmente en lenguajes de alto nivel y ensamblador para llamar a una función o
subrutina. Cuando se ejecuta una instrucción "call", el programa guarda la dirección actual
de ejecución en la pila (o en otro lugar adecuado, dependiendo de la arquitectura), salta a
la dirección de inicio de la función o subrutina especificada y comienza a ejecutar su
código.
La instrucción "call" se utiliza para lograr la ejecución de código modular y reutilizable.
Permite que el flujo del programa se desplace a una función o subrutina específica para
realizar ciertas tareas, y luego regresa al punto de origen después de completar la función.
Esto facilita la división de un programa en piezas más pequeñas y manejables, lo que
hace que el código sea más organizado y mantenible.
Return:

La instrucción return es una construcción utilizada en muchos lenguajes de programación


para finalizar la ejecución de una función o subrutina y, opcionalmente, devolver un valor
al punto de llamada. La acción exacta que realiza return puede variar según el lenguaje de
programación, pero su propósito general es salir de la función y, en algunos casos,
proporcionar un valor de resultado.

En resumen, la instrucción return hace lo siguiente:

Finaliza la ejecución de la función o subrutina actual y regresa el control al punto de


llamada.
Puede devolver un valor resultante, que es un valor calculado dentro de la función, al
punto de llamada. Este valor puede ser útil para transmitir información o resultados desde
la función a quien la llamó.

4) subwf y addwf.

subwf y addwf son dos instrucciones utilizadas en ensamblador para operaciones


aritméticas en microcontroladores PIC (Peripheral Interface Controller). Estas
instrucciones se utilizan comúnmente para realizar sumas y restas en registros del
microcontrolador.

Subwf
Se utiliza para restar un valor en un registro de trabajo (W) de un valor en un registro específico y
guardar el resultado en ese mismo registro.
La sintaxis general de "SUBWF" es la siguiente:
cssCopy code
SUBWF destino, d, a

Donde:
"destino" es el registro de destino donde se almacenará el resultado de la resta.
"d" es un indicador que especifica si se actualiza el registro de destino con el resultado (d=0) o si
se actualiza W con el resultado (d=1).
"a" es un indicador que especifica si se habilita la operación de acarreo (a=0) o si se deshabilita
(a=1).
La instrucción "SUBWF" resta el valor en W del valor en el registro de destino y guarda el
resultado en el registro de destino o en W, según los indicadores "d" y "a". El bit de acarreo se
establecerá si hay un acarreo en la resta.
Esta instrucción es útil para realizar operaciones de resta en ensamblador en microcontroladores
PIC.
addwf (Add with Carry):

ADDWF (sumar) el contenido del registro W con el contenido de un archivo. El resultado puede
ser guardado en el registro W (designador = 0) o emplazado en el archivo llamado (designador =
1). Con la orden ADDWF, en el registro STATUS se ven afectados los bits: C (Carry), Z (Cero) y el
DC (Dígito Carry).

Si el resultado de una instrucción ADD rebasa FF, la bandera C (Carry) es puesta a 1, si tiene
cualquier otro valor es 0.
Si el resultado de una instrucción ADD es cero 0000 0000, la bandera Z (Cero) se pone a 1 y 0 si
tiene cualquier otro valor.
La suma se realiza en aritmética binaria pura y sin signo. Si hay un (desborde) acarreo del bit 7,
es decir que el resultado es mayor de 255, el bit C (bandera Carry) resulta 1, en caso contrario
resulta 0. El PIC supervisa si hay acarreo del bit 3, es decir que, la suma de los dos (nibbles)
mitades menos significativas (bits 0 a 3) resulta mayor de 15, el bit DC (digit carry) se pone a 1, en
caso contrario se pone a 0.

Por ejemplo: Si agregamos 21h a 3Ch, el resultado es 5Dh, esto no afecta la bandera Carry, por
lo que la bandera DC (dígito carry) será puesta a 1, pero si a 2Dh le agregamos 3Eh, el resultado
es 6Bh, lo que desborda el contador (6B>FF) por lo que la bandera C (Carry) será puesta a 1.

5) Retlw.

La instrucción retlw es una instrucción específica de los microcontroladores PIC


(Peripheral Interface Controller) de Microchip y se utiliza para retornar un valor literal (un
byte) desde una rutina de interrupción o subrutina. Esta instrucción se encuentra
comúnmente en el conjunto de instrucciones de ensamblador para microcontroladores
PIC.

6) Nop

"NOP" es una instrucción vacía que no tiene efecto en el flujo del programa. Su principal
utilidad radica en la creación de retardos, la alineación de código o simplemente para
llenar espacios en el código ensamblador sin realizar ninguna operación útil.
En muchas arquitecturas y ensambladores, la instrucción "NOP" generalmente se
representa como "NOP" o "nop". Un ejemplo de uso de "NOP" en ensamblador x86 sería:

7) incfsz y decfsz

Las instrucciones INCFSZ y DECFSZ son instrucciones específicas de los


microcontroladores PIC (Peripheral Interface Controller) de Microchip, y se utilizan para
incrementar (sumar uno) o decrementar (restar uno) el valor contenido en un registro
específico, y luego saltar a una instrucción diferente si el resultado de la operación es igual
a cero (cero resultante, Z=0).
INCFSZ (Increment File and Skip if Zero):

La instrucción INCFSZ se utiliza para incrementar el valor en un registro y, si el resultado


es cero, salta a la siguiente instrucción.
La instrucción toma dos operandos: el registro que se va a incrementar y el registro o
literal donde se almacenará el resultado.
INCFSZ Registro, F

DECFSZ (Decrement File and Skip if Zero):


La instrucción DECFSZ se utiliza para decrementar el valor en un registro y, si el resultado
es cero, salta a la siguiente instrucción.
Al igual que INCFSZ, DECFSZ toma dos operandos: el registro que se va a decrementar y
el registro o literal donde se almacenará el resultado.
Ejemplo:

DECFSZ Registro, F

Se utiliza para decrementar el contenido de un registro en 1 y saltar a una dirección específica en


el programa si el resultado se convierte en cero (es decir, si el registro llega a cero).

8) Display de 7 segmentos.

Un display de 7 segmentos es un tipo de pantalla o indicador que se utiliza comúnmente


para mostrar dígitos decimales y algunos caracteres alfanuméricos utilizando segmentos
iluminados. Cada dígito o carácter se representa mediante la combinación de siete
segmentos individuales. Cada segmento se llama "a", "b", "c", "d", "e", "f" y "g". Estos
segmentos se encienden o apagan para formar los números o letras deseados.

Cada segmento se puede encender o apagar independientemente para mostrar los dígitos
del 0 al 9 y algunas letras, como A, b, C, d, E, F, etc.

9)

Los ciclos anidados se refieren a la práctica de colocar un ciclo dentro de otro ciclo en la
programación. Esto se utiliza para realizar tareas repetitivas o iteraciones dentro de otras tareas
repetitivas. Los ciclos anidados son una técnica común en la programación y se utilizan en
situaciones en las que se necesita un control más fino sobre las repeticiones.

En un ciclo anidado, el ciclo interior se ejecuta completamente dentro de cada iteración del ciclo
exterior. Esto significa que el ciclo interior se ejecutará varias veces para cada iteración del ciclo
exterior. Los ciclos anidados son útiles cuando necesitas procesar elementos en una estructura de
datos multidimensional, como una matriz bidimensional o una matriz tridimensional. También son
útiles para generar todas las combinaciones posibles de elementos en una colección.
2. Desarrollo

El funcionamiento de la práctica es lo siguiente:

1. Al ejecutar la simulación deberán activarse el display de 7 segmentos, ambos dígitos,


en el valor de “0”, tanto unidades como decenas.

2.1. Material y equipo:

- Aplicación para elaborar diagramas de flujo (Lucidchart-online).


- MPLAB 2.10 y Compilador MPASM.
- Simulador PROTEUS 8.0.
- Microcontrolador: PIC16F4A (1).
- Resistencias
- R=10 kohms (5).
- R= 10 kohms (2).
- Capacitores
- C= 1 uF (2).
- Display de 7 segmentos de color rojo (7SEG-MPX2-CA) Cátodo común.
- Cristal de 4 MHz (1).
- Push Bottom (2).
- Fuente de alimentación a +5 VCD.
Diagrama de flujo.
En la figura 1. se muestra el diagrama de flujo del programa.

Figura 1. diagrama de flujo.


3. Diagrama esquemático en Simulador Proteus.

El diagrama esquemático se presenta en la Figura 2, Donde se puede apreciar la en -


trada hacia el puerto RA0, donde se conecta el botón de incremento y en el puerto B se
conecta hacia el display de 7 segmentos de dos dígitos de color rojo. Así mismo, en el
puerto RA1 y RA2, de conectan los bits de control, para el encendido y apagado de
cada dígito en el display. Por lo tanto, al presionar el botón de incremento, se ingresaría
un 1 digital, el cual se debe contar e incrementar la cuenta en 1, lo que debe aparecer
en el display, de acuerdo a la cantidad de veces que se presione el botón, hasta llegar
a 99, posteriormente, debe reiniciar el contar a 0.

El Puerto B va hacia los LED’s co- rrespondientes a la configuración del display de 7


segmentos (A, B, C, D, E, F, G Y DP).

Del lado izquierdo se encuentra, el botón de reset con sus resistencia de pull -up, así
como el cristal, oscilador que genera la señal de reloj de 4 MHz, para el funcionamiento
del sistema mínimo, para el microcontrolador PIC16F84A.

Figura 2. Diagrama esquemático.


2.4. Código fuente en lenguaje ensamblador.

A continuación, se presenta el código fuente de la práctica correspondiente, a partir del


cual se debe elaborar el diagrama de flujo (apartado 2.2). Inicia con su encabezado, la
solución (apartado 2-funcionamiento) y los comentarios , debidamente asignados a
cada línea de código, para la interpretación del mismo. En las mediciones, incluir la
captura de pantalla de la compilación satisfactoria.

; Programa: Práctica 2 - Contador con Botón de Incremento


; Autor: diaz sixto jesus
; Fecha: 17 de octubre de 2023
; Lugar: Hermosillo, Sonora
; Versión:2.1

; Cargar las librerías del microcontrolador


LIST P=16F84A
#INCLUDE <P16F84A.INC>

; Declaración de variables
UNIDAD EQU 0x12 ; Dirección de memoria para la variable UNIDAD
DECENA EQU 0x13 ; Dirección de memoria para la variable DECENA
O EQU 0x14 ; Dirección de memoria para la variable O
M EQU 0x15 ; Dirección de memoria para la variable M
N EQU 0x16 ; Dirección de memoria para la variable N
TempUnidad EQU 0x17 ; Dirección de memoria para la variable TempUnidad
R_ContA EQU 0x18 ; Dirección de memoria para el registro R_ContA
R_ContB EQU 0x19 ; Dirección de memoria para el registro R_ContB

; Dirección de origen o reset


ORG 0x00
INICIO

; Configuración de puertos de entrada


bsf STATUS, RP0 ; Acceso al banco 1
movlw b'00000001' ; Configura pin de entrada RA0
movwf TRISA ; Configura el puerto A como entrada
clrf TRISB ; Configura el puerto B como salida
bcf STATUS, RP0 ; Regresa al banco 0
clrf PORTA ; Limpia el puerto de entrada A
clrf PORTB ; Limpia el puerto de salida B
clrf UNIDAD ; Limpia el registro UNIDAD
clrf DECENA ; Limpia el registro DECENA
clrf TempUnidad ; Limpia el registro TempUnidad
movlw d'0' ; Asigna el valor 0 a W
movwf UNIDAD ; Asigna el valor de W a UNIDAD

; Inicializa el display en ceros


bsf PORTA, RA2 ; Enciende el segundo dígito (UNIDADES)
movlw d'0'
call TablaCodigo
movwf PORTB
bsf PORTA, RA1 ; Enciende el primer dígito (DECENAS)
movlw d'0'
call TablaCodigo
movwf PORTB

; Ciclo infinito
CICLO
movf PORTA, W ; Lee el bit RA0 del puerto A (botón)
call RETARDO_20ms ; Retardo antirrebote
call RETARDO_10ms ; Retardo antirrebote
call DISPLAY ; Llama a la subrutina DISPLAY
btfss PORTA, RA0 ; Salta si RA0 es igual a 1
goto CICLO ; Regresa al ciclo infinito
goto CONTAR ; Salta a la subrutina CONTAR

; Subrutina para incrementar y contar los pulsos en RA0


CONTAR
incf UNIDAD, 0 ; Incrementa el valor de UNIDAD en 1
movwf UNIDAD
movlw d'10' ; Carga el valor 10 a W
subwf UNIDAD, 0 ; Resta UNIDAD a W
btfss STATUS, C ; Salta si el bit "C" es 1
goto CICLO ; Si C=0, regresa al ciclo
goto DECENAS ; Si C=1, salta a la subrutina DECENAS

; Subrutina para incrementar las decenas


DECENAS
movlw d'0' ; Carga el valor 0 a W
movwf UNIDAD ; Mueve W a UNIDAD (UNIDADES=0)
incf DECENA, 0 ; Incrementa el valor de DECENA en 1
movlw d'10' ; Carga el valor 10 a W
subwf DECENA, 0 ; Resta DECENA a W
btfss STATUS, C ; Salta si el bit "C" es 1
goto CICLO ; Si C=0, regresa al ciclo
goto REINICIO ; Si C=1, salta a la subrutina REINICIO

; Subrutina para reiniciar los valores


REINICIO
movlw d'0' ; Carga el valor 0 a W
movwf UNIDAD ; Mueve W=0 a UNIDAD
movwf DECENA ; Mueve W=0 a DECENA
goto CICLO ; Regresa al ciclo

; Tabla de códigos para los dígitos del display de 7 segmentos


TablaCodigo
addwf PCL, F
retlw b'11000000' ; Código para el número "0"
retlw b'11111001' ; Código para el número "1"
retlw b'10100100' ; Código para el número "2"
retlw b'10110000' ; Código para el número "3"
retlw b'10011001' ; Código para el número "4"
retlw b'10010010' ; Código para el número "5"
retlw b'10000010' ; Código para el número "6"
retlw b'11111000' ; Código para el número "7"
retlw b'10000000' ; Código para el número "8"
retlw b'10011000' ; Código para el número "9"
return
; Subrutina de retardo de 200 ms
RETARDO_200ms
movlw d'200' ; Carga el valor de retardo en ms
goto RETARDO_ms
; Subrutina de retardo de x ms (general)
RETARDO_ms
movwf R_ContB ; Asigna el valor de retardo en ms a R_ContB (ciclo externo)
RETARDO_CICLO_EXTERNO
movlw d'249' ; Carga el número de veces para ejecutar el ciclo en W
movwf R_ContA ; Asigna el valor a R_ContA
RETARDO_CICLO_INTERNO
nop ; No operation, no realiza ninguna operación, consume ciclos de reloj
decfsz R_ContA, F ; Decrementa y guarda el valor en R_ContA (ciclo interno)
goto RETARDO_CICLO_INTERNO ; Vuelve al ciclo interno
decfsz R_ContB, F ; Decrementa y guarda el valor en R_ContB (ciclo externo)
goto RETARDO_CICLO_EXTERNO ; Vuelve al ciclo externo
return ; Regresa a la dirección desde la que se invocó la función
; Subrutina DISPLAY
DISPLAY
movf UNIDAD, 0
call TablaCodigo
bcf PORTA, RA2 ; Apaga el dígito de las DECENAS
bsf PORTA, RA1 ; Enciende el dígito de las UNIDADES
movwf PORTB ; Envía el código del dígito al puerto B (display de 7 segmentos)
call RETARDO_20ms ; Retardo para mostrar el dígito
call RETARDO_10ms ; Retardo para mostrar el dígito

movf DECENA, 0
call TablaCodigo
bcf PORTA, RA1 ; Apaga el dígito de las UNIDADES
bsf PORTA, RA2 ; Enciende el dígito de las DECENAS
movwf PORTB ; Envía el código del dígito al puerto B (display de 7 segmentos)
call RETARDO_20ms ; Retardo para mostrar el dígito
call RETARDO_10ms ; Retardo para mostrar el dígito
return ; Regresa a la dirección desde la que se invocó la función

END.
Estados:
1) En la siguiente figura se muestra el display de 7 segmentos al iniciar el
programa con el valor de “00” en pantalla.

Figura 3. Display “00”.

2) Al presionar el botón de incremento, debe incrementarse el valor del


contador en 1. Ver figura 4.

Figura 4.Display en “01”.

3) Al presionar el botón, el contador llega a 09 y 10. Ver figura 5 y 6.


Figura 5. Display en “09”.

Figura 6. Display en “10”.

4) En la siguientes figuras 7 y 8 contador llega a 49 y 50.


Figura 7.Display en 49

Figura 8. Display en 50

5). En las siguientes figuras el contador llega a 98 y 00.

Figura 10. Display en “98”


Figura 10. Display en “00”.
6) Botón de reset presionado, se reinicia la simulación.

Figura 11. Sistema reiniciado,


Conclusiones
La implementación del código para el microcontrolador PIC 16F84A es técnicamente sólida y
eficaz en su funcionamiento. El código configura con precisión los puertos de entrada y salida,
estableciendo RA0 como un pin de entrada y configurando adecuadamente los puertos para el
display de 7 segmentos. El proceso de rutina para encender y apagar los dígitos de unidades y
decenas en el display se ejecuta de manera precisa y controlada. El uso de subrutinas de retardo,
como RETARDO_20ms y RETARDO_10ms, se muestra efectivo para evitar problemas de rebote
del botón, lo que contribuye al comportamiento estable del programa. Además, el proceso de
retardo se implementa de manera eficiente, utilizando ciclos de reloj para consumir el tiempo
necesario.

El display de 7 segmentos funciona de manera coherente, y la tabla de códigos se emplea con


precisión para mostrar los números en la pantalla. A pesar de que los dígitos en el display parecen
estáticos, el código está diseñado para operar de manera cíclica a una velocidad constante, lo que
garantiza un rendimiento constante y preciso.

En resumen, el código demuestra un sólido entendimiento de la configuración del hardware, el


control de puertos y el manejo de retardo. El desempeño general del programa es coherente y
estable, logrando el objetivo de contar pulsos en el botón y mostrarlos de manera efectiva en el
display de 7 segmentos.

Durante la práctica, enfrenté varios desafíos que me llevaron a una experiencia valiosa. En primer
lugar, la configuración de los puertos y la interacción con el hardware del microcontrolador
resultaron más complejas de lo que esperaba. Tuve problemas iniciales al establecer los registros
TRISA y TRISB para los pines de entrada y salida, pero después de revisar detenidamente el
manual y realizar algunos ensayos, logré superar estos obstáculos.

Otro desafío significativo fue lidiar con el rebote del botón al presionar RA0. Para abordar este
problema, implementé subrutinas de retardo, RETARDO_20ms y RETARDO_10ms, que resultaron
ser efectivas para eliminar el rebote y garantizar la precisión del contador.

Una de las lecciones más valiosas que aprendí durante la práctica fue la importancia de la
planificación y la paciencia al enfrentar problemas técnicos. También mejoré mi comprensión de la
estructura de un programa en ensamblador y su relación con el hardware.
3. Referencias bibliograficas

Admin. (2023, 15 marzo). Instrucciones de comparación, PLC - EQU NEQ GRT LES GEQ LEQ

LIM. ProLogic. https://www.germanmadrid.com/2020/04/18/instrucciones-de-comparacion/

DECFSZ (Microchip PIC18F Instruction Set). (s. f.).

http://technology.niagarac.on.ca/staff/mboldin/18F_Instruction_Set/DECFSZ.html

González, J. D. M. (2018). Ciclos anidados. www.programarya.com.

https://www.programarya.com/Cursos/C++/Ciclos/Ciclos-anidados

García, V. (s. f.-a). Instrucciones PIC – Electrónica Práctica aplicada.

https://www.diarioelectronicohoy.com/blog/instrucciones-pic

14/20-Pin Full-Featured, Low Pin count microcontrollers with XLP. (s. f.).

https://onlinedocs.microchip.com/pr/GUID-1D0144A3-6E9C-49D4-850F-2F7000F00CDF-

en-US-8/index.html?GUID-3EC45548-66D4-4FD9-BAAD-FEE7A5ABC71B

También podría gustarte