TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: halowin en 27 de Diciembre de 2011, 15:08:39
-
Hola a todos.
Posiblemente haya ya en el "Almacen" alguna subrutina parecida, pero bueno la he hecho por cacharrear un poco y probarla.
Se trata de sacar por la LCD el numero contenido en el acumulador, pero en decimal. He ojeado la que viene en la libreria LCD_4BIT.INC pero saca el numero en hexadecimal y no me gustaba.
La subrutina en si es esta:
;---------subrutina de converion a decimal
CBLOCK
VAR1
ORIGINAL
CENTENAS
DECENAS
UNIDADES
ENDC
LCD_Dec
CLRF CENTENAS
CLRF DECENAS
CLRF UNIDADES
MOVWF VAR1
MOVWF ORIGINAL
ANALIZA_CENTENAS
MOVLW .100
SUBWF VAR1,1
BTFSC STATUS,0
GOTO INCREMENTA_CENTENAS
GOTO ANALIZA_DECENAS
INCREMENTA_CENTENAS
INCF CENTENAS
GOTO ANALIZA_CENTENAS
ANALIZA_DECENAS
MOVLW .100 ;le sumo los ultimos 100 restados
ADDWF VAR1,1 ;y en VAR1 me queda el resto
OTRA
MOVLW .10
SUBWF VAR1,1
BTFSC STATUS,0
GOTO INCREMENTA_DECENAS
GOTO ANALIZA_UNIDADES
INCREMENTA_DECENAS
INCF DECENAS
GOTO OTRA
ANALIZA_UNIDADES
MOVLW .10 ;le sumo las ultimas 10 restadas
ADDWF VAR1,1 ;y en VAR1 me queda el resto (las unidades)
MOVF VAR1,0
MOVWF UNIDADES
;devuelvo el WREG a su valor original
MOVF ORIGINAL,0
RETURN
Y para probarla en la realidad (no simulacion) he hecho este pequeño programa que podeis probar rapidamente:
; Contador en Decimal
;con salida a la LCD
LIST P=16F84A
INCLUDE <P16F84A.INC>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
CBLOCK 0x0C
PDel0
PDel1
dato
ENDC
; ZONA DE CÓDIGOS *******************
ORG 0
Inicio
call LCD_Inicializa
movlw MensajeFijo ; Apunta al mensaje fijo y lo visualiza.
call LCD_Mensaje
movlw 0
movwf dato
bucle
movlw 7 ;se situa despues de Cuenta=
call LCD_PosicionLinea1
movf dato,0
call LCD_Dec ;llamo a la subrutina de conversion
movf CENTENAS,0
call LCD_Byte ;Completo, no me gusta como lo espacia
movf DECENAS,0
call LCD_Byte
movf UNIDADES,0
call LCD_Byte
incf dato,0
movwf dato
call DEMORA
goto bucle
Mensajes
addwf PCL,F
MensajeFijo
DT "Cuenta=", 0x00;
INCLUDE <LCD_4BIT.INC>
INCLUDE <LCD_MENS.INC>
INCLUDE <RETARDOS.INC>
;END
;-------------------------------------------------------------
; Generado con PDEL
; Descripcion: Delay 500000 ciclos
;-------------------------------------------------------------
DEMORA
movlw .239 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop1 movlw .232 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 goto PDelL3 ; 2 ciclos delay
PDelL3 clrwdt ; 1 ciclo delay
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL4 goto PDelL5 ; 2 ciclos delay
PDelL5 goto PDelL6 ; 2 ciclos delay
PDelL6 goto PDelL7 ; 2 ciclos delay
PDelL7 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;-------------------------------------------------------------
;---------subrutina de converion a decimal
CBLOCK
VAR1
ORIGINAL
CENTENAS
DECENAS
UNIDADES
ENDC
LCD_Dec
CLRF CENTENAS
CLRF DECENAS
CLRF UNIDADES
MOVWF VAR1
MOVWF ORIGINAL
ANALIZA_CENTENAS
MOVLW .100
SUBWF VAR1,1
BTFSC STATUS,0
GOTO INCREMENTA_CENTENAS
GOTO ANALIZA_DECENAS
INCREMENTA_CENTENAS
INCF CENTENAS
GOTO ANALIZA_CENTENAS
ANALIZA_DECENAS
MOVLW .100 ;le sumo los ultimos 100 restados
ADDWF VAR1,1 ;y en VAR1 me queda el resto
OTRA
MOVLW .10
SUBWF VAR1,1
BTFSC STATUS,0
GOTO INCREMENTA_DECENAS
GOTO ANALIZA_UNIDADES
INCREMENTA_DECENAS
INCF DECENAS
GOTO OTRA
ANALIZA_UNIDADES
MOVLW .10 ;le sumo las ultimas 10 restadas
ADDWF VAR1,1 ;y en VAR1 me queda el resto (las unidades)
MOVF VAR1,0
MOVWF UNIDADES
;devuelvo el WREG a su valor original
MOVF ORIGINAL,0
RETURN
;--------------------------------------------
END
Funciona bien pero la salida del numero no me gusta, en vez de pintar por ejemplo 179 pinta 1 7 9 debido a que utilizo la llamada LCD_Byte de la libreria LCD_4BIT.INC; he intentado forzar el cursor a las posiciones 7,8 y 9 justo despues del mensaje "Cuenta=" pero no va.
Nada mas espero que le sea util a alguien.
Un saludo.
-
Hola de nuevo.
Pues he encontrado una solución muy sencilla al problema que creaba la llamada a LCD_Byte ya que ésta está preparada para pintar dos digitos por byte.
Pues la solución es muy sencilla, como veis en el codigo abajo lo unico que he hecho es sumar a las UNIDADES,DECENAS y CENTENAS 48 en decimal que corresponde al codigo ASCII del simbolo "0" y en vez de llamar a LCD_Byte llamo a LCD_Caracter, por lo que solo hay que tocar el programa y no la subrutina.
; Contador en Decimal
;con salida a la LCD
LIST P=16F84A
INCLUDE <P16F84A.INC>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
CBLOCK 0x0C
PDel0
PDel1
dato
ENDC
; ZONA DE CÓDIGOS *******************
ORG 0
Inicio
call LCD_Inicializa
movlw MensajeFijo ; Apunta al mensaje fijo y lo visualiza.
call LCD_Mensaje
movlw 0
movwf dato
bucle
movlw 7 ;se situa despues de Cuenta=
call LCD_PosicionLinea1
movf dato,0
call LCD_Dec ;llamo a la subrutina de conversion
movf CENTENAS,0
addlw .48 ;codigo ASCII del 0
;call LCD_Byte ;Pinta W en Decimal
call LCD_Caracter
movf DECENAS,0
addlw .48 ;codigo ASCII del 0
;call LCD_Byte
call LCD_Caracter
movf UNIDADES,0
addlw .48 ;codigo ASCII del 0
;call LCD_Byte
call LCD_Caracter
incf dato,0
movwf dato
call DEMORA
goto bucle
Mensajes
addwf PCL,F
MensajeFijo
DT "Cuenta=", 0x00;
;MensajeParpadeante
; DT " El niño Jesus ", 0x00
INCLUDE <LCD_4BIT.INC>
INCLUDE <LCD_MENS.INC>
INCLUDE <RETARDOS.INC>
;END
;-------------------------------------------------------------
; Generado con PDEL
; Descripcion: Delay 500000 ciclos
;-------------------------------------------------------------
DEMORA movlw .239 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop1 movlw .232 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
PDelL1 goto PDelL2 ; 2 ciclos delay
PDelL2 goto PDelL3 ; 2 ciclos delay
PDelL3 clrwdt ; 1 ciclo delay
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop1 ; 2 no, loop
PDelL4 goto PDelL5 ; 2 ciclos delay
PDelL5 goto PDelL6 ; 2 ciclos delay
PDelL6 goto PDelL7 ; 2 ciclos delay
PDelL7 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;-------------------------------------------------------------
;---------subrutina de converion a decimal
CBLOCK
VAR1
ORIGINAL
CENTENAS
DECENAS
UNIDADES
ENDC
LCD_Dec
CLRF CENTENAS
CLRF DECENAS
CLRF UNIDADES
MOVWF VAR1
MOVWF ORIGINAL
ANALIZA_CENTENAS
MOVLW .100
SUBWF VAR1,1
BTFSC STATUS,0
GOTO INCREMENTA_CENTENAS
GOTO ANALIZA_DECENAS
INCREMENTA_CENTENAS
INCF CENTENAS
GOTO ANALIZA_CENTENAS
ANALIZA_DECENAS
MOVLW .100 ;le sumo los ultimos 100 restados
ADDWF VAR1,1 ;y en VAR1 me queda el resto
OTRA
MOVLW .10
SUBWF VAR1,1
BTFSC STATUS,0
GOTO INCREMENTA_DECENAS
GOTO ANALIZA_UNIDADES
INCREMENTA_DECENAS
INCF DECENAS
GOTO OTRA
ANALIZA_UNIDADES
MOVLW .10 ;le sumo las ultimas 10 restadas
ADDWF VAR1,1 ;y en VAR1 me queda el resto (las unidades)
MOVF VAR1,0
MOVWF UNIDADES
;devuelvo el WREG a su valor original
MOVF ORIGINAL,0
RETURN
;--------------------------------------------
END
-
Gracias por compartir, seguro que vendran bien.