Displays de 7 segmentos
February 26, 2007 at 8:40 pm | In MPASM, Rutinas, Tutorial | 25 CommentsUn display de 7 segmentos no es otra cosa que 7 leds conectados entre si con su ánodo o su cátodo en común. Dependiendo del tipo de display será la manera en que se enciendan sus segmentos, un display de cátodo común requiere un 1 logico para encender mientras que uno de cátodo común un 0 así que dependiendo del display que se utilice cambiará la rutina encargada de controlarlo, pero en cualquier caso al momento de cambiar el tipo de display solo debemos cambiar los ceros por unos y viceversa.
Aqui supondremos que se usa un display de cátodo común así que los segmentos encenderán con un 1. El display estará conectado al puerto B, el segmento A estará conectado al bit RB0, el B al RB1, el C al RB2, el D al RB3 y así sucesivamente hasta llegar al G que estará conectado al bit RB6.
Encender y apagar los segmentos del display es igual que encender y apagar leds, podríamos hacerlo de la misma manera que en el tutorial 1, pero una manera mas eficaz de controlar un display es mdiante una tabla. Haremos que el display muestre los números 0 a 15 en hexadecimal (0 a F) con un retardo de medio segundo entre cada número. Para eso se declara el puerto B como salida. Una vez hecho eso se crea la rutina encargada de mandar llamar el numero correspondiente de una tabla y de desplegar el numero correspondiente por el puerto B. El programa principal es el siguiente:

Y ese es basicamente el programa. Al principio se declaran 4 variables, una se utiliza para llevar la cuenta del numero a desplegar y las demas sirven para la rutina de retardo. Como ya se dijo se configura el puerto B como salida y despues se limpia la variable Numero (clrf NUMERO). Despues el programa entra en una subrutina que se encarga de leer la tabla y de desplegar el numero en el puerto. Primero se mueve el valor de la variable Numero al registro W (movf NUMERO,w) y despues se manda llamar la tabla (call DESPLIEGA), al volver el registro W tiene el valor del numero a desplegar y simplementa se mueve al puerto B (movwf PORTB). Se llama a la rutina de retardo (call RETARDO) y al volver de esta se incrementa el valor de la variable Numero (incf NUMERO,f) y despues se transfiere ese valor al registro W (movf NUMERO,w). Esto se hace para realizar una comparacion entre W y la literal 0×10 (16 en valor decimal) para saber si la variable Numero ya fue incrementada 16 veces, si es asi se salta la siguiente instruccion y el programa se repite desde la etiqueta Principal, si no es asi el programa regresa a la etiqueta Ciclo. De este modo el numero se incrementa de 0 a F y al llegar a F regresa a 0. La comparacion se realiza mediante la instruccion sublw 0×10 si el resultado es cero (en caso de que NUMERO=16) la bandera ZERO se pone en 1 y es esa la bandera que se revisa en btfss STATUS,Z.
Como ya se dijo antes de llamar la rutina que lee la tabla se carga el valor de la variable Numero en W, esto se hace asi ya que al entrar a la rutina se realiza una suma entre W y el contador de programa PCL para montarlo en un offset, asi el contador apuntara a la direccion que seguia mas el valor de la variable Numero. Asi la rutina de la table queda de la siguiente manera:

