Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

27/11/2008 #1


De binario a decimal, , programa muy largo
Estoy haciendo un pequeño proyecto, tengo una aplicacion en mi celular donde simula un dipswith de 8 bits, y del otro lado un display, asi que te da en valor en decimal del valor binario que este en los pics, tengo el material, lo voy a hacer, claro, con un dip swith, 3 displays de esos normales creo que se llaman de 8 segmentos, asi que voy a ir checando el estado del dip y mostrar el valor del 0 al 256 en los display.

El problema es que por el metodo que lo estoy haciendo es demaciado largo, chequen mi codigo, solo hice una pequeña parte, pues se repetiria muchas veces, 256 checadas del dip y 256 para imprimir el numero en los display, me preguntaba si no hay otra forma de hacerlo:

Código:
INCLUDE P16F877A.INC
TIME EQU 0X21
DATO EQU 0X22
ORG OXOO
BSF STATUS,5
BCF STATUS,6
MOVLW B'11111111'
MOVWF TRISA
CLRF TRISB
CLRF TRISC
CLRF TRISD
MOVLW B'00000111'
MOVWF OPTION_REG
BCF STATUS,5

INICIO 	MOVF PORTA,W
		MOVWF DATO
		MOVLW B'00000000'
		SUBWF DATO,W
		BTFSC		STATUS,Z
		GOTO CERO
		MOVLW B'00000001'
		SUBWF		DATO,W
		BTFSC		STATUS,Z
		GOTO		UNO


UNO 
MOVLW B'00111111'
MOVWF PORTB
MOVLW B'00111111'
MOVWF PORTC
MOVLW B'00000110'
MOVWF PORTD
RETURN
Muchas gracias, supongo que debe de haber un algoritmo facil, pero no se me ocurre como.
27/11/2008 #2


Aqui tienes un algoritmo general para 32 bits.
Creo que te sea facil modificarlo si solo necesitas ocho bits


Código:
; Convert 32-bit binary number at <acc> into a bcd number
; at <bcd>. Uses Mike Keitz's procedure for handling bcd 
; adjust; Modified Microchip AN526 for 32-bits.

b2bcd	movlw	32		; 32-bits
	movwf	ii		; make cycle counter
	clrf	bcd		; clear result area
	clrf	bcd+1
	clrf	bcd+2
	clrf	bcd+3
	clrf	bcd+4
	
b2bcd2	movlw	bcd		; make pointer
	movwf	FSR
	movlw	5
	movwf	cnt

; Mike's routine:

b2bcd3	movlw	33h		
	addwf	0 		; add to both nybbles
	btfsc	0,3		; test if low result > 7
	andlw	0f0h		; low result >7 so take the 3 out
	btfsc	0,7		; test if high result > 7
	andlw	0fh		; high result > 7 so ok
	subwf	0 		; any results <= 7, subtract back
	incf	FSR 		; point to next
	decfsz	cnt
	goto	b2bcd3
	
	rlf	acc+0 		; get another bit
	rlf	acc+1 
	rlf	acc+2 
	rlf	acc+3 
	rlf	bcd+0 		; put it into bcd
	rlf	bcd+1 
	rlf	bcd+2 
	rlf	bcd+3 
	rlf	bcd+4 
	decfsz	ii 		; all done?
	goto	b2bcd2		; no, loop
	ret
27/11/2008 #3


mmm no le entiendo muy bien, no habra uno mas facil en un rato lo analizo con mas calma
28/11/2008 #4


No le entiendo muy bien, pero estuve pensando y logre obtener el valor que esta en el dipswith, es decir

que segun el valor del dip la w cambia

ejemplo

si tengo w=128 me dijo mi profesor que solo tenia que mandar a llamar una subrutina para cada display uno, dos y ocho, para no tener que formar todas las combinaciones.

PAra lo que necesito ayuda es para saber que numero esta en que posicion, osea como sabe el programa que tiene que llamar a prender el uno para el primer display, el dos para el segundo y el ocho para el tercero?

