En muchas ocasiones nuestros programas necesitan realizar varias tareas y algunas pueden ser más importantes que otras, es por eso que cuando trabajamos con interrupciones podemos declarar diferentes prioridades para ellas, entre más alta sea su prioridad más importante es la tarea a realizar, entonces si se activa una interrupción de alta prioridad, no importa lo que esté realizando nuestro programa (incluso aunque esté realizando otra función de interrupción de baja prioridad) saltará a la función correspondiente y después regresará a donde estaba.
En este caso vamos a utilizar nuestro ADC, pero activaremos las interrupciones del mismo, las cuales nos avisarán cuando el dato recibido en el ADC esté listo para ser utilizado, esta será nuestra interrupción de baja prioridad, nuestra interrupción de alta prioridad será activada por desborde de timer, el cual congelará el sistema por un segundo, sin importar lo que esté realizado nuestro programa.
Lo primero que haremos será definir los vectores tanto para las interrupciones de baja prioridad como los de alta prioridad, este dato se puede encontrar en la hoja de datos, y se hará de la siguiente forma:
ORG 0x0008 goto ISR_H ORG 0x0018 goto ISR_L
El vector 0x0008 para alta prioridad y el vector 0x0018 para baja prioridad, posteriormente definiremos lo que se hará en cada función de interrupción.
Ahora vamos a configurar tanto el timer0 como el ADC, así como las interrupciones de alta y baja prioridad.
INICIO movlw 0x00 movwf TRISJ ;Puerto B como salida ;Configuración del timer0 movlw 0x84 movwf T0CON ;Configura timer0, prescaler, 16 bits bsf INTCON,7;Habilitar interrupciones de alta prioridad bsf INTCON,5;Habilitar interrupciones por desborde movlw 0x00 movwf adc_result ;Reinicio adc_result ;Inicialización del ADC movlw 0x00 movwf TRISF ;Puerto F como salida (Paso de MiuvaPro) movlw 0xFF movwf TRISA ;Puerto A como entrada movlw 0xFE movwf ANCON0 ;Configuramos AN0 como analógico movlw 0xFF movwf ANCON1 ;Configuramos puertos digitales movlw 0x00 movwf ADCON0 ;Configuración del ADC movlw 0x08 movwf ADCON1 ;Configuración del ADC bsf ADCON0,ADON ;ADC ENABLED
Ahora habilitaremos las interrupciones asociadas a la conversión de datos del ADC, esto ser hace mediante los registros PIR1, PIE1, IPR1, INTCON, ADCON y RCON, puedes encontrar más detalle de estos registros en la sección 9 de la hoja de datos.
;INTERRUPCIONES DEL ADC bcf PIR1,ADIF ;Limpio bit bandera bsf PIE1,ADIE ;Habilito bit enable bcf IPR1,ADIP ;Limpio bit de prioridad (low priority) bsf INTCON,6 ;Habilito interrupciones baja prioridad bsf ADCON0,GO_DONE ;Comienzo conversion bsf RCON,IPEN ;Habilito niveles de prioridad
Ahora crearemos las funciones de interrupción tanto para el fin de conversión del ADC como el desborde del timer0.
ISR_H call RETARDO1s ;Congelo el sistema 1 segundo movff adc_result,PORTJ ;Muestro en los leds el valor del ADC guardado bcf INTCON,TMR0IF ;Limpia la bandera del timer bsf INTCON,7 ;Habilito interrupciones alta prioridad return ;Regreso ISR_L bcf PIR1,ADIF ;Limpia la bandera del ADC bsf INTCON,6 ;Habilita interrupciones baja prioridad movff ADRESH,adc_result ;Leo el valor del ADC movff adc_result,PORTJ ;Muestro en el puerto J el valor del ADC bsf ADCON0,GO_DONE ;Habilito conversión del ADC return
Nuestro código quedará de la siguiente forma:
LIST P = 18F87J50 ;PIC a utilizar INCLUDE <P18F87J50.INC> ;************************************************************ ;Configuración de fusibles CONFIG FOSC = HS ;Oscilador de 8MHz CONFIG DEBUG = OFF CONFIG XINST = OFF CBLOCK 0x000 contador adc_result ret1 ret2 ret3 ENDC ORG 0x0000 goto INICIO ORG 0x0008 goto ISR_H ORG 0x0018 goto ISR_L INICIO movlw 0x00 movwf TRISJ ;Puerto B como salida ;Configuración del timer0 movlw 0x84 movwf T0CON ;Configura timer0, prescaler, 16 bits bsf INTCON,7;Habilitar interrupciones de alta prioridad bsf INTCON,5;Habilitar interrupciones por desborde movlw 0x00 movwf adc_result ;Reinicio adc_result ;Inicialización del ADC movlw 0x00 movwf TRISF ;Puerto F como salida (Paso de MiuvaPro) movlw 0xFF movwf TRISA ;Puerto A como entrada movlw 0xFE movwf ANCON0 ;Configuramos AN0 como analógico movlw 0xFF movwf ANCON1 ;Configuramos puertos digitales movlw 0x00 movwf ADCON0 ;Configuración del ADC movlw 0x08 movwf ADCON1 ;Configuración del ADC bsf ADCON0,ADON ;ADC ENABLED ;INTERRUPCIONES DEL ADC bcf PIR1,ADIF ;Bit bandera de AD bsf PIE1,ADIE ;Bit de enable de AD bcf IPR1,ADIP ;Bit de prioridad de AD bsf INTCON,6 ;Habilitar interrupciones baja prioridad bsf ADCON0,GO_DONE bsf RCON,IPEN ;Habilita niveles de prioridad en las interrupciones BUCLE goto BUCLE ISR_H call RETARDO1s ;Congelo el sistema 1 segundo movff adc_result,PORTJ ;Muestro en los leds el valor del ADC guardado bcf INTCON,TMR0IF ;Limpia la bandera del timer bsf INTCON,7 ;Habilito interrupciones alta prioridad return ;Regreso ISR_L bcf PIR1,ADIF ;Limpia la bandera del ADC bsf INTCON,6 ;Habilita interrupciones baja prioridad movff ADRESH,adc_result ;Leo el valor del ADC movff adc_result,PORTJ ;Muestro en el puerto J el valor del ADC bsf ADCON0,GO_DONE ;Habilito conversión del ADC return RETARDO1s ;Se crea un retardo de 1 segundo movlw D'255' movwf ret1 movlw D'255' movwf ret2 movlw D'11' movwf ret3 Ret1s decfsz ret1, F goto Ret1s decfsz ret2, F goto Ret1s decfsz ret3, F goto Ret1s return END