Y asi, de este modo se decodifica un display de 7 segmentos. La rutina de retardo se omitio en la explicacion ya que los retardos se explicaron anteriormente, de cualquier forma se incluye en el codigo del programa. Descargar codigo.
Como nota final: Las imagenes que contienen el codigo en esta ocasion se ven algo distintas que en los tutoriales pasados, ese descuadre se debe a que el codigo se escribio utilizando MPLAB bajo linux, pero en realidad se conservan los mismos espacios y tabulaciones que en ocasiones anteriores, eso se puede ver al descargar el codigo completo.
25 Comments »
RSS feed for comments on this post. TrackBack URI
Leave a comment
Blog at WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.
hola, que tal, perdona que no te respondi tu ultimo correo es que he tenido algunnos problemas con la pc y ahora estoy recuperando el tiempo perdido.
Comment by Mandracke — March 1, 2007 #
Hola, pues ya sabes, para cualquier duda o comentario ahi tienes el correo, espero que sigas pasandote por aqui, estamos en contacto
Comment by micropic — March 2, 2007 #
hay un error despues de la etiqueta inicio:
en vez de hacer un clrf TRISB hace un clrf PORTB!!!!
al hacer clrf PORTB envia ceros al puerto B pero aun no lo configura.
corrección:
inicio
bsf STATUS,RP0 ;Seleccionamos el banco de memoria 1
movlw b’00000000′
clrf TRISB; configura el puerto B como salida
bcf STATUS,RP0
Comment by raziel — March 8, 2007 #
Lo que dices es correcto, sin embargo mi codigo no tiene error, veras PORTB es el registro 0×06 y TRISB el registro 0×86, estando en el banco 0 no se puede acceder a TRISB porque este se encuentra en el banco 1, sin embargo al pasar al banco 1 PORTB y TRISB pasan a ser el mismo ya que TRISB se encuentra en el sexto registro de este banco, es decir 0×06, es por eso que al cambiar al banco 1 configuro TRISB pero accesandolo como PORTB, haciendolo como tu dices si configura el puerto pero lo mas probable es que MPLAB te marque un warning que te avise que el registro TRISB no esta en el banco en el que te encuentras.
Si te fijas en todos los tutoriales para configurar los puertos cambio al banco 1 pero modifico directamente PORTA y PORTB, esto es porque una vez en el banco 1 es lo mismo y no marca ningun error, al contrario, ni siquiera marca warnings
La correccion que tu indicas es correcta pero el codigo del tutorial tambien lo es, yo prefiero hacerlo de esa manera ya que me parece mejor, gracias por tu comentario
Comment by micropic — March 8, 2007 #
GRACIAS POR EL TUTORIAL ME HA SERVIDO DE MUCHA AYUDA. ADELANTE CONTINUA CON ESTA CAPACITACION.
SU AMIGO KABUBIS
Comment by JAIRO RODRIGUEZ — March 17, 2007 #
que tal me pregunto si me pudieras ayudar con un proyecto. mira, tengo que hacer una calculadora y decidi hacerlo con el pic16f684 me gustaria que me dieras una sugerencia de como realizarlo. la calculadora realizara las 4 operaciones basicas, usando un teclado de 0 a 9 .los numeros se desplegaran en un conjunto de 5 Display de 7 segementos. en serio me vendria bien un poco de ayuda. por los cual estare muy agradecido.
Comment by luiscord2 — June 2, 2007 #
olas a toos, espero ser participe de esta gran comunidad de los PIC’s…
bites
Comment by Juan Susanibar — June 8, 2007 #
[...] se decodifica la tecla pulsada utilizando una tabla como la que se utilizó en el ejemplo del display de 7 segmentos.Existen otros métodos de manejar teclados matriciales, pero creo que ésta es la más sencilla. [...]
Pingback by Teclado Matricial 4×4 « MicroPIC — June 13, 2007 #
hola quisiera saver algo sobre el codigo del 7segmento el parte del programa que dice
cblock 0×20
numero
cont1
cont2
cont3
bueno quiero saver si a estas constantes tengo que declararlas es decir
cblock 0×20
numero 0×0c
cont1 0×21
cont2 0×22
cont3 0×23
quisoera saver eso oes que con la asignacion que le haces al cblock 0×20 ya esta asignado pra todos por favor explicame esa parte por lo demas e comprendido . a te felicito y la vez te agradesco por tu ayuda y tus tutoriales que son muy buenos
gracias
Comment by daniel — June 15, 2007 #
daniel, la directiva cblock sirve para declarar variables y constantes, “cblock 0×20″ indica que las variables comenzarán a declararse a partir de la dirección 0×20 de la memoria de datos, no es necesario declarar la dirección a cada una de las variables ya que el valor se irá incrementando en cada una, de este modo cont1 ocupa la dirección 0×20, cont2 la 0×21 y cont3 la 0×22. Al final para decir que ya no se declararán mas variables se usa la directiva endc.
Espero que haya quedado claro, si no es así cualquier duda exponla.
Comment by micropic — June 19, 2007 #
muy bueno el tutorial
una pregutna como puedo controlar dos display por el mismo puerto? no se si puedas hacer un tutorial asi para el de 2 display
Comment by Angel — June 24, 2007 #
Para controlar dos displays en un mismo puerto ocupas multiplexar el puerto. Es una buena idea para un tutorial, cuando tenga algo de tiempo trataré de hacerlo.
Mientras tanto consulta esta página, hay un ejemplo que tal vez te sirva.
Comment by micropic — June 24, 2007 #
hola ,una consulta porque o cuando se utiliza –config 0×3f38 ……
antemano agradesco tu ayuda por este buen tutorial
Comment by leo — September 20, 2007 #
hola, me llamo axel, estudio en la universidad popular autonoma del estado de puebla en puebla, mex. estoy desarrollando un reloj que cuente las horas minutos y seg. con un pic30f2010 pero no he podido desarrollar el programa en C para mplab, me podrias recomendar como comensar el programa????
gracias.
Comment by axel perez — October 3, 2007 #
me pregunto que es lo que hace la funcion despliega sobre todo el codigo addwf PLC;f gracias
Comment by crispin velez — November 9, 2007 #
Eso está explicado en el post pero por si no quedó claro aquí esta de nuevo: el registro PCL es el registro del contador de programa, ese contador de programa siempre apunta hacia la instrucción que se ejecutará a continuación, si se altera el contador se altera el orden de las instrucciones. La subrutina despliega le suma un número cargado en el registro W al registro PCL para que el contador de programa salte hacia la instrucción correspondiente de la tabla. La tabla está formada por instrucciones RETLW, esta instrucción es como ejecutar un return (regreso de subrutina) pero regresa con un valor cargado en el registro W.
Comment by micropic — November 9, 2007 #
gracias por tu aporte man
Comment by jorge — September 26, 2008 #
Como se le haria si solo quiero mostrar los numeros del 0 al 9, como se programa la condicion.
Gracias
Comment by Enrique — October 4, 2008 #
Hola, estoy haciendo tu publicacion como proyecto, por falta de tiempo, y me resulta un problema
se queda en 0, i no avanza de 0, i algunas apareceria ke se resetea, si porsiacaso alguna vez te paso o algo, algun consejo, tengo 4 dias para entregar, gracias.
pd. lo pase a 16f84a, porque el 16f628a tuvo un pequeño problema, y no pude conseguirlo, igual ese no es el problema, porke con el 628 tmb tenia este mismo tema.
el programa:
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
LIST P=16F84a
INCLUDE
CBLOCK 0×0C
NUMERO
CONT1
CONT2
CONT3
ENDC
ORG 0×00
goto Inicio
ORG 0×04
Inicio
bsf STATUS,RP0
clrf PORTB
bcf STATUS,RP0
Principal
clrf NUMERO
Ciclo
movf NUMERO, w
call Despliega
movwf PORTB
call Retardo
incf NUMERO,f
movf NUMERO,w
sublw 0×10
btfss STATUS,Z
goto Ciclo
goto Principal
Despliega
addwf PCL,f
retlw b’00111111′
retlw b’00000110′
retlw b’01011011′
retlw b’01001111′
retlw b’01100110′
retlw b’01101101′
retlw b’01111101′
retlw b’00000111′
retlw b’01111111′
retlw b’01101111′
retlw b’01110111′
retlw b’01111100′
retlw b’00111001′
retlw b’01011110′
retlw b’01111001′
retlw b’01110001′
Retardo
movlw d’50′
movwf CONT3
ciclo3 movlw d’100′
movwf CONT2
ciclo2 movlw d’33′
movwf CONT1
ciclo1 decfsz CONT1,f
goto ciclo1
decfsz CONT2,f
goto ciclo2
decfsz CONT3,f
goto ciclo3
return
end
Comment by Maxy — February 26, 2009 #
hola me llamo edgar, disculpe la molestia pero quisiera saber como se hace una calculadora con el pic 16f84a, los numeros ya me los muestra pero no se como hacer para que el numero se quede guardado y lo sume, reste o multiplique con el otro numero que oprima, si me puede ayudar gracias
Comment by edgar — April 18, 2009 #
por que dices que no muestra warnings y a mi todos tus proyectos me muestran muchisimos warnings ¿que estoy haciendo mal?
perdona esta pregunta pero deseo con todo mi corazon aprender a programar pics (me sale build succeed pero con un monton de warnings).
si pudieras ayudarme muchisimas gracias
Comment by DANIEL URIBE — April 19, 2009 #
hola nesesito ke me ayuden a a ser una calculadora con el pic 16f84a que solo sume o reste del 0 al 9 ayuda urge ok si me pueden ayudar esto ke casi muero
Comment by adal — October 6, 2009 #
muy bueno el tutorial, pero hay unas dudas sobre un comentario que lei, se supone q
Comment by fhantastic — November 18, 2009 #
la variable NUMERO es la que ocupa la direccion 0×20 y las restantes 21,22 y 23 o estoy equivocado?, ademas que significa _config 3f38, he leido la hoja de datos pero aun asi no lo comprendo, por lo demas el tutorial esta muy bueno.
Comment by fhantastic — November 19, 2009 #
hola yo ya he realizadoun proyecto similar al de tu display que despliega los simbolos del 1 al f pero con unos retardos dados por un SWITCH es decir cuando tenemos 00 los muestra con un retardo de .1s cuando tenemos 01 retarda 1s cuando tenemos 10 lo hace en .5s y cuando tenemos 11 lo hace en 5s, mi pregunta es , como utiliso el timer para que cuando el SWITCH tenga 00 se retarde 1s, en 01 2s , en 10 5s y en 11 se tarde 10 segundos, la verdad es que me encuentro desesperado pues no entiendo como utilizarlo y me gustaria me ayudara
pd: anexo el codigo que use para lo descrito arriba y usop el pic 16f84a con el lenguaje ensamblador
; Programa que configura el puerto B como salida y A como entrada
; y convierte la entrada HEX a Salida 7 segmentos
; Declaracion y configuracion del procesador.
LIST P=16F84a
#include “p16f84a.inc” ; Titulo del procesador
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
org 0×00 ;Inicio del programa.
goto Main ;Brinca al inicio, Main.
org 0×04 ;Vector de interrupci¢n.
; ASIGNACION DE VARIABLES
cnt1 equ 0×0c ;Localidad de memoria para usar con el retardo
cnt2 equ 0×0d
cnt3 equ 0×0e
PTB equ 0×0f
; ESTA ES LA RUTINA QUE CONVIERTE A 7 SEGMENTOS
convierte
addwf PCL, 1
retlw b’00111111′ ;dato en siete segmentos “0″
retlw b’00000110′ ;dato en siete segmentos “1″
retlw b’01011011′ ;”2″
retlw b’01001111′ ;”3″
retlw b’01100110′ ;”4″
retlw b’01101101′ ;”5″
retlw b’01111101′ ;”6″
retlw b’00000111′ ;”7″
retlw b’01111111′ ;”8″
retlw b’01100111′ ;”9″
retlw b’01110111′ ;”A”
retlw b’01111100′ ;”b”
retlw b’00111001′ ;”C”
retlw b’01011110′ ;”d”
retlw b’01111001′ ;”E”
retlw b’01110001′ ;”F”
goto Main ;La rutina de atenci¢n a
;la interrupci¢n no existe.
;INICIO DEL PROGRAMA PRINCIPAL (INICIALIZAR PUERTOS)
Main
;inicializacion del puertos
bsf STATUS,RP0 ;Selecciona el banco de memoria 1.
;programacion para salidas a display
movlw b’00000000′ ;out-out-out-out-out-out-out-out
movwf TRISB ;INICIALIZA PUERTO B
;programacion para entradas de switch BCD
movlw b’11111111′ ;x-x-x-in-in-in-in-in
movwf TRISA ;INICIALIZA PUERTO A
bcf STATUS,RP0 ;Selecciona el banco de memoria 0.
;inicializa interrupciones
clrf INTCON ;deshabilita todas las interrupciones
;inicializa el puerto B
movlw 0×00
movwf PORTB ;Saca ceros por el puerto B.
; ESTA ES LA RUTINA PARA CARGAR EL NUMERO AL PORTB
Loop
movlw 0 ;LE CARGAMOS A W UN 0
call convierte ;LLAMAMOS A LA RUTINA CONVIERTE
movwf PTB ;MOVEMOS LO QUE HAY EN W A PTB=DIRECCION DE MEMORIA
movf PTB,PORTB ;MOVEMOS LO QUE HAY EN PTB HACIA EL PORTB
call LEERPORTA ;LLAMAMOS A LA RUTINA QUE LEE EL PUERTO A
movlw 1
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 2
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 3
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 4
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 5
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 6 ;lee del puerto A el dato a w
call convierte ;LLAMAMOS A LA RUTINA CONVIERTE
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 7
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 8
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 9
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 0×0A
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 0X0B
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 0X0C
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 0X0D
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 0X0E
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
movlw 0X0F
call convierte
movwf PTB
movf PTB,PORTB
call LEERPORTA
;ESTA ES LA RUTINA PARA LEER EL DATO DEL PUERTO A Y DECIDIR SU RETARDO
LEERPORTA
READA00 movlw 0 ;CARGA O EN W
subwf PORTA,0 ;HACE LA RESTA PORTA-W
btfss STATUS,Z ; BTFSS= SI EL BIT DEL REGISTRO ES 1 SE SALTA UNA INSTRUCCION
; Z=1 cuando la operacion logica es 0 (son iguales)
; z=0 cuando la operacion logica es 1 (son diferentes)
goto READA01 ; SI NO ES 0, LLAMA A LA OTRA SUBRUTINA READA01
goto Retardo00 ; COMO ES O EL RESULTADO SON IGUALES, ENTONCES LLAMA A LA SUBRUTINA DEL RETARDO ESPECIFICADO
READA01 movlw 1
subwf PORTA,0
btfss STATUS,Z
CALL READA10
goto Retardo01
READA10 movlw b’10′
subwf PORTA,0
btfss STATUS,Z
CALL READA11
goto Retardo10
READA11 movlw 3
subwf PORTA,0
btfss STATUS,Z
CALL READA01
goto Retardo11
Retardo00
movlw .110
movwf cnt1
PLoop1 movlw .181
movwf cnt2
PLoop2 decfsz cnt2, 1
goto PLoop2
decfsz cnt1, 1
goto PLoop1
return
Retardo01
movlw .239
movwf cnt1
PLoop11 movlw .232
movwf cnt2
PLoop22 decfsz cnt2, 1
goto PLoop22
decfsz cnt1, 1
goto PLoop11
return
Retardo10
movlw .14
movwf cnt1
PLoop00 movlw .72
movwf cnt2
PLoop111 movlw .247
movwf cnt3
PLoop222 decfsz cnt3,1
goto PLoop222
decfsz cnt2,1
goto PLoop111
decfsz cnt1,1
goto PLoop00
return
Retardo11
movlw .165
movwf cnt1
PLoop0000 movlw .41
movwf cnt2
PLoop1111 movlw .147
movwf cnt3
PLoop2222 decfsz cnt3,1
goto PLoop2222
decfsz cnt2, 1
goto PLoop1111
decfsz cnt1,1
goto PLoop0000
return
End ;Es necesario marcar el fin del programa
Comment by oscar — November 24, 2009 #