Decodificador Binario a Hexadecimal con PIC16F887

#1
Hola que tal, soy nuevo en el foro y quisiera que me ayudaran para encontrar las fallas que tengo en éste proyecto. Estoy programando un decodificador binario-hexadecimal con el PIC16F887, es la primera vez que programo con este PIC, y el problema que tengo es que al implementarlo en el protoboard no funciona, ya lo simulé con la ayuda de PROTEUS y aparentemente todo funciona bien. El PIC debe recibir 8 bits, 4 en el puerto A y 4 en el puerto B, y desplegar el dígito hexadecimal correspondiente en los puertos C y D en display's de 7 segmentos.
alguien sabe qué estoy haciendo mal? Saludos y gracias.
PHP:
				INCLUDE 	P16F887.INC
				__CONFIG	_CONFIG1,_INTOSCIO&_WDT_OFF&_PWRTE_ON&_MCLRE_ON&_CP_OFF&_DEBUG_OFF&_LVP_OFF
			 	__CONFIG	_CONFIG2,_WRT_OFF 

				ORG			0x00

				BSF			STATUS,RP0				; activa el banco 1
				
				CLRF		PORTA

				MOVLW		0x0FF					; carga 0x0FF en W
				MOVWF		TRISA					; puerto A, entradas
				CLRF		TRISC					; puerto C todas salidas
				
				MOVLW		0x0FF					; carga 0x0FF en W
				MOVWF		TRISB					; puerto B, entradas
				CLRF		TRISD					; puerto D todas salidas

				BSF			STATUS,RP1
												
				CLRF		ANSEL
				CLRF		ANSELH
				
				BCF			STATUS,RP1
				BCF			STATUS,RP0				; volvemos al banco 0
				
INICIO												; etiqueta
			
				MOVF		PORTA,W					; lee el puerto A, y lo guarda en W
				CALL		TABLA					; llamamos a TABLA
				MOVWF		PORTC					; cargamos W en el puerto B

				MOVF		PORTB,W					; lee el puerto A, y lo guarda en W
				CALL		TABLA					; llamamos a TABLA
				MOVWF		PORTD					; cargamos W en el puerto B
							
				GOTO		INICIO					; va a INICIO
				
TABLA

				ADDWF		PCL,F					; suma w (valor puerto A) con el valor de PCL
													
				RETLW		b'00111111'				; 0, carga b'1111110' en W y retorna
				RETLW		b'00000110'				; 1, carga b'0110000' en W y retorna
				RETLW		b'01011011'				; 2, carga b'1101101' en W y retorna
				RETLW		b'01001111'				; 3, carga b'1111001' en W y retorna
				RETLW		b'01100110'				; 4, carga b'0110011' en W y retorna
				RETLW		b'01101101'				; 5, carga b'1011011' en W y retorna
				RETLW		b'01111101'				; 6, carga b'1011111' en W y retorna
				RETLW		b'00000111'				; 7, carga b'1110000' en W y retorna
				RETLW		b'01111111'				; 8, carga b'1111111' en W y retorna
				RETLW		b'01101111'				; 9, carga b'1111011' en W y retorna
				RETLW		b'01110111'				; A, carga b'1110111' en W y retorna
				RETLW		b'01111100'				; b, carga b'0011111' en W y retorna
				RETLW		b'00111001'				; C, carga b'1001110' en W y retorna
				RETLW		b'01011110'				; d, carga b'0111101' en W y retorna
				RETLW		b'01111001'				; E, carga b'1001111' en W y retorna
				RETLW		b'01110001'				; F, carga b'1001111' en W y retorna
				RETURN
			
				END
 

Adjuntos

#2
Hola agzaldivar, veo varias mejoras que podrías hacerle a tú programa, y creo que dentro de estas mejoras está la solución:

Primero poner como salida los pines del micro que no usas, esto evita que al trabajar como entradas el micro sea más propicio a las interferencias

Segundo, definir la dirección de arranque (ya lo haz hecho) y la dirección de interrupciones.

Tercero, desabilitar las interrupciones.

Cuarto, iniciar seleccionando banco 0 y borrando los registros correspondientes

Las tablas siempre van primero que el resto del programa.

En definitiva, elprograma quedaría algo así:

