;
;					EJEMPLO 23
;
;				Autor: Mikel Etxebarria
;			(c) Microsystems Engineering (Bilbao)
;
;Ejemplo MicroPIC Trainer y Micro'PIC I/O
;
;El módulo conversor ADC. Variando la velocidad de un motor.
;
;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 la regulación de velocidad del motor CC de la tarjeta Micro'PIC I/O mediante
;PWM. Para ello, el potenciómetro AN3 de la Micro'PIC Trainer conectado a la línea RA3/AN3,
;determina la duración de la anchura del pulso. El valor de este potenciómetro es convertido
;cada 10 mS para su lectura y posterior ajuste de la anchura del pulso.
;
;La salida PWM en RC2/CCP1 se conecta a la señal Enable del motor. RB0 y RB1 determinan el
;sentido de giro.

		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	0x04		;Vector de interrupción
	
;Programa de tratamiento de la interrupción

Inter		btfss	PIR1,ADIF	;Ha sido interrupción del ADC ??
		retfie			;No, falsa interrupción
		bcf	PIR1,ADIF	;Reponer el flag del conversor
		movf	ADRESH,W
		movwf	CCPR1L		;Carga los 8 bits de más peso para el PWM
		bsf	STATUS,RP0	;Selecciona banco 1
		rrf	ADRESL,F
		rrf	ADRESL,W
		andlw	b'00110000'
		bcf	STATUS,RP0	;Selecciona banco 0
		iorwf	CCP1CON,F	;Carga los dos bits de menos peso para el PWM
		retfie

;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
		bsf	PIE1,ADIE	;Activa interrupción del convertidor
		bcf	STATUS,RP0	;Selecciona banco 0

;Se activa el ADC y se selecciona el canal RA3/AN3. Frecuencia de trabajo Fosc/32

		movlw	b'10011001'
		movwf	ADCON0		;ADC en On, seleciona canal AN3
		bcf	PIR1,ADIF	;Restaura el flag del conversor AD

;El módulo CCP1 actúa en el modo PWM.

		movlw	b'00001100'
		movwf	CCP1CON		;Módulo CCP1 en modo PWM con salida por RC2/CCP1

;El periodo del PWM para el módulo CCP1 es de 4 mS (PR2*TMR2 Preescaler*4*Tosc)

		movlw	.250
		bsf	STATUS,RP0	;Selecciona página 1
		movwf	PR2
		bcf	STATUS,RP0	;Selecciona página 0

;La anchura inicial del pulso es la mínima (1)

		movlw	.1
		movwf	CCPR1L

;El TMR2 trabaja con un preescaler de 1:16. Evoluciona cada 16 uS

		movlw	b'00000110'
		movwf	T2CON		;TMR2 en On
			
;El módulo CCP2 se configura en modo de comparación con disparo de eventos. El TMR1 se 
;resetea y se da inicio a una nueva conversión cada vez que se alcanza el valor del CCPR2.

		movlw	b'00001011'
		movwf	CCP2CON		;Modo comparación con disparo de eventos
		movlw	high .10000
		movwf	CCPR1H
		movlw	low .10000
		movwf	CCPR2L		;Carga el registro CCPR2 con 10000
		clrf	TMR1L
		clrf	TMR1H		;Inicia el TMR1

;El TMR1 actúa con oscilador interno y un preescaler de 1:1

		movlw	b'00000001'
		movwf	T1CON		;TMR1 en On
		
		movlw	b'11000000'
		movwf	INTCON		;Activa interrupciones

		movlw	b'00000010'
		movwf	PORTB		;Motor en On, giro horario

Loop		clrwdt			;Refrescar el WDT
		goto	Loop

		end			;Fin del programa fuente