muchas gracias adelantadas
28/11/2008 #5


el programa lo que hace es convertir el numero binario a bcd natural y almacenarlo en uno o unos registros.

el bcd (o binary coded decimal) es una forma de representar un numero decimal del 0-9 en 4 bits (o un nibble).

0000 - 0
0001 - 1
0010 - 2
0011 - 3
0100 - 4
0101 - 5
0110 - 6
0111 - 7
1000 - 8
1001 - 9
1010 - 10 no se implementa
1011 - 11 no se implementa
1100 - 12 no se implementa
1101 - 13 no se implementa
1110 - 14 no se implementa
1111 - 15 no se implementa

vas a necesitar 1 nibble por cada digito del numero decimal, es decir que si queres representar el 255 (tu maximo numero a representar) vas a necesitar 3 nibbles. Uno para el 2, otro para el 5 y otro para el 5, quedando algo asi 0010 0101 0101 (2 5 5)

en esos registros del programa (creo porque lo lei muy por arriba el programa) estan guardados los bcds, en el nibble alto uno, y en el bajo otro.

salu2,
mano.
28/11/2008 #6

Avatar de pepechip

te creas tres registros: unidad, decenas y centenas.
Al numero binario le restas 10 y si el resultado el mayor de cero incrementas las decenas.
Si el numero resultante de la resta es mayor que 10, vuelves a repetir el paso anterior, creando un bucle.

Cuando las decenas llegen a 10 las pones a cero y incrementas las centenas.
Cuando al ir realizando las restas el numero binario sea inferior a 10 coges el numero resultante para las unidades.
28/11/2008 #7


mmm... como podre modificar el de 32 bits para pasar un numero binario de 24 bits a BCD? alguien sabe?

gracias,
mano.
28/11/2008 #8


mm gracias pepechip, creo que le voy entendiendo, pero no seria mucho pedir una prueba de escritorio, un ejemplo, no hay algun programa hecho que haga lo mismo?.

Les dejo lo que llevo al momento y me tarde un buen en pensarlo

Código:
INCLUDE P16F877A.INC
TIME EQU 0X21
DATO EQU 0X22
ORG OXOO
BSF STATUS,5
BCF STATUS,6
MOVLW B'11111111'
MOVWF TRISA
CLRF TRISB
CLRF TRISC
CLRF TRISD
MOVLW B'00000111'
MOVWF OPTION_REG
BCF STATUS,5 	

INICIO CLRW 
BTFSC PORTA,0
ADDLW .1
BTFSC PORTA,1
ADDLW .2
BTFSC PORTA,2
ADDLW .4
BTFSC PORTA,3
ADDLW .8
BTFSC PORTA,4
ADDLW .16
BTFSC PORTA,5
ADDLW .32
BTFSC PORTA,6
ADDLW .64
BTFSC PORTA,7
ADDLW .128
CALL IMPRIME
GOTO INICIO
28/11/2008 #9


no es mas facil mover el puerto a al registro w?

asi:

movf PORTA

entonces si todo esta en 1 vas a tener W = 11111111 que resulta ser 255

de todos modos te paso una libreria del libro PIC16F84A: Desarrollo de Proyectos, de la editorial Ra-Ma.


Código:
;******************************** Librería "BIN_BCD.INC" ********************************
;
;	===================================================================
;	  Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;	  E. Palacios, F. Remiro y L. López.		www.pic16f84a.com
; 	  Editorial Ra-Ma.  www.ra-ma.es
;	===================================================================
;
; Un número binario natural de 8 bits es convertido a BCD. El resultado se guarda en tres
; posiciones de memorias llamadas: BCD_Centenas, BCD_Decenas y BCD_Unidades.
;
; El procedimiento utilizado es mediante restas de 10, tal como se explicó en el capítulo 9.
;
; Entrada:	En el registro W el número binario natural a convertir.
; Salidas:	En (BCD_Centenas), (BCD_Decenas) y (BCD_Unidades).
;			En el registro W también las decenas (nibble alto) y unidades (nibble bajo).