PHP:
				INCLUDE 	P16F887.INC
				__CONFIG	_INTOSCIO&_WDT_OFF&_PWRTE_ON&_MCLRE_ON&_CP_OFF&_DEBUG_OFF&_LVP_OFF&_WRT_OFF 

				ORG		0x00
				GOTO		INICIO

				ORG		0x04
				CLRF		INTCON
				RETURN

TABLA
				ADDWF	PCL,F			; suma w (valor puerto A) con el valor de PCL									
				RETLW	b'00111111'		; 0, carga b'1111110' en W y retorna
				RETLW	b'00000110'		; 1, carga b'0110000' en W y retorna
				RETLW	b'01011011'		; 2, carga b'1101101' en W y retorna
				RETLW	b'01001111'		; 3, carga b'1111001' en W y retorna
				RETLW	b'01100110'		; 4, carga b'0110011' en W y retorna
				RETLW	b'01101101'		; 5, carga b'1011011' en W y retorna
				RETLW	b'01111101'		; 6, carga b'1011111' en W y retorna
				RETLW	b'00000111'		; 7, carga b'1110000' en W y retorna
				RETLW	b'01111111'		; 8, carga b'1111111' en W y retorna
				RETLW	b'01101111'		; 9, carga b'1111011' en W y retorna
				RETLW	b'01110111'		; A, carga b'1110111' en W y retorna
				RETLW	b'01111100'		; b, carga b'0011111' en W y retorna
				RETLW	b'00111001'		; C, carga b'1001110' en W y retorna
				RETLW	b'01011110'		; d, carga b'0111101' en W y retorna
				RETLW	b'01111001'		; E, carga b'1001111' en W y retorna
				RETLW	b'01110001'		; F, carga b'1001111' en W y retorna
				RETURN

INICIO
				BCF		STATUS,RP1				; activa el banco 0
				BCF		STATUS,RP0
				CLRF		INTCON
				CLRF		PORTA
				CLRF		PORTB
				CLRF		PORTC
				CLRF		PORTD
				CLRF		PORTE

				BSF		STATUS,RP0				; activa el banco 2
				BSF		STATUS,RP1
				CLRF		ANSEL
				CLRF		ANSELH

				BSF		STATUS,RP0				; activa el banco 1
				BCF		STATUS,RP1
				
				MOVLW	0x00F					; carga 0x0FF en W
				MOVWF	TRISA				; puerto A, entradas
				MOVLW	0x00F					; carga 0x0FF en W
				MOVWF	TRISB					; puerto B, entradas
				CLRF		TRISC				; puerto C todas salidas
				CLRF		TRISD				; puerto D todas salidas
				CLRF		TRISE					; puerto E todas salidas

				BCF		STATUS,RP1			; activa el banco 0
				BCF		STATUS,RP0
				
PROGRAMA										; etiqueta
				MOVF		PORTA,W				; lee el puerto A, y lo guarda en W
				CALL		TABLA				; llamamos a TABLA
				MOVWF	PORTC				; cargamos W en el puerto B
				MOVF		PORTB,W				; lee el puerto A, y lo guarda en W
				CALL		TABLA				; llamamos a TABLA
				MOVWF	PORTD				; cargamos W en el puerto B
				GOTO		PROGRAMA				; va a INICIO
				
				END
Un saludo.

Atte. CARLOS.
 
Última edición:
#3
Hola Carlos, muchas gracias por tu tiempo y ayuda, de lo que me respondiste solo modifiqué la tabla, pues la lee de la F al 0, y ya funciona bien el puerto A y C, ahora el problema radica en obtener lo que le introduzco por el puerto B en el puerto D; pues como estado inicial debería mostrarme un "0" y me muestra un "9".
Espero puedas ayudarme o si alguien sabe que puedo hacer, le agradeceré mucho. Saludos!

PHP:
				INCLUDE     P16F887.INC
                __CONFIG    _CONFIG1,_INTOSCIO&_WDT_OFF&_PWRTE_ON&_MCLRE_ON&_CP_OFF&_DEBUG_OFF&_LVP_OFF 
                __CONFIG    _CONFIG2,_WRT_OFF

                ORG        	0x00
                GOTO        INICIO
                ORG        	0x04
				CLRF        INTCON

                RETURN

