list p=12f675 ; list directive to define processor
#include <p12f675.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.
;***** VARIABLE DEFINITIONS
Cblock 0x20
PDel0
PDel1
PDel2
PDel3
FLAG
w_temp ; variable used for context saving
status_temp ; variable used for context saving
timer1,timer2,timer3
endc
#define toggle FLAG,0
#define PULS GPIO,5
#define RL1 GPIO,4
;**********************************************************************
ORG 0x000 ; processor reset vector
goto Inicio ; go to beginning of program
; these first 4 instructions are not required if the internal oscillator is not used
Inicio
call 0x3FF ; retrieve factory calibration value
bsf STATUS,RP0 ; set file register bank to 1
movwf OSCCAL ; update register with factory cal value
bcf STATUS,RP0 ; set file register bank to 0
CLRF GPIO ;Init GPIO
MOVLW 07h ;Set GP<2:0> to
MOVWF CMCON ;digital IO
BSF STATUS,RP0 ;Bank 1
movlw 0
movwf OPTION_REG;habilitacion pullups
movwf IOC ;deshabilitar int por cambio puertos
movwf WPU
; bsf WPU,5 ;todas pullups deshabilitadas excepto GP5 entrada pulsador
movlw b'00110001'; FRC, AD en GP0, left justif. Leemos el ADRESH para la conversión 8 bits
movwf ANSEL ;
MOVLW b'11101101';GP0= AD IN, GP4 Relay out, GP5 pulsador in
MOVWF TRISIO ;
BCF STATUS,RP0 ;Bank 0
call delay500
main
bcf toggle
bcf RL1
test_puls1
btfsc PULS
goto main
call delay20
bsf RL1
test_puls2
btfsc PULS
goto test500 ;ha dejado de pulsar por 500ms?
goto test_puls2
test500
bcf RL1
call delay500
btfsc PULS
goto main
son2
call delay20
bsf ADCON0,ADON
start
bsf ADCON0,GO
waiting
btfsc ADCON0,GO
goto waiting
start2
movf ADRESH,W
movwf timer1
movwf timer2
start3
bsf RL1 ;turn on
call DEMORA
decfsz timer1,1
goto start3
pause1
bcf RL1
CALL DEMORA
decfsz timer2,1
goto pause1
test_puls3
btfss PULS
goto start
bcf ADCON0,ADON
goto main
delay500
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.
DEMORA movlw .80 ; 1 set numero de repeticion
movwf PDel0 ; 1 |
PLoop50 clrwdt ; 1 clear watchdog
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ?
goto PLoop50 ; 2 no, loop
clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
delay20 movlw .21 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop10 movlw .237 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop20 clrwdt ; 1 clear watchdog
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop20 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop10 ; 2 no, loop
PDelL10 goto PDelL20 ; 2 ciclos delay
PDelL20 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
END ; directive 'end of program'si tuviesemos una libreria tan amplia y bien echa como el c o basic... no acabariamos a veces "clrf cerebro" en mi humilde opinion.
pues eso, estas :ni) clrf cerebro :D, que si tuviesemos librerias de todo, no nos pasariamos al c, basic... en un futuro, o a lo mejor no es necesario y se puede seguir con asm. pero efectivamente creo que es la causa de que la gente opte por otro tipo de lenguajePero Alogic, entonces estás de acuerdo conmigo. Tal vez yo me expresé mal. Me refiero a lo mismo que tu dice.
en lo que me gusta a mi, sonido, midi... y esas cosillas que por aqui no gustan nada :mrgreen: casi todos utilizan arduino (pduaj), dicen solo por el lenguaje, (siempre me lo intentan comparar con los pic. :shock: arduino esto si, aquello tambien, pic de eso nada...) y hay que verles la cara cuando ven un programa en assembler, parece les diera miedo u algo asi :evil:. tan complicado es :huh: o tan facil son los otros
un saludo
Para ser sincero, muchos se pasan al C, al BASIC porque muchos problemas están resueltos, como por ejemplo, multiplicar, dividir, comunicación RS232, USB y muchos etcmas menos lo mismo ;)
Alogic_on muy bueno el data del 16f876, si tienes mas subelos
hay veces que tal y como estan no te sirven y si tienes que adaptarlas a tu programa, si no sabes como funcionan no podras hacerlo.yo creo que mas que tener que adaptarlas a nuestros programas las usamos de ejemplo para desarrollar y entender lo que necesitamos, aunque a veces coincida con lo que queremos, pero ya sea estudiandolas o solo copiando/pegando algo seguro que se aprende
... presentar brevemente las características sobresalientes de la Arquitectura PIC Linea Media Mejorada, integrada por los PIC16F1XXX y PIC12F1XXXX que se caracterizan por ampliar la capacidad de los PIC Linea Media y el Set de Instrucciones, luego haré un informe especial sobre los mismos...habria que plantearse probarlos, la puñeta es en mi caso la de siempre, la informacion, no me entero con el ingles, asi que ya saben a ver cuando empiezan a sacar los datas traducidos estos de uC. que somos muchos los que estamos varados :8} :8}
veis a que me refiero, por ej te pueden contar la teoria un millon de veces, pero llega en este caso BrunoF... y a mi casi siempre me cambia la forma de ver las cosas. ahora mismo ya estoy dandole vueltas a esa
una preguntica, BrunoF?? si no es mucha indicrecion :mrgreen: cuanto tiempo llevas programando en ensamblador (segun lo que me respondas me tiro al pozo :D)
Si Aalogic_on Bruno siempre nos da sorpresas agradables, no te desesperes si no llegas aser tan bueno como el, da la impresion de que hay una escuela Argentina de programadores en asembler no? muy buena ademas.
Por supuesto que cualquiera puede ser tan "bueno... :roll:" o mejor que yo. .No te desanimes.
Si Aalogic_on Bruno siempre nos da sorpresas agradables, no te desesperes si no llegas aser tan bueno como eljej que es coña, soy mucho mas cabezota y para desanimarme vais a necesitar algo mas :D n veas si me queda por seguiros dando el peñaso por aqui con mis electrotrastornos :D :D
:shock: :rolleyes: Que el hilo no pierda su tema principal. Leer las reglas del Foro :mrgreen:traaaaaanki :D :D que no lo pierde
Mejor que así sea! :?:shock: :rolleyes: Que el hilo no pierda su tema principal. Leer las reglas del Foro :mrgreen:traaaaaanki :D :D que no lo pierde
tenemos rutinas para matematicas X : + -...., tambien IIC, ADC,eeprom.... que nos falta para cubrir rutinas para compartir, así a ojo de buen cubero.... usart, modulo comparador de las tres formas, escribir leer en la flash y perifericos que podriamos ir añadiendo un larguisimo etc luego subo alguna para no perder el hilo Suky :D
un saludo
LIST P=16F877A
INCLUDE <P16F877A.INC>
__CONFIG _XT_OSC & _PWRTE_OFF & _WDT_OFF & _CP_OFF & _BODEN_OFF & _LVP_OFF & _WRT_OFF
;
;---------------------------------------------------------------
;VARIABLES.
;---------------------------------------------------------------
;
CBLOCK H'20'
dato_enviar
dato_enviar_temp
contador
cont_bit
ENDC
;
RESET ORG H'00'
GOTO INICIO
ORG H'04' ;VECTOR INTERRUPCIÓN
;
#INCLUDE USART_TX.INC
INICIO
;
BCF STATUS,RP0
BCF STATUS,RP1 ;BANCO 0
CLRF PORTA
CLRF PORTB
CLRF PORTC
CLRF PORTD
CLRF PORTE
BSF STATUS,RP0 ;BANCO 1
CLRF TRISA
MOVLW H'FF'
MOVWF TRISB
CLRF TRISC
CLRF TRISD
CLRF TRISE
MOVLW 0x06
MOVWF ADCON1
;
;EJEMPLO DE UTILIZACIÓN
;----------------------
;
;ENVÍA EL ESTADO DEL PORTB POR MEDIO DE LA USART.
;
BCF STATUS,RP0
CALL INI_USART
MOVFW PORTB
CALL DETERMINAR_PARIDAD
BCF contador,0 ;RETORNA CON LA FINALIZACIÓN DE LA TRANSMISIÓN
CALL TRANSMITIR
GOTO $-4
;
END LIST P=16F877A
INCLUDE <P16F877A.INC>
__CONFIG _XT_OSC & _PWRTE_OFF & _WDT_OFF & _CP_OFF & _BODEN_OFF & _LVP_OFF & _WRT_OFF
;
;---------------------------------------------------------------
;VARIABLES.
;---------------------------------------------------------------
;
CBLOCK H'20'
bit_recepcion
bit_cont
bit_cont_temp
dato_recibido
dato_recibido_temp
RCSTA_temp
SALVAR_W
SALVAR_STATUS
SALVAR_FSR
SALVAR_PCLATH
SALVAR_OPTION_REG
ENDC
;
RESET ORG H'00'
GOTO INICIO
ORG H'04' ;VECTOR INTERRUPCIÓN
INTERRUP
MOVWF SALVAR_W ;SALVA EL CONTENIDO DE W
SWAPF STATUS,W ;PASAMOS A W STATUS (ES CON SWAPF PARA NO AFECTAR EL BIT Z)
MOVWF SALVAR_STATUS ;SALVA EL CONTENIDO DE STATUS
SWAPF FSR,W ;PASAMOS A W FSR
MOVWF SALVAR_FSR ;SALVA FSR
SWAPF PCLATH,W ;PASAMOS A W PCLATH (Pagina de programa)
MOVWF SALVAR_PCLATH ;SALVA EL CONTENIDO DE PCLATH
BCF STATUS,RP1
BSF STATUS,RP0 ;BANCO 1
SWAPF OPTION_REG,W ;PASAMOS A W OPTION_REG (Bancos)
MOVWF SALVAR_OPTION_REG ;SALVA EL CONTENIDO DE OPTION_REG
BCF STATUS,RP0 ;BANCO 0
BTFSS PIR1,RCIF ;¿SE ACTIVÓ RECEPCIÓN USART?
GOTO SALIR ;FALSA INTERRUPCIÓN
BCF PIR1,RCIF ;SI, REESTABLECEMOS EL BIT DE RCIF
;
#INCLUDE RX_USART_INTERRUPCION.INC
;
SALIR BSF STATUS,RP0 ;BANCO 1
SWAPF SALVAR_OPTION_REG,W ;RESTAURA EL VALOR A OPTIO_REG
MOVWF OPTION_REG
SWAPF SALVAR_PCLATH,W ;RESTAURA EL VALOR A PCLATH
MOVWF PCLATH
SWAPF SALVAR_FSR,W ;RESTAURA EL VALOR A FSR
MOVWF FSR
SWAPF SALVAR_STATUS,W ;RESTAURA EL VALOR A STATUS
MOVWF STATUS
SWAPF SALVAR_W,W ;RESTAURA EL VALOR A W
RETFIE
;
#INCLUDE RX_USART.INC
;
INICIO BCF STATUS,RP0
BCF STATUS,RP1 ;BANCO 0
CLRF PORTA
CLRF PORTB
CLRF PORTC
CLRF PORTD
CLRF PORTE
BSF STATUS,RP0 ;BANCO 1
CLRF TRISA
CLRF TRISB
CLRF TRISC
CLRF TRISD
CLRF TRISE
MOVLW 0x06 ;PORTA TODAS DIGITALES.
MOVWF ADCON1
;
;EJEMPLO DE UTILIZACIÓN.
;
;RECIBE EL ESTADO DEL PORTB DE TX POR MEDIO DE LA USART Y LO MUESTRA EN EL PORTB.
;
CALL INI_USART_RX
CALL ACTIVAR_USART
BTFSS bit_recepcion,0
GOTO $-1
BCF bit_recepcion,0
MOVFW dato_recibido
MOVWF PORTB
GOTO $-5
END
te habrás quedao agusto¡¡¡ :D :D :D
Sin ofender, pero no te entiendojej vas a tener que decir algo mas para ofender :D :D :D era como un piropo que me salio asi en ese momento
#INCLUDE <p18F4550.inc>
LECTURA EQU 0x0050 ;Variable de estado
LECTURA_PRUEBA EQU 0x0055 ;Variable de estado
temp EQU 0x0054
temp_retraso EQU 0x0051
temp2_retraso EQU 0x0052
temp3_retraso EQU 0x0053
Ind_Buf EQU 0x00 ; Contador de número de datos copiados
Buf_Dat EQU 0x20 ; Bufer de recepción/transmisión
ORG 0x00 ;Vectorizacion
; GOTO inicio
;------------------------------------------
BCF INTCON,7 ;DESACTIVAR INTERRUPCIONES
BCF WDTCON,0 ;dESACTIVAR WDT
MOVLW b'10001000' ;timer 0 ON-16bits-TImer0 prescaler off
MOVWF T0CON ;
;registros de interrupciones
BCF INTCON,7 ;deshabilitar interrupciones
; configurar puertos
CLRF PORTD
CLRF LATD
MOVLW 0x00 ;d SALIDA DE MATRIZ DE LEDS
MOVWF TRISD
;=========================
;=====inicio del progama==
;=========================
MOVLW d'248'
MOVWF temp_retraso
MOVLW d'255'
MOVWF temp2_retraso
MOVLW d'24'
MOVWF temp3_retraso
BTG LATD,0 ;INVIERTE D0
CLRF TMR0L
CALL retraso_
BRA 0X1E ;te manda a BTG LATD
;==========rutina de retrasos=============
retraso_:
movlw 0x18 ;1
movwf temp3_retraso ;1
decfsz temp_retraso,1,0 ;1 --- 3 ciclos cuando es cero ;FF-- salta si file es cero
goto retraso1 ;2 = [(20332*(248-2)]+7=5001679---> 5001679*200nSeg=1 seg aprox ^
movlw 0xF8 ;1 ni maiz 246+2=248=F8 /|\
movwf temp_retraso ;1 / | \
; 1 segundo sera={[246(254(80)+12)]+7}200x10^-9=1.000335 segundos / | \
; / | \
return ;2 + 3 del decfsz cuando es cero Tercer ciclo [246*ans]+7
retraso1: |
decfsz temp2_retraso,1,0 ;1 --- 3 ciclos cuando es cero ;FF-- salta si file es cero |
goto retraso2 ;2 (255-1)(80)+12=20332 |
movlw 0xFF ;54h=84d ;1 |
movwf temp2_retraso ;1 Segundo ciclo [254*80]+12
goto retraso_ ;2 |
|
retraso2: ;El ciclo debe de ser igual a 77 para que 255*255*77*200ns= 1.00925 segundo |
decfsz temp3_retraso,1,0 ;1 --- 3 ciclos cuando es cero |
goto retraso2 ;2 Secuencia ascendente para
movlw 0x18 ;18h=24d ;+1 77+3=80 obtener los tiempos
movwf temp3_retraso ;+1 3 del ciclo anterior en retraso1 de retardo totales
nop ;+1 |
goto retraso1 ;+2 Primer ciclo 80
;+3 del ciclo anterior en retraso1 |
;------------------------------------------
Fin_intT0:
RETFIE
END
;------------------------------------------
- Suma 16bits + 16bits
- Resta 16bis – 16 bits
- División 8bits/8bits
- División 24bits/16bits
- Multiplicación 16bitsx16bits=32bits
- Conversión binario de 8 bits a BCD
- Conversión binario de 16 bits a BCD
- Suma 16bits + 16bits
- Resta 16bis – 16 bits
- División 8bits/8bits
- División 24bits/16bits
- Multiplicación 16bitsx16bits=32bits
- Conversión binario de 8 bits a BCD
- Conversión binario de 16 bits a BCD
;*********************************** CONVERTIR VALOR BCD A HEX ******************************************************
; Convierte valor bcd a hexagesimal .
; ejemplo: 0x15(15 segundos del RTC) a 0x0F (valor 15 en decimal)BCD_HEX
BANK7 ;selecciona banco 7 de ram
movwf ByteL ;carga valor a convertir contenido en W
movwf ByteH ;carga valor a convertir contenido en W
movlw 0x0f ;selecciona el nibble bajo de W
andwf ByteL,f ;introducelo en el registro ByteL
movlw 0xf0 ;selecciona el nibble alto de W
andwf ByteH,f ;introducelo en el registro ByteH
swapf ByteH,w ;invierte los nibles de ByteH e introduce el resultado en W
mullw .10 ;multiplica el contenido de W por 10d
movf PRODL,w ;caga el resultado en W
addwf ByteL,w ;suma el contenido de ByteL a W
return;ESTE PROGRAMA DEVUELVE EN W,EL VALOR ANALOGICO INTRODUCIDO EN AN0,AN1,AN2 O A43 aunque esta modificado para funcionar solo con AN3
;si introducimos un valor inferior a TOPE_TECLA,y metemos un valor de voltage en uno de las cuatro entradas analogicas,
;ese valor se introduce en TEMP_ANALOG.el programa solo lee un pin a la vez,es decir si introducimos voltage en los dos
;pin,solo se tendra encuenta el primer voltage que se halla aplicado.
;
;la peculariedad de que este programa sea tan grande,es que tiene un sistema de comprovacion de errores,que al pulsar
;una tecla.se almazenan en memoria 10 valores de esa tecla y se coje el valor mas repetido.de esa forma se evita el que al
;pulsar un boton resistivo,no cojamos el valor mas aproximado al real de ese boton.y que nos falle la identificacion de esa tecla.
;el programa tarda en ejecutarse 118ms a 48Mhz
CBLOCK BOTON_PULS_VAR
TEMP_ANALOG ;registro de tecla pulsada
COMPARADOR
PREVALECE
CONT_REG
CONT_COINC
ENDC
#define VALOR_TOPE .240 ;valor tope de tecla sin pulsar
#define INI_RAM 0XF6 ;zona donde se ubicaran los datos analogicos de tecla pulsada
#define INI_TABLA 0XEC
BOTON_PULS movlw INI_RAM
movwf FSR0L
movlw BANCO_GENERAL
movwf FSR0H
REPE call DAT_AN ;lee dato analogico
movlw VALOR_TOPE
cpfslt TEMP_ANALOG
return ;si el valor analogico de la tecla es superior a TOPE_TECLA repite busqueda analogica(sin pulsar)
movff TEMP_ANALOG,INDF0
incf FSR0L,F ;incrementa FSR
clrf WREG
cpfseq FSR0L
goto REPE ;si no se ha llegado al tope de la ram repite
;********************************************************BUSCA_REP**********************************************************************;
; ;
;//////////////////////////////////////aqui leemos la ram y buscamos el dato mas repetido///////////////////////////////////////////////;
;//en este subprograma se cogen los valores almacenados entre las direcciones seleccionadas y se coge valor que tenga mas numeros repetidos.
BUSCA_REP movlw BANCO_GENERAL ;banco donde trabajaremos con los registros generales
movwf FSR2H ;selecciona bancos de direccionamiento indirecto
movwf FSR1H
movwf FSR0H
movlw INI_TABLA ;inicio de tabla ram donde estan los valores a comparar
movwf FSR0L ;selecciona indice de tabla
decf FSR0L,F ;decrementa una direccion para luego incrementarla
movlw INI_RAM ;inicio de tabla ram donde se introduciran cantidad de coincidencias
movwf FSR2L ;selecciona indice de tabla
decf FSR2L,F ;decrementa una direccion para luego incrementarla
movlw .11 ;bytes a comparar menos 1
movwf CONT_COINC ;contador de comparaciones
regsig2 dcfsnz CONT_COINC,F ;decrementa el contador de comparaciones
goto discrim ;si se ha terminado de comprobar las coincidencias salta a esta direccion
movlw INI_RAM ;inicio de tabla ram donde se introduciran cantidad de coincidencias
movwf FSR1L ;selecciona indice de tabla
incf FSR2L,F ;incrementa indice de tabla
decf FSR1L,F
movff INDF2,COMPARADOR ;introduce valor de la tabla en registro comparador
movlw .11 ;registros a comparar
movwf CONT_REG ;contador de registros a comparar
incf FSR0L,F ;incrementa indice de registros
regsig1 incf FSR1L,F ;incrementa indice de comparaciones
movf INDF1,W ;lee el registro indexado
dcfsnz CONT_REG,F ;decrementa contador de registros
goto regsig2 ;si se ha llegado al limite salta a lectura de siguiente registro
cpfseq COMPARADOR ;comprueba si w es igual a COMPARADOR
goto regsig1 ;siguiente comparacion
incf INDF0,F ;incrementa direccion seleccionada si hay coincidencia
goto regsig1 ;siguiente comparacion
;busca el valor mas alto
discrim movlw .9 ;cantidad de registros a comparar
movwf CONT_REG ;registro contador
movlw INI_TABLA ;inicio de tabla
movwf FSR0L ;direcciona tabla ram
movff INDF0,PREVALECE ;introduce el valor contenido en ram al registro prevalescente
dis1 incf FSR0L,F ;siguiente direccion
movf INDF0,W ;carga valor direccionado en W
cpfsgt PREVALECE ;comprueba si es mayor
movff INDF0,PREVALECE ;si es mayor introduce el valor en el registro prevalescente
decfsz CONT_REG,F ;decrementa contador de comprobaciones
goto dis1 ;siguiente comprovacion
;busca el valor mas alto de las coincidencias
movlw INI_TABLA ;carga inicio de tabla
movwf FSR0L
pre1 movf INDF0,W ;carga el valor direccionado en W
xorwf PREVALECE,W ;comparalo con el valor mas alto
btfsc STATUS,Z ;si se ha encontrado,
goto pre2 ;salta a pre2
incf FSR0L,F ;incrementa direccion
goto pre1 ;repite comparacion
pre2 movlw .10 ;valor de salto a tabla de valores
addwf FSR0L ;salta al valor
movf INDF0,w ;introduce valor en W
return ;retorna
;//////////////////////////////////(conversor A/D)////////////////////////////////////////////////////////////////////////////////////////////////
;///////////////busca el dato analogico introducido por el pin seleccionado/////////////////////////////////////////////////////////////////////
;////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
;Si queremos que funcionen todas las entradas analogicas.hay que habilitar las lineas deshabilitadas
DAT_AN ;BANK0 ;selecciona banco 0
;GIE_OFF ;GIE0 ;deshabilita las interrupciones
;btfsc INTCON,GIE
;goto GIE_OFF
bsf ADCON0,GO_DONE ;inicia la conversion
AD_GOIN btfsc ADCON0,GO_DONE ;comprueva si la conversion ha finalizado
goto AD_GOIN ;si la conversion ha finalizado continua
movf ADRESH,w ;carga dato analogico en el acumulador
movwf TEMP_ANALOG ;carga el dato de w en TEMP_ANALOG
;movf ADCON0,W
;movwf CANAL ;mete el contenido de ADCON0 en CANAL
;movf CONT_AD,W ;dato que se suma a ADCON0 para que a la siguiente lectura sea en el proximo canal de AD
;addwf ADCON0,F ;incrementa el canal analogico(AN0->AN4)
;movlw b'00100001';valor para usar AN5 -> b'00101001' ;valor del ultimo registro del conversor analogico
;xorwf ADCON0,w
;btfss STATUS,Z ;si llega a este valor
;return
;movlw 0x01 ;selecciona de nuevo el conversor AN0
;movwf ADCON0
return
;******************************************************* BIN16_TO_DEC ***************************************************
;conversor
BIN16_TO_DEC movff DEC_H,ADD_DEC_H
clrf CIENTOS ;registro de las centenas
clrf ACUMULADOR
clrf DEC_U
SUB1 movlw .100 ;valor a restar
subwf DEC_L,W ;restalo al acumulador
btfss STATUS,C
goto SUB ;si es menor salta a SUB.pero si es mayor o igual,sigue restando
movlw .100 ;valor a restar
subwf DEC_L,F ;restalo del byte bajo
incf CIENTOS,F ;incrementa el registro de las centenas
call incre_cientos ;incremento de los registros contadores
goto SUB1 ;repite
;*********************************************************** SUB ******************************************************
SUB movf DEC_L,W ;recoge el resto
addwf ACUMULADOR,F ;y sumalo al acumulador
movlw .100
subwf ACUMULADOR,w ;si no llega a 100,
btfss STATUS,C
goto acu1 ;continua calculo
movlw .100
subwf ACUMULADOR,F ;si ACUMULADOR es igual o superior a 100. resta 100 al acumulador y
incf CIENTOS,F ;incrementa el registro de las centenas
call incre_cientos ;incremento de los registros contadores
acu1 clrf WREG ;valor 0
cpfseq DEC_H ;comprueba el valor del registro de las centenas (fin del contaje)
goto acu5 ;salta aqui si se llego al tope de descuento del registro de centenas.
acu_fin movf ADD_DEC_H,W
addwf ACUMULADOR,f ;ajusta el valor final
btfsc STATUS,C
call incre_doble ;otro ajuste
movlw .100
subwf ACUMULADOR,w
btfss STATUS,C ;comprueba si ACUMULADOR es mayor o igual a 100
goto fin2
movlw .100 ;si es asi,
subwf ACUMULADOR,F ;resta elvalor a ACUMULADOR
incf CIENTOS,F ;he incrementa CIENTOS
call incre_cientos
;por si el valor era 200d
movlw .100
subwf ACUMULADOR,w
btfss STATUS,C ;comprueba si ACUMULADOR es mayor o igual a 100
goto fin2
movlw .100 ;si es asi,
subwf ACUMULADOR,F ;resta elvalor a ACUMULADOR
incf CIENTOS,F ;he incrementa CIENTOS
call incre_cientos ;incremento de los registros contadores
fin2 movlw .100
subwf CIENTOS,w ;comprueba si CIENTOS es superior a 100
btfss STATUS,C
goto fin3
movlw .100 ;si lo es,
subwf CIENTOS,f ;restale 100 al registro de las centenas
incf DEC_U,F ;he incrementa el de los diezmiles
fin3 movff ACUMULADOR,DEC_L ;intercambia registros
movff CIENTOS,DEC_H ;intercambia registros
return ;fin del la rutina
;******************************************************************************************************************
acu5 setf DEC_L ;setea el registro para una nueva resta
decf DEC_H,F ;decrementa el registro de las centenas
goto SUB1 ;vuelve al principio
;circunstancia que se da en el valor 0xB000.donde hay un desbordamiento que hay que ajustar.
incre_doble incf CIENTOS,F
incf CIENTOS,F
movlw .56
addwf ACUMULADOR,F
return
;incremento del contador de los cientos y los miles
incre_cientos movlw .100 ;valor a comparar
cpfseq CIENTOS;subwf CIENTOS,w
return ;retorna si no lo es
incf DEC_U,F ;incrementa el contador de los diez miles
clrf CIENTOS ;
return ;retorna
;*************************************************************** DEC_TO_ASCII *********************************************************
DEC_TO_ASCII movf DEC_L,w
call DEC_HEX
movwf DEC_L
movff DEC_L,TEMP_DEC_L
;call DEC_HEX
andlw 0x0F
movwf Un
movf TEMP_DEC_L,W
;call DEC_HEX
andlw 0xF0
swapf WREG
movwf Dc
movf DEC_H,W
call DEC_HEX
movwf DEC_H
movff DEC_H,TEMP_DEC_H
;movf TEMP_DEC_L,W
;call DEC_HEX
andlw 0x0F
movwf Cn
movf TEMP_DEC_H,W
;call DEC_HEX
andlw 0xF0
swapf WREG
movwf Um
movf DEC_U,W
call DEC_HEX
movwf DEC_U
movff DEC_U,TEMP_DEC_U
;movf TEMP_DEC_L,W
;call DEC_HEX
andlw 0x0F
movwf Dm
call ASCII_CONV
;xorwf TEMP_DEC_L,f
return
ASCII_CONV movlw 0x30
addwf Un,f
addwf Dc,f
addwf Cn,f
addwf Um,f
addwf Dm,f
return
;*********************************** CONVERTIR VALOR DECIMAL EN HEX ******************************************************
; Convierte valor decimal en hexgesimal
; ejemplo: 0x0f -> 0x15
DEC_HEX ;BANK7 ;selecciona el banco 7 de ram
movwf reg1 ;carga valor a convertir contenido en W
setf Resultado ;pon a 1 todos los bits del registro Resultado.
movlw .10 ;carga el valor 10d en W
div incf Resultado,f ;incrementa el registro Resultado
subwf reg1,F ;restar a reg1 el valor .10
btfsc STATUS,C ;comprueba si ha habido acarreo
goto div ;repite div
movlw .10 ;carga el valor 10d en W
addwf reg1,W ;sumalo a reg1
movwf Resto ;carga la suma enterior en Resto
swapf Resultado ;invierte los nibles
addwf Resultado ;suma el contenido de w a Resulatado
movf Resultado,w
return ;retorna