; Subrutina "BIN_a_BCD" -----------------------------------------------------------------

	CBLOCK						; En las subrutinas no se debe fijar la dirección
	BCD_Centenas				; de la RAM de usuario. Se toma a continuación de
	BCD_Decenas					; la última asignada.
	BCD_Unidades	
	ENDC
;
BIN_a_BCD
	clrf	BCD_Centenas		; Carga los registros con el resultado inicial.
	clrf	BCD_Decenas			; En principio las centenas y decenas a cero.
	movwf	BCD_Unidades		; Se carga el número binario a convertir.
BCD_Resta10
	movlw	.10					; A las unidades se les va restando 10 en cada
	subwf	BCD_Unidades,W		; pasada. (W)=(BCD_Unidades) -10.
	btfss	STATUS,C			; ¿C = 1?, ¿(W) positivo?, ¿(BCD_Unidades)>=10?
	goto 	BIN_BCD_Fin			; No, es menor de 10. Se acabó.
BCD_IncrementaDecenas
	movwf	BCD_Unidades		; Recupera lo que queda por restar.
	incf	BCD_Decenas,F		; Incrementa las decenas y comprueba si ha llegado
	movlw	.10					; a 10. Lo hace mediante una resta.
	subwf	BCD_Decenas,W		; (W)=(BCD_Decenas)-10).
	btfss	STATUS,C			; ¿C = 1?, ¿(W) positivo?, ¿(BCD_Decenas)>=10?
	goto	BCD_Resta10			; No. Vuelve a dar otra pasada, restándole 10 a
BCD_IncrementaCentenas			; las unidades.
	clrf	BCD_Decenas			; Pone a cero las decenas 
	incf	BCD_Centenas,F		; e incrementa las centenas.
	goto	BCD_Resta10			; Otra pasada: Resta 10 al número a convertir.
BIN_BCD_Fin
	swapf	BCD_Decenas,W		; En el nibble alto de (W) también las decenas.
	addwf	BCD_Unidades,W		; En el nibble bajo de (W) las unidades.
	return						; Vuelve al programa principal.
	
; La directiva "END" se debe poner en el programa principal no aquí.

;	===================================================================
;	  Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
;	  E. Palacios, F. Remiro y L. López.		www.pic16f84a.com
; 	  Editorial Ra-Ma.  www.ra-ma.es
;	===================================================================
salu2,
mano.
28/11/2008 #10


Osea que en (BCD_Centenas), (BCD_Decenas) y (BCD_Unidades) voy a tener al final de la subrutina, ejemplo:

w=11111111

BCD_Centenas = 2
BCD_Decenas = 5
BCD_Unidades = 5

en binario o mas bien como me dijiste?:

BCD_Centenas = 0010
BCD_Decenas = 0101
BCD_Unidades = 0101
28/11/2008 #11


correcto...

vos moves al registro w un byte, cual fuera, y haces un llamado a la subrutina

call BIN_a_BCD

y vas a tener el resultado en esos tres registros.

el programa ese o lo pegas al tuyo o simplemente pones al principio o al final del programa:

INCLUDE <BIN_BCD.INC>

espero que te haya sido de utilidad.
29/11/2008 #12


Muchas gracias, segun yo mi programa quedaria asi, si un alma bondadosa podria checarmelo y decirme si esta bien o por que falle para modificarlo, muchas gracias, ayudan mucho aqui, cuando este el proyectito subo un video para que vean como quedo:

Código:
INCLUDE P16F877A.INC

CENTENAS EQU 0X21
DECENAS EQU 0X22
UNIDADES EQU 0X23

ORG 0X00
BSF STATUS,5
BCF STATUS,6
MOVLW B'11111111'
MOVWF TRISA
CLRF TRISB
CLRF TRISC
CLRF TRISD
MOVLW B'00000111'
MOVWF OPTION_REG
BCF STATUS,5 	

