;
;					EJEMPLO 22
;
;				Autor: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Ejemplo MicroPIC Trainer y Micro'PIC I/O
;
;El módulo conversor ADC. Variando la frecuencia de una señal cuadrada y su simetría.
;
;Los dispositivos PIC16F87X disponen de un convertidor A/D de 10 bits de resolución y 5 u 8 
;canales de entrada analógica. La tensión de referencia determina la resolución por bit:
;(Res. = Vref/1024). Con 5 Vref=4.8 mV/Bit; con 2.5 Vref=2.4 mV/Bit
;
;Se propone realizar una modulación de anchura de pulsos (PWM) mediante el módulo CCP1 y con
;salida de señal por la línea RC2/CCP1. El periodo se establece mediante el potenciómetro de
;la Micro'PIC Trainer conectado a RA0/AN0 y, la anchura "Duty", mediante el pontenciómetro
;conectado a RA1/AN1.
;
;El TMR2 trabajando con un preescaler de 1:1 y a una frecuencia de 4 MHz podrá generar un 
;periodo máximo de 250 uS.
;
;Un osciloscopio conectado en RC2/CCP1 podrá visualizar las variaciones de la señal de sali-
;a medida que el periodo y la anchura se modifican.

		List	p=16F873	;Tipo de procesador
		include	"P16F873.INC"	;Definiciones de registros internos

Periodo		equ	0x20		;Variable para el periodo
Duty_H		equ	0x21
Duty_L		equ	0x22		;Variable para la anchura de pulso

		org	0x00		;Vector de Reset
		goto	Inicio

		org	0x05		;Salva el vector de interrupción
	
;Programa principal

Inicio	        clrf	PORTA
		clrf	PORTB
		clrf 	PORTC
		bsf	STATUS,RP0	;Selecciona banco 1
		clrf	ADCON1		;Puerta A analógica, justificación izda.
		clrf	TRISB		;Puerta B se configura como salida
		movlw	b'00011111'
		movwf	TRISA		;RA4-RA0 entradas
		movlw	b'11111011'
		movwf	TRISC		;RC2/CCP1 salida
		movlw	b'11001111'
		movwf	OPTION_REG	;Preescaler de 128 asociado al WDT
		bcf	STATUS,RP0	;Selecciona banco 0

;Se activa el ADC y se selecciona el canal RA0/AN0. Frecuencia de trabajo Fosc/32

Loop		clrwdt	
		movlw	b'10000001'
		movwf	ADCON0		;ADC en On, seleciona canal AN0

		bcf	PIR1,ADIF	;Restaura el flag del conversor AD
		nop
		bsf	ADCON0,GO	;Inicia la conversión

ADC_Wait_0	btfss	PIR1,ADIF	;Fin de conversión ??
		goto	ADC_Wait_0	;Todavía no
		
		movf	ADRESH,w
		movwf	Periodo		;Registra valor actual para el periodo

		movlw	b'10001001'
		movwf	ADCON0		;ADC On, selecciona canal 1

		bcf	PIR1,ADIF	;Restaura el flag del conversor AD
		nop
		bsf	ADCON0,GO	;Inicia la conversión

ADC_Wait_1	btfss	PIR1,ADIF	;Fin de conversión ??
		goto	ADC_Wait_1	;Todavía no

		movf	ADRESH,W
		movwf	Duty_H		;Salva parte alta de la conversión
		bsf	STATUS,RP0	;Selecciona página 1
		rrf	ADRESL,F
		rrf	ADRESL,W
		bcf	STATUS,RP0	;Selecciona página 0
		andlw	b'00110000'
		movwf	Duty_L		;Salva parte baja de la conversión
		
;El módulo CCP1 se configura en modo PWM con salida por RC2/CCP1. Los bits LSB se obtienen
;de la variable Duty_L

		movlw	b'00001100'
		iorwf	Duty_L,F
		movwf	CCP1CON		;Modo PWM para el módulo CCP1

;El periodo se determina según el valor de la variable "Periodo". Este se carga sobre el
;registro PR2.

		movf	Periodo,W
		bsf	STATUS,RP0	;Selecciona página 1
		movwf	PR2
		bcf	STATUS,RP0	;Selecciona página 0

;La anchura del pulso o "Duty" se determina según el valor con que se cargue el registro
;CCPR1L concatenado con los bits 4 y 5 de CCP1CON. Dichos valores se obtiene de las varia-
;bles Duty_H y Duty_L respectivamente.

		movf	Duty_H,W
		movwf	CCPR1L

;Trabajando con un preescaler 1:1 y a una frecuancia de 4MHz, el TMR2 evoluciona cada 1 uS.

		movlw	b'00000100'
		movwf	T2CON		;TMR2 en On
		goto	Loop

		end			;Fin del programa fuente
