reiniciar
bcf PORTA,3 ;Cierro la entrada de frecuencia
clrf PULSOS
clrf TMR0
movlw .20
movwf CONTE_F
emp bsf PORTA,3 ;Permito que entre la frecuencia
LoopE
movlw .250
movwf CONTI_F
goto Comprueba1
LoopI
nop
nop
nop
nop
nop
nop
Comprueba1
movf TMR0,W ; Muevo TMR0 a W
subwf V_TMR0,F ;
btfss STATUS,Z ;
goto Comprueba2
nop
goto Asigna
Comprueba2
btfsc STATUS,C ;Compruebo que si TMR0 ...
incf PULSOS,F ; ... ha dado una vuelta incremento pulsos
Asigna
movwf V_TMR0 ; Guardo el valor de TMR0 para comprobar en la sig iteracion
nop
nop
nop
decfsz CONTI_F ; Decremento el contador Interno
goto LoopI ; Mientras no termine sigo.
decfsz CONTE_F ; Decremento el contador Externo
goto LoopE
fina bcf PORTA,3 ;Termino de contar y cierro la entrada de frecuencia
nop
Bucle
goto reiniciar;====================================================================
; Main.asm file generated by New Project wizard
;
; Created: sáb sep 14 2013
; Processor: PIC16F84A
; Compiler: MPASM (Proteus)
;====================================================================
;====================================================================
; DEFINITIONS
;====================================================================
#include p16f84a.inc ; Include register definition file
;#include lib_lcd.inc ; Incluyo la libreria lcd
;====================================================================
; Opciones
;====================================================================
__config _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
;====================================================================
; VARIABLES
;====================================================================
PULSOS equ 0x11
V_TMR0 equ 0x12
delayl equ 0x13
delayh equ 0x14
aux equ 0x15
;Define
#DEFINE IN_OUT_DELAY .9 ;ciclos de demora introducidos por el call, return, cierre de NAND deben ser tenidos en cuenta)
#DEFINE CYCLES (.50000 - IN_OUT_DELAY)
;====================================================================
; RESET and INTERRUPT VECTORS
;====================================================================
; Reset Vector
RST code 0x0
goto Start
ISR org 0x4
incf PULSOS,F
retfie
PGM code
FRECUENCIA
;Operaciones
return
errorlevel -302
Start
;Incializamos el LCD
;call initlcd
;Incializamos las interrupciones
bsf STATUS,RP0 ; Paso al banco 1
movlw b'11101000'
movwf OPTION_REG ; Configuro el registro de opciones Preescaler a 000
movlw b'10000'
movwf TRISA
bcf STATUS,RP0 ; Vuelvo al banco 0
;LCD_PUTC 'F'
;LCD_PUTC 'R'
;LCD_PUTC 'E'
;LCD_PUTC 'C'
;LCD_PUTC 'U'
;LCD_PUTC 'E'
;LCD_PUTC 'N'
;LCD_PUTC 'C'
;LCD_PUTC 'I'
;LCD_PUTC 'M'
;LCD_PUTC 'E'
;LCD_PUTC 'T'
;LCD_PUTC 'R'
;LCD_PUTC 'O'
bcf PORTA,3 ; Cierro la entrada de frecuencia
;bsf INTCON,7 ; Activo las interrupciones globales
;bsf INTCON,5 ; Activo la interrupcion del TMR0 por desbordamiento
reiniciar
clrf PULSOS
movlw HIGH CYCLES
movwf delayh
movlw LOW CYCLES
movwf delayl
clrf TMR0
bcf INTCON,T0IF
open
bsf PORTA,3 ; Abro la entrada de frecuencia
call retardo_100ms
close
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
nop
bcf PORTA,3 ; Cierro la entrada de frecuencia
btfsc INTCON,T0IF ;caso extraño, pero puede ocurrir
incf PULSOS,F
movf TMR0,W ; Muevo al registro W
movwf V_TMR0 ; Almaceno el valor que hay en TMR0
goto reiniciar
;====================================================================
; Subrutinas
;====================================================================
retardo_100ms
movf INTCON,W
movwf aux
movlw .8 ;demora básica bucle
btfsc aux,T0IF
incf PULSOS,F
btfsc aux,T0IF
bcf INTCON,T0IF ;limpiar flag de interr.
nop ; para hacer par la cantidad de instrucciones del bucle
subwf delayl,F
btfsc STATUS,C
goto noCarry
movlw .1
subwf delayh,F
btfsc STATUS,C
goto retardo_100ms
return
noCarry ;compensar ciclos hasta llegar a 16 (8 x 2)
goto $+1 ; 2 ciclos
goto retardo_100ms ; 2 ciclos
;====================================================================
END
Para ello, el algoritmo de demora podría utilizar una dos variables de 8 bits trabajando como una de 16 bits(nuestro contador de ciclos / 2).Esto no lo entiendo. Se que el 100000 son los ms pero no entiendo porque cargar la mitad. ¿No sería el contador de ciclos *2? Tengo un cacao mental ahora mismo.
Lo pre-cargaríamos entonces con un valor poco menor a 100000 / 2 (0xC350). E implementaríamos un bucle sencillo que iría descontando a partir de allí:
Hola BrunoF.
Buenísimo el código ((:-)) como dicen en otros foros, marchando unas cervezas ;-)
La idea del contador de 50000 me parece buenísima así se puede ajustar el retardo mucho mejor que haciendo bucles anidados que para ajustarlos uno a la exactitud se acaba volviendo loco.
Vale ¿entonces como das una vuelta que son 16 ciclos descuentas 8 y así consigues que con esos 50000 en realidad sean 100000?
Ya solo me queda la duda de estas dos lineas de códigoCódigo: ASMHe visto que el IN_OUT_DELAY siempre es 1 más que lo que descuentas de CYCLES en el retardo a que se debe eso?? y porque lo inicializas ya con esos 9 de menos??
#DEFINE IN_OUT_DELAY .9 ;ciclos de demora introducidos por el call, return, cierre de NAND deben ser tenidos en cuenta) #DEFINE CYCLES (.50000 - IN_OUT_DELAY)
Ya otra cosa aprovechando. Si quisiera hacer un ajuste así pero usando interrupción, como puedo calcular el tiempo que añade la interrupción al retardo o no se puede?
Es que ahora me ha picado el gusanillo para intentar hacerlo yo en la interrupción.
;====================================================================
; Main.asm file generated by New Project wizard
;
; Created: sáb sep 14 2013
; Processor: PIC16F84A
; Compiler: MPASM (Proteus)
;====================================================================
;====================================================================
; DEFINITIONS
;====================================================================
#include p16f84a.inc ; Include register definition file
;#include lib_lcd.inc ; Incluyo la libreria lcd
;====================================================================
; Opciones
;====================================================================
__config _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF
;====================================================================
; VARIABLES
;====================================================================
PULSOS equ 0x11
V_TMR0 equ 0x12
delayl equ 0x13
delayh equ 0x14
aux equ 0x15
aux2 equ 0x16
;Define
#DEFINE IN_OUT_DELAY .13 ;ciclos de demora introducidos por el call, return, cierre de NAND deben ser tenidos en cuenta)
#DEFINE CYCLES (.50000 - IN_OUT_DELAY)
;====================================================================
; RESET and INTERRUPT VECTORS
;====================================================================
; Reset Vector
RST code 0x0
goto Start
ISR org 0x4
bcf INTCON,T0IF
incf PULSOS,F
bsf aux,T0IF ;indicar que ha ocurrrido desbordamiento
nop ;ajuste
retfie
PGM code
FRECUENCIA
;Operaciones
return
errorlevel -302
Start
;Incializamos el LCD
;call initlcd
;Incializamos las interrupciones
bsf STATUS,RP0 ; Paso al banco 1
movlw b'11101000'
movwf OPTION_REG ; Configuro el registro de opciones Preescaler a 000
movlw b'10000'
movwf TRISA
bcf STATUS,RP0 ; Vuelvo al banco 0
;LCD_PUTC 'F'
;LCD_PUTC 'R'
;LCD_PUTC 'E'
;LCD_PUTC 'C'
;LCD_PUTC 'U'
;LCD_PUTC 'E'
;LCD_PUTC 'N'
;LCD_PUTC 'C'
;LCD_PUTC 'I'
;LCD_PUTC 'M'
;LCD_PUTC 'E'
;LCD_PUTC 'T'
;LCD_PUTC 'R'
;LCD_PUTC 'O'
bcf PORTA,3 ; Cierro la entrada de frecuencia
bsf INTCON,GIE ; Activo las interrupciones globales
bsf INTCON,T0IE ; Activo la interrupcion del TMR0 por desbordamiento
reiniciar
clrf PULSOS
movlw HIGH CYCLES
movwf delayh
movlw LOW CYCLES
movwf delayl
clrf TMR0
clrf aux
bcf INTCON,T0IF
open
bsf PORTA,3 ; Abro la entrada de frecuencia
call retardo_100ms
close
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
goto $+1
bcf PORTA,3 ; Cierro la entrada de frecuencia
btfsc INTCON,T0IF ;caso extraño, pero puede ocurrir
incf PULSOS,F
movf TMR0,W ; Muevo al registro W
movwf V_TMR0 ; Almaceno el valor que hay en TMR0
goto reiniciar
;====================================================================
; Subrutinas
;====================================================================
retardo_100ms
movf aux,W ;realizar cache de variable
movwf aux2
movlw .12 ;demora básica bucle
btfss aux2,T0IF
goto noInterr ;si no se ejecutó ISR, generar ciclos de demora adicionales
check1:
btfsc aux2,T0IF
bcf aux,T0IF ;limpiar flag de interr.
nop ; para hacer par la cantidad de instrucciones del bucle
subwf delayl,F
btfsc STATUS,C
goto noCarry
movlw .1
subwf delayh,F
btfsc STATUS,C
goto retardo_100ms
return
noCarry ;compensar ciclos hasta llegar a 16 (8 x 2)
goto $+1 ; 2 ciclos
goto retardo_100ms ; 2 ciclos
noInterr
goto $+1 ; 2 ciclos
goto $+1 ; 2 ciclos
nop ; 1 ciclo
goto check1 ; 2 ciclos
;====================================================================
END