INICIO MOVF PORTA,W
CALL BIN_a_BCD 
CALL IMPRIMIRCENTENAS
MOVWF PORTB
CALL IMPRIMIRDECENAS
MOVWF PORTC
CALL IMPRIMIRUNIDAD
MOVWF PORTD
GOTO INICIO




BIN_a_BCD
CLRF CENTENAS 
CLRF DECENAS 
MOVWF UNIDADES 
BCD_RESTA10
MOVLW .10 
subwf UNIDADES,W 
BTFSS STATUS,C 
GOTO BIN_BCD_FIN 
BCD_IINCREMENTADECENAS
MOVWF UNIDADES 
INCF DECENAS,F 
MOVLW .10 
SUBWF DECENAS,W 
BTFSS STATUS,C 
GOTO BCD_RESTA10 
BCD_INCREMENTACENTENAS 
CLRF DECENAS 
INCF CENTENAS,F 
GOTO BCD_RESTA10 
BIN_BCD_FIN
SWAPF DECENAS,W 
ADDWF UNIDADES,W 
RETURN


IMPRIMIRCENTENAS
MOVLW B'0000'
SUBWF CENTENAS,W
BTFSS STATUS,Z
GOTO OPCION2
CALL CERO
OPCION2 MOVLW B'0001'
SUBWF CENTENAS,W
BTFSS STATUS,Z
GOTO OPCION3
CALL UNO
OPCION3 MOVLW B'0010'
SUBWF CENTENAS,W
BTFSS STATUS,Z
GOTO OPCION4
CALL DOS
OPCION4 MOVLW B'0011'
SUBWF CENTENAS,W
BTFSS STATUS,Z
GOTO OPCION5
CALL TRES
OPCION5 MOVLW B'0100'
SUBWF CENTENAS,W
BTFSS STATUS,Z
GOTO OPCION6
CALL CUATRO
OPCION6 MOVLW B'0101'
SUBWF CENTENAS,W
BTFSS STATUS,Z
GOTO OPCION7
CALL CINCO
OPCION7 MOVLW B'0110'
SUBWF CENTENAS,W
BTFSS STATUS,Z
GOTO OPCION8
CALL SEIS
OPCION8 MOVLW B'0111'
SUBWF CENTENAS,W
BTFSS STATUS,Z
GOTO OPCION9
CALL SIETE
OPCION9 MOVLW B'1000'
SUBWF CENTENAS,W
BTFSS STATUS,Z
GOTO OPCION10
CALL OCHO
OPCION10 MOVLW B'1001'
SUBWF CENTENAS,W
BTFSS STATUS,Z
GOTO INICIO
CALL NUEVE
RETURN

IMPRIMIRDECENAS
MOVLW B'0000'
SUBWF DECENAS,W
BTFSS STATUS,Z
GOTO OPCION2
CALL CERO
OPCION2D MOVLW B'0001'
SUBWF DECENAS,W
BTFSS STATUS,Z
GOTO OPCION3D
CALL UNO
OPCION3D MOVLW B'0010'
SUBWF DECENAS,W
BTFSS STATUS,Z
GOTO OPCION4D
CALL DOS
OPCION4D MOVLW B'0011'
SUBWF DECENAS,W
BTFSS STATUS,Z
GOTO OPCION5
CALL TRES
OPCION5D MOVLW B'0100'
SUBWF DECENAS,W
BTFSS STATUS,Z
GOTO OPCION6D
CALL CUATRO
OPCION6D MOVLW B'0101'
SUBWF DECENAS,W
BTFSS STATUS,Z
GOTO OPCION7D
CALL CINCO
OPCION7D MOVLW B'0110'
SUBWF DECENAS,W
BTFSS STATUS,Z
GOTO OPCION8
CALL SEIS
OPCION8D MOVLW B'0111'
SUBWF DECENAS,W
BTFSS STATUS,Z
GOTO OPCION9D
CALL SIETE
OPCION9D MOVLW B'1000'
SUBWF DECENAS,W
BTFSS STATUS,Z
GOTO OPCION10D
CALL OCHO
OPCION10D MOVLW B'1001'
SUBWF DECENAS,W
BTFSS STATUS,Z
GOTO INICIO
CALL NUEVE
RETURN