TABLA
                ADDWF    	PCL,F            		; suma w (valor puerto A) con el valor de PCL                                    
                
                RETLW    	b'01110001'        		; F, carga b'1001111' en W y retorna
                RETLW   	b'01111001'        		; E, carga b'1001111' en W y retorna
                RETLW   	b'01011110'       		; d, carga b'0111101' en W y retorna
                RETLW   	b'00111001'       		; C, carga b'1001110' en W y retorna
                RETLW  	b'01111100'      		; b, carga b'0011111' en W y retorna
                RETLW   	b'01110111'        		; A, carga b'1110111' en W y retorna
                RETLW 	b'01101111'        		; 9, carga b'1111011' en W y retorna
                RETLW 	b'01111111'        		; 8, carga b'1111111' en W y retorna
                RETLW  	b'00000111'        		; 7, carga b'1110000' en W y retorna
                RETLW    	b'01111101'        		; 6, carga b'1011111' en W y retorna
                RETLW   	b'01101101'        		; 5, carga b'1011011' en W y retorna
                RETLW       b'01100110'        		; 4, carga b'0110011' en W y retorna
                RETLW    	b'01001111'        		; 3, carga b'1111001' en W y retorna
                RETLW    	b'01011011'        		; 2, carga b'1101101' en W y retorna
                RETLW    	b'00000110'       		; 1, carga b'0110000' en W y retorna
				RETLW    	b'00111111'        		; 0, carga b'1111110' en W y retorna
	
                RETURN

INICIO
                BCF         STATUS,RP1              ; activa el banco 0
                BCF         STATUS,RP0
                CLRF        INTCON
                CLRF        PORTA
                CLRF        PORTB
                CLRF        PORTC
                CLRF        PORTD
                CLRF        PORTE

                BSF         STATUS,RP0              ; activa el banco 2
                BSF         STATUS,RP1
                CLRF        ANSEL
                CLRF        ANSELH

                BSF        	STATUS,RP0              ; activa el banco 1
                BCF        	STATUS,RP1
                
                MOVLW    	0x00F                   ; carga 0x00F en W
                MOVWF    	TRISA                	; puerto A, entradas
                MOVLW    	0x00F                  	; carga 0x00F en W
                MOVWF    	TRISB                   ; puerto B, entradas
                CLRF        TRISC                	; puerto C todas salidas
                CLRF        TRISD                	; puerto D todas salidas
                CLRF        TRISE                   ; puerto E todas salidas

                BCF        	STATUS,RP1            	; activa el banco 0
                BCF       	STATUS,RP0
                
PROGRAMA                                        	; etiqueta
                MOVF        PORTA,W                	; lee el puerto A, y lo guarda en W
                CALL        TABLA                	; llamamos a TABLA
                MOVWF    	PORTC                	; cargamos W en el puerto B
                
				MOVF        PORTB,W                	; lee el puerto A, y lo guarda en W
                CALL        TABLA               	; llamamos a TABLA
                MOVWF    	PORTD                	; cargamos W en el puerto B
                
				GOTO        PROGRAMA                ; va a INICIO
                
                END
 
#4
Hola agzaldivar, con respecto a lo siguiente:

Hola Carlos, muchas gracias por tu tiempo y ayuda, de lo que me respondiste solo modifiqué la tabla, pues la lee de la F al 0, y ya funciona bien el puerto A y C, ahora el problema radica en obtener lo que le introduzco por el puerto B en el puerto D; pues como estado inicial debería mostrarme un "0" y me muestra un "9".
Espero puedas ayudarme o si alguien sabe que puedo hacer, le agradeceré mucho. Saludos!
Si miras bien el programa que yo te e colocado... verás que no solo modifiqué el lugar de la tabla. Hice mucho más que eso, como por ejemplo configurar los puertos en distinto orden al que tú as usado, no parece mucho, pero en ocasiones si no lo haces en un orden muy específico los puertos no se configuran correctamente. Esto anterior, más allá de que los configuré de manera muy distinta a la tuya....

Yo creo que deberías leer y estudiar muy bien el orden y lo que e hecho en el programa que te e pasado, y si tienes el datasheet del micro a mano y sabes leerlo, pues mucho mejor.

Saliendo del tema del programa, por lo que yo veo, las entradas son del tipo normal altas, por lo que con los 4 bits en HI la salida se coloca en "0". Ahora la pregunta ¿Estas usando las pertinentes resistencias de pull-up conectadas a los 5Vcc?

