;
;					EJEMPLO 12
;
;				Autor: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Ejemplo MicroPIC Trainer y Micro'PIC I/O
;
;Los módulos CCPx. Modo de Captura, Medida de la duración de un pulso.
;
;El ejemplo emplea el módulo CCP1 y trata de capturar el valor del TMR1 cada vez que lleguen
;un flanco ascendente y otro descendente por la línea RC2/CCP1. Conocida la velocidad a la 
;que evoluciona el TMR1, se puede determinar el lapsus de tiempo transcurrido entre ambos
;flancos, lo que nos dará la anchura del pulso.
;
;La pantalla LCD visualiza dicho lapsus de tiempo expresado en microsegundos.
		
		List	p=16F873	;Tipo de procesador
		include	"P16F873.INC"	;Definiciones de registros internos

Lcd_var		equ	0x20		;Variables para las rutinas de manejo del LCD
Byte_L		equ	0x22		;Parte baja del byte a convertir
Byte_H		equ	0x23		;Parte alta del byte a convertir
BCD_2		equ	0x24		;Byte 2 de conversión a BCD
BCD_1		equ	0x25		;Byte 1 de conversión a BCD
BCD_0		equ	0x26		;Byte 0 de conversión a BCD
Contador	equ	0x27		;Variable de contaje
Temporal	equ	0x28		;Variable temporal
Captura		equ	0x29		;Nº de capturas
Cap_1_L		equ	0x2a
Cap_1_H		equ	0x2b		;Variables temporales para las capturas

		org	0x00		;Vector de Reset
		goto	Inicio

		org	0x04		
		goto	Inter		;Vector de interrupción

		include	"LCD_CXX.INC"	;Incluye rutinas de manejo del LCD

;Visualizar: Visualiza sobre la pantalla LCD los cinco dígitos situados en las variables
;BCD_0, BC_1 y BCD_2

Visualizar	movlw	0x80
		call	LCD_REG		;Posiciona el cursor
		movlw	3
		movwf	Contador	;Inicia contador de bytes a convertir
		movlw	BCD_0
		movwf	FSR		;Inicia puntero índice
Visual_loop	swapf	INDF,W
		andlw	0x0f
		iorlw	0x30		;Convierte a ASCII el nible de más peso
		call	LCD_DATO	;Lo visualiza
		movf	INDF,W
		andlw	0x0f
		iorlw	0x30		;Convierte a ASCII el nible de menos peso
		call	LCD_DATO	;Lo visualiza
		decf	FSR,F		;Siguiente byte
		decfsz	Contador,F
		goto	Visual_loop
		movlw	' '
		call	LCD_DATO	;Visualiza ' '
		movlw	0xe4
		call	LCD_DATO	;Visualiza micro
		movlw	'S'
		call	LCD_DATO	;Visualiza 'S'
		return

;16Bits_BCD: Esta rutina convierte un número binario de 16 bits situado en Byte_H y
;Byte_L y, en 5 dígitos BCD que se depositan en las variables BCD_0, BCD_1 y BCD_2,
;siendo esta última la de menos peso.
;Está presentada en la nota de aplicación AN544 de MICROCHIP y adaptada por Microsystems
;Engineering

Bits16_BCD	bcf	STATUS,C
		clrf	Contador	
		bsf	Contador,4	;Carga el contador con 16		
		clrf	BCD_0
		clrf	BCD_1
		clrf	BCD_2		;Puesta a 0 inicial

Loop_16		rlf	Byte_L,F
		rlf	Byte_H,F
		rlf	BCD_2,F
		rlf	BCD_1,F
		rlf	BCD_0,F		;Desplaza a izda. (multiplica por 2)
		decfsz	Contador,F
		goto	Ajuste
		return

Ajuste		movlw	BCD_2
		movwf	FSR		;Inicia el índice
		call	Ajuste_BCD	;Ajusta el primer byte
		incf	FSR,F
		call	Ajuste_BCD	;Ajusta el segundo byte
		incf	FSR,F
		call	Ajuste_BCD
		goto	Loop_16

Ajuste_BCD	movf	INDF,W		
		addlw	0x03
		movwf	Temporal	
		btfsc	Temporal,3	;Mayor de 7 el nibble de menos peso ??
		movwf	INDF		;Si, lo acumula
		movf	INDF,W		
		addlw	0x30
		movwf	Temporal
		btfsc	Temporal,7	;Mayor de 7 el nibble de menos peso ??
		movwf	INDF		;Si, lo acumula
		return

;Programa de tratamiento de la interrupción que provoca el módulo CCP1 cada vez que se
;detecta, primero un flanco ascendente y luego un descendente por la línea RC2/CCP1.

Inter		bcf	PIR1,CCP1IF	;Repone el flag del módulo CCP1
		btfsc	Captura,0	;Es la captura del flanco descendente
		goto	Medir		;Si, medir el tiempo transcurrido entre ambas
		incf	Captura,F	;No, ha sido la captura del flanco ascendente
		movf	CCPR1L,W
		movwf	Cap_1_L
		movf	CCPR1H,W
		movwf	Cap_1_H		;Salvar, temporalmente, el 1er valor capturado
		bcf	CCP1CON,0	;Capturar al flanco descendente
		retfie

Medir		movf	Cap_1_L,W	;Es la captura del flanco descendente
		subwf	CCPR1L,W
		movwf	Byte_L
		btfss	STATUS,C
		incf	Cap_1_H,F
		movf	Cap_1_H,W
		subwf	CCPR1H,W
		movwf	Byte_H		;Restar el tiempo entre la 2ª captura y la 1ª
		call	Bits16_BCD	;Convertir a BCD
		incf	Captura,F	;Capturar el 1er. flanco
		call	Visualizar	;Salida a pantalla LCD
		bsf	CCP1CON,0	;Captura al flanco ascendente
		retfie

;Programa principal

Inicio	        clrf	PORTB		;Desconecta salidas
		clrf	PORTA
		bsf	STATUS,RP0	;Selecciona banco 1
		movlw	b'00000110'
		movwf	ADCON1		;Puerta A E/S digitales
		clrf	TRISB		;Puerta B se configura como salida
		clrf	TRISA		;Puerta A salidas
		movlw	b'11111111'	
		movwf	TRISC		;Puerta C entrada
		movlw	b'11001111'
		movwf	OPTION_REG	;Preescaler de 128 asociado al WDT
		bsf	PIE1,CCP1IE	;Habilita interrupción del módulo CCP1
		bcf	STATUS,RP0	;Selecciona banco 0
	
		call	UP_LCD		;Configura puertos para el LCD
		call	LCD_INI		;Inicia el LCD
		movlw	b'00001100'
		call	LCD_REG		;LCD On, cursor y blink Off

;El TMR1 actúa en el modo temporizador con reloj interno y un preescaler 1:1. Según esto, la
;duración máxima del pulso que se puede medir será en torno a los 65mS. La mínima estará
;en torno a los 20 uS. Para otros rangos se debe seleccionar un preescaler diferente.

		movlw	b'00000001'
		movwf	T1CON		;TMR1 en On
		
		movlw	b'11000000'
		movwf	INTCON		;Habilita interrupciones

;El módulo CCP1 actúa en modo de captura al flanco ascendente

		movlw	b'00000101'
		movwf	CCP1CON		;Módulo CCP en On

		clrf	Captura		;Inicia captura en el 1er. flaco ascendente

Loop		clrwdt			;Refresca el WDT	
		goto	Loop		;Bucle infinito		

		end			;Fin del programa fuente