IMPRIMIRUNIDAD
MOVLW B'0000'
SUBWF UNIDADES,W
BTFSS STATUS,Z
GOTO OPCION2U
CALL CERO
OPCION2U MOVLW B'0001'
SUBWF UNIDADES,W
BTFSS STATUS,Z
GOTO OPCION3U
CALL UNO
OPCION3U MOVLW B'0010'
SUBWF UNIDADES,W
BTFSS STATUS,Z
GOTO OPCION4U
CALL DOS
OPCION4U MOVLW B'0011'
SUBWF UNIDADES,W
BTFSS STATUS,Z
GOTO OPCION5U
CALL TRES
OPCION5U MOVLW B'0100'
SUBWF UNIDADES,W
BTFSS STATUS,Z
GOTO OPCION6U
CALL CUATRO
OPCION6U MOVLW B'0101'
SUBWF UNIDADES,W
BTFSS STATUS,Z
GOTO OPCION7U
CALL CINCO
OPCION7U MOVLW B'0110'
SUBWF UNIDADES,W
BTFSS STATUS,Z
GOTO OPCION8U
CALL SEIS
OPCION8U MOVLW B'0111'
SUBWF UNIDADES,W
BTFSS STATUS,Z
GOTO OPCION9U
CALL SIETE
OPCION9U MOVLW B'1000'
SUBWF UNIDADES,W
BTFSS STATUS,Z
GOTO OPCION10U
CALL OCHO
OPCION10U MOVLW B'1001'
SUBWF UNIDADES,W
BTFSS STATUS,Z
GOTO INICIO
CALL NUEVE
RETURN

CERO MOVLW B'00111111'
RETURN
UNO MOVLW B'00000110'
RETURN
DOS MOVLW B'01011011'
RETURN
TRES MOVLW B'01001111'
RETURN
CUATRO MOVLW B'01100110'
RETURN
CINCO MOVLW B'01101101'
RETURN
SEIS MOVLW B'01111101'
RETURN
SIETE MOVLW B'00000111'
RETURN
OCHO MOVLW B'00000000'
RETURN
NUEVE MOVLW B'01101111'
RETURN

END
29/11/2008 #14


miraa, en un principio esta bien, pero que e slo qe tenes qe hacer? representar un numero en un display de leds? si es eso, directamente tenes que sacar por los puertos, el codigo BCD que te da la subrutina para meterlo adentro d un deco BCD-7segmentos.

ahora si lo qe qeres hacer es conectar el display directamente a los puertos esta bien! es mas, en vez de dejar ese codigo dentro de tu programa principal, podrias ponerlo dentro de otro programa y llamarlo BCD_a_7segmentos.

se me ocurre que podrias hacerlo de una forma MUCHO mas simple... con salto indexado.

salu2,
mano.
29/11/2008 #15


muchas gracias, creo que ya di con el resultado, si me funciona les enseño
29/11/2008 #16

Avatar de asherar

Le puse un poco de nafta a la motoneta, y salí a recorrer tu extenso código.
Entre otras cosas ví que para acortarlo podrías usar la estructura de tabla para
acceder a los numeros binarios que tienes al final.
Esto se logra haciendo como se muestra en el ejemplo:
Código:
Ejemplo: 

  ORG 0
  GOTO INICIO

  ORG 5
NUMEROS addwf	PCL,F
	retlw	B'00111111'	; 0
	retlw	B'00000110'	; 1
	retlw	B'01011011'	; 2
	retlw	... etc. hasta 9

INICIO

(cuerpo del programa)

   MOVLW   1  ; Asigno el índice de la tabla W <- 1 
   CALL NUMEROS  ; Me devuelve el valor NUMEROS(1) = B'00000110' en W
   ...