Los foros no son solo para "pedir" que a uno le hagan o le solucionen las cosas, son para aprender, esta es la idea principal de un foro, y esto lo digo sin ánimos de ofender a nadie, por lo que analiza lo que ya tienes y trata de comprender lo que no funciona y ahí si puedes preguntar el porque de algo que no funciona indicando los pasos que has seguido.

Ya comento, esto es sin interés de ofender. Se nota que eres principiante con esto de los micros, porque si ya as programado cualquier micro de la línea 16F puedes notar que salvo alguna configuración distinta para los periféricos, el resto es todo igual. Sabiendo esto con gusto te ayudaré a que aprendas. Pero la solución no la tendrás en bandeja...

Espero no ofender a nadie, y si así es le pido disculpas.

Un saludo.

Atte. CARLOS.
 
#5
Hola Carlos, agradezco tu interés y ayuda, respecto a lo que comentas de esperar la solución en bandeja, pues no, he leído el datasheet, aunque no todo,pero si referente al PuertoA y B y su configuración, y pues según lo que entendí y con la ayuda que me proporcionaste modificando el código, ya debería funcionar.
Respecto a los cambios que le hiciste, los revisé y noté que no solo consiste en cambiar de lugar la tabla, noté que por ejemplo, el registro INTCON lo limpias dos veces, y antes de configurar los puertos como salidas también los limpias, etc... y como tu mencionas, soy nuevo en este mundo de los microcontroladores, solo he programado el 16F84A y el 16F628A, pero ambos con los típicos programas de enciende un led y lee el PuertoA y muéstralo con LED's en el PuertoB.
En cuanto a las resistencias pull-up, deben ser de algún valor en específico? tengo conectadas unas de 10KΩ y a Vcc, tal como lo puse en la simulación, son las que me dijo mi profesora =p.
Y no me ofendo, y ofrezco una disculpa si me expresé mal y di a entender cosas diferentes, pero no trato de obtener la solución tal cual a mi problema, si no una orientación que me lleve a ella.
Por último respecto al programa, he probado sacando por el puerto C y D, simultáneamente, lo que leo en el puerto A, pero solo se muestra correctamente en el PuertoC, ya revisé el cableado y cambié 2 veces de protoboard y sigue sin funcionar correctamente esa parte. me muestra como estado inicial un "9", en el PuertoD, en vez de 0.
ya revisé el datasheet y no encuentro como configurar el puerto D, por que asumo que es el puertoD el que está mal configurado pues no muestra correctamente la salida, o será que está dañado ese puerto? Seguiré revisando esto y nuevamente ofrezco una disculpa si no me expresé correctamente, pero mi intención es aprender, no buscar que me resuelvan las cosas.

Saludos y gracias! :)
 
#6
Hola Carlos, he encontrado el error al último problema, un falso contacto en el protoboard estaba ocasionando que mostrara cosas raras en el puertoD, te agradezco todo tu apoyo y ayuda, así como a los demás que se molestaron en visitar este post. Gracias y para la próxima espero poder aportar algo.
Saludos!
 
Última edición:
#7
Hola agzaldivar:

Hola Carlos, he encontrado el error al último problema, un falso contacto en el protoboard estaba ocasionando que mostrara cosas raras en el puertoD, te agradezco todo tu apoyo y ayuda, así como a los demás que se molestaron en visitar este post. Gracias y para la próxima espero poder aportar algo.
Saludos!
Me alegra que tú realmente desees aprender y ahora eso se nota, en este foro soy un simple usuario como tú, pero en otro foro soy moderador global desde hace muchos años y te aseguro que estoy cansado de ver gente que quiere que le "hagan las cosas", este es el motivo de mi comentario anterior, no creo que haga falta que pidas disculpas, ya con tu actitud y el resolver tú mismo el problema demostraste más que suficiente voluntad y ganas de aprender.

Me alegra muchísimo que allas encontrado el problema y lo solucionaras, bien por tí.

Las resistencias, tanto las de pull-up o las de pull-down pueden tener un valor entre 1K y 47K sin ningún tipo de problemas, tal como lo mencionas tú el valor de 10K es el más "standard"

Me olvide de comentarte antes, pero hay un IC (no me acuerdo bien si de familia CMOS o TTL) que hace exactamente lo que estas haciendo con el PIC, pero claro en este caso no se aprende la programación de un micro :)

Bueno, felicidades y mucho éxito.

Un saludo.

Atte. CARLOS.
 
Arriba