END
Otra forma de hacer lo mismo es usando la directiva DT (Data Table) en la cabecera del código.
Se empieza con el rótulo del nombre de la tabla, se sigue con el elemento "cero", etc. , y se termina
con "0". Todo separado por comas.
Te recomiendo ver el tutorial que viene en el "Ayuda" del MPLAB.
13/07/2009 #17

Avatar de dragondgold

Código:
;******************************** Librería "BIN_BCD.INC" ********************************
    ;
    ; ===================================================================
    ; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
    ; E. Palacios, F. Remiro y L. López. www.pic16f84a.com
    ; Editorial Ra-Ma. www.ra-ma.es
    ; ===================================================================
    ;
    ; Un número binario natural de 8 bits es convertido a BCD. El resultado se guarda en tres
    ; posiciones de memorias llamadas: BCD_Centenas, BCD_Decenas y BCD_Unidades.
    ;
    ; El procedimiento utilizado es mediante restas de 10, tal como se explicó en el capítulo 9.
    ;
    ; Entrada: En el registro W el número binario natural a convertir.
    ; Salidas: En (BCD_Centenas), (BCD_Decenas) y (BCD_Unidades).
    ; En el registro W también las decenas (nibble alto) y unidades (nibble bajo).

    ; Subrutina "BIN_a_BCD" -----------------------------------------------------------------

    CBLOCK ; En las subrutinas no se debe fijar la dirección
    BCD_Centenas ; de la RAM de usuario. Se toma a continuación de
    BCD_Decenas ; la última asignada.
    BCD_Unidades
    ENDC
    ;
    BIN_a_BCD
    clrf BCD_Centenas ; Carga los registros con el resultado inicial.
    clrf BCD_Decenas ; En principio las centenas y decenas a cero.
    movwf BCD_Unidades ; Se carga el número binario a convertir.
    BCD_Resta10
    movlw .10 ; A las unidades se les va restando 10 en cada
    subwf BCD_Unidades,W ; pasada. (W)=(BCD_Unidades) -10.
    btfss STATUS,C ; ¿C = 1?, ¿(W) positivo?, ¿(BCD_Unidades)>=10?
    goto BIN_BCD_Fin ; No, es menor de 10. Se acabó.
    BCD_IncrementaDecenas
    movwf BCD_Unidades ; Recupera lo que queda por restar.
    incf BCD_Decenas,F ; Incrementa las decenas y comprueba si ha llegado
    movlw .10 ; a 10. Lo hace mediante una resta.
    subwf BCD_Decenas,W ; (W)=(BCD_Decenas)-10).
    btfss STATUS,C ; ¿C = 1?, ¿(W) positivo?, ¿(BCD_Decenas)>=10?
    goto BCD_Resta10 ; No. Vuelve a dar otra pasada, restándole 10 a
    BCD_IncrementaCentenas ; las unidades.
    clrf BCD_Decenas ; Pone a cero las decenas
    incf BCD_Centenas,F ; e incrementa las centenas.
    goto BCD_Resta10 ; Otra pasada: Resta 10 al número a convertir.
    BIN_BCD_Fin
    swapf BCD_Decenas,W ; En el nibble alto de (W) también las decenas.
    addwf BCD_Unidades,W ; En el nibble bajo de (W) las unidades.
    return ; Vuelve al programa principal.

    ; La directiva "END" se debe poner en el programa principal no aquí.

    ; ===================================================================
    ; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"
    ; E. Palacios, F. Remiro y L. López. www.pic16f84a.com
    ; Editorial Ra-Ma. www.ra-ma.es
    ; ===================================================================
como podria adaptar este programa para convertir 10 bits binarios a bcd?
13/07/2009 #18
Moderador

Avatar de Vick

dragondgold dijo:
como podria adaptar este programa para convertir 10 bits binarios a bcd?
Busca en las notas de aplicación en la página de Microchip ahí hay una librería para pasar de binario a BCD de 16 bits creo que es la AN526...

Suerte.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.