7 Manejo de Interrupciones PIC

25
1 Manejo de Interrupciones

description

Manejo de Interrupciones PIC

Transcript of 7 Manejo de Interrupciones PIC

Page 1: 7 Manejo de Interrupciones PIC

1

Manejo de Interrupciones

Page 2: 7 Manejo de Interrupciones PIC

2

7.1. Introducción Se le llama interrupción a un salto especial a una subrutina que no está contemplado en un

punto específico del programa principal, sino que puede ocurrir en cualquier punto de éste y

no es provocado por una instrucción en el programa, sino por un evento interno o externo al

sistema del microcontrolador.

Es decir, una interrupción es una técnica particular del PIC que permite: interceptar eventos

externos de un programa en ejecución, interrumpiendo momentáneamente la operación del

programa, controla el evento con una subrutina apropiada, y retorna para continuar con la

ejecución del programa en el punto donde se produjo la interrupción.

Los dispositivos que manejan eventos capaces de provocar una solicitud de

interrupción se denominan fuentes de interrupción. La familia del PIC16F87x cuenta con hasta

14 fuentes de interrupción, de las cuales algunas de ellas se habilitan por medio del registro de

control INTCON, otras, sin embargo, como la del convertidor A/D se encuentra en el registro

PIE1, en este mismo registro está el bit del TIMER1 (TMRIE ,PIE1<0>) entre otros.

En el registro INTCON sólo se encuentran tres controles de interrupciones. Interrupciones

ocasionadas en la patilla RBO/INT, las ocasionadas por cambios de estado en las patillas

RB7:RB4 y las que tienen lugar por el desbordamiento del temporizador TMR0, el resto de los

controles de periféricos y funciones especiales se encuentran en los registros PIR1, PIR2.

El bit GIE (INTCON<7>) habilita las interrupciones no enmascaradas, por el contrario, cuando

está a cero, deshabilita todas las interrupciones con independencia de cómo se encuentren los

bits individuales de interrupciones.

Cuando tiene lugar una interrupción, el valor del Contador de Programa (PC) se envía al Stack y

se carga con 0004 hex (vector de interrupción). El microcontrolador comenzar a ejecutar las

instrucciones de la subrutina de interrupciones y cuando se encuentre una instrucción RETFIE

dará por finalizada la subrutina volviendo a la siguiente dirección de la última instrucción

ejecutada antes de producirse la interrupción.

Hay que tener en cuenta que cuando se produce un Reset se borra el bit GIE, por lo que se

deshabilitan todas las interrupciones, aunque se habiliten los bits individuales.

Al atender una interrupción, el bit GIE se borra automáticamente con lo que se deshabilita la

posibilidad de futuras interrupciones, la dirección de retorno se envía al Stack y el Contador de

Programa se carga con la dirección 0004 hex. (vector de interrupción). En esta dirección

comenzará la subrutina de servicio de interrupciones. Para determinar qué periférico o función

ha ocasionado la interrupción se deberán leer los bits de control de las correspondientes

interrupciones

Cada fuente de interrupción posee dos bits asociados a ella:

• Una Bandera (terminada en F) de Interrupción, la cual es activada (en alto) por el

evento para solicitar una interrupción.

• Una Máscara (terminada en E) Local de Interrupción, la cual si está desactivada (en

bajo) bloqueará la solicitud de interrupción correspondiente, pero si está activada

Page 3: 7 Manejo de Interrupciones PIC

3

(en alto) permitirá la solicitud de Interrupción.

• Además existe una máscara de interrupción global GIE (INTCON<7>), la cual

bloqueará todas las solicitudes de interrupción si está desactivada (GIE=0).

• Algunas fuentes de interrupción también poseen una segunda máscara de

interrupción global denominada PEIE (INTCON<6>). De hecho, actúa sobre

todas las fuentes de interrupción, excepto las interrupciones debidas a la patita INT,

el sobre flujo del Timer 0 y las interrupciones del puerto B (INTF, T0IF y RBIF).

De acuerdo a lo anterior, la única manera en que una solicitud de interrupción provoca en

efecto una interrupción en el programa es cuando:

• La máscara global está activada (GIE=1).

• (En su caso) la máscara global de periféricos está activada (PEIE=1)

• La máscara local está activada

• Ocurre un evento que activa la bandera correspondiente.

7.2. Tipos de Eventos y Bits de Habilitación

En el registro INTCON sólo se encuentran tres controles de interrupciones:

1. Un cambio de estado sobre la línea RB0 ( pin de interrupción externa RB0/INT )

2. Desbordamiento de la cuenta del registro TMR0 ( TMR0 overflow interrupt )

3. Un cambio de estado sobre una de las líneas de RB4 a RB7 ( PORTB change interrupts ).

Los cuales se describen a continuación:

1. Interrupción de TMR0

Si el temporizador TMR0 se ha desbordado, el flag de overflow (T0IF) del registro

INTCON se habrá puesto a uno. Es evidente que previamente se habrán borrado todos

los flags que pudieran ocasionar una interrupción, así se evitarán interrupciones

recursivas. Para habilitar esta interrupción se debe poner en 1 el bit T0IE.

2. Interrupción externa por RB0/INT

Las transiciones de bajo a alto, o viceversa, de la patilla RB0/INT puede ocasionar una

interrupción, el flanco que la producirá se elige con el bit INTEDG

(OPTION_REG<6>). Cuando este bit se pone a uno, la interrupción tendrá lugar en la

transición de cero a uno, por el contrario, el flanco de bajada ocasionará la interrupción

cuando el bit se coloque a cero. En cuanto tenga lugar en la patilla RB0/INT el flanco

elegido, el bit INTF (INTCON<1>) se pondrá a uno; el estado de los bits de

interrupciones globales (GIE) e interrupción externa (INTE) determina si se atenderá o

no la interrupción. Si están habilitadas y el microcontrolador se encuentra en reposo

(Sleep) éste despertará.

3. Interrupción por cambio de estado en RB4:RB7

Además de la interrupción externa descrita, estos microcontroladores se disponen de otro

modo de ocasionar una interrupción externa; cualquier cambio de estado que se produzca

Page 4: 7 Manejo de Interrupciones PIC

4

en las patillas RB7:RB4 también la ocasionará, para habilitarla, hay que poner a uno el

flag de interrupciones RBIE (INTCON<3>). Cualquier cambio de estado que haya en

estas patillas hará que el bit RBIF (INTCON<0>) se ponga a uno y se produzca la

interrupción.

Para que el sistema pueda ocasionar una interrupción por cambios de estado en las

patillas RB7:RB4 es necesario realizar algunas actuaciones previas que no son necesarias

en otro tipo de interrupciones ya que el estado de estas cuatro patillas es comparado

continuamente, en la fase Q1 del reloj, con el estado previo de los latch del puerto. Por

consiguiente, antes de habilitar esta interrupción habrá que leer o escribir en él para que

su contenido se quede almacenado en los latch; solamente los bits configurados como

entradas se comparan y si son diferentes a los previamente almacenados pueden

ocasionar una interrupción.

El resto de los controles de periféricos y funciones especiales se encuentran en los registros

PIR1, PIR2 (Banderas) y PIE1, PIE2 (Mascaras).

Una interrupción de cualquiera de estos eventos puede ser conseguida habilitando o

deshabilitando independientemente los siguientes bits de los registro INTCON, PIR1 y, PIR2:

• INTE. Si este bit está en 1 habilitará la interrupción de cambio de estado sobre la línea

RB0

• T0IE. Si este bit está en 1 habilitará la interrupción de final de conteo del registro

TMR0

• RBIE. Si este bit está en 1 habilitará la interrupción de cambio de estado sobre una de

las líneas de RB4 a RB7

• EEIE. Si este bit está en 1 habilitará la interrupción de final de escritura sobre la

EEPROM

• PSPIE. Si este bit está en habilitará la interrupción por lectura/escritura en el PSP

• ADIE. Si este bit está en 1 habilitará la interrupción del convertidor A/D

• RCIE. Si este bit está en 1 habilitará interrupción por recepción en el USAR

• TXIE. Si este bit está en 1 habilitará la interrupción de transmisión por el USAR

• SSPIE. Si este bit está en 1 habilitará la interrupción del SSP

• CCP1IE. Si este bit está en 1 habilitará la interrupción del CCP1

• TMR2IE. Si este bit está en 1 habilitará la interrupción por desbordamiento de TMR2

emparejado a PR2

• TMR1IE. Si este bit está en 1 habilitará la interrupción por desbordamiento de TMR1

• CCP2IE. Si este bit está en 1 habilitará la interrupción de CCP2

• BCLIE. Si este bit está en 1 habilitará la interrupción por colisión de bus SSP

Existe otros dos bits de habilitación:

• Interrupción global GIE (INTCON<7>), la cual bloqueará todas las solicitudes de

interrupción si está desactivada (GIE=0) y si este bit está en 1 habilitará todas las

interrupciones.

• Algunas fuentes de interrupción también poseen una segunda máscara de

interrupción global denominada PEIE (INTCON<6>). De hecho, actúa sobre

todas las fuentes de interrupción, excepto las interrupciones: debidas a la patita INT,

Page 5: 7 Manejo de Interrupciones PIC

5

el sobreflujo del Timer 0 y las interrupciones del puerto B (INTF, T0IF y RBIF).

7.3. Vector de Interrupción y Control de Interrupción Cualquier evento que sea habilitado, o se manifieste, el PIC interrumpe la ejecución del

programa, almacena automáticamente en el STACK el valor actual del PROGRAM

COUNTER y este pasa a ejecutar la instrucción presente en la dirección de memoria 0004H,

denominada Interrupt Vector ( vector de interrupción ). Por lo tanto, desde este punto debemos

colocar la llamada a la subrutina de control denominada Interrupt Handler ( control de

interrupción ).

Se puede habilitar varias interrupciones simultáneamente, porque la primera providencia del

control de interrupción es la de verificar cuál evento habilitado genera la interrupción de la

ejecución de parte del programa. Este control puede ser efectuado utilizando Interrupt Flag (

bandera de interrupción ).

7.4. Bandera de Interrupción

Dado que cualquier interrupción genera una llamada a la dirección 04H, en los registros

INTCON, PIR1 y PIR2 está presente varias banderas que indican cuál evento es el que genera

la interrupción, las cuales se describen a continuación:

Interrup. Descripción Registro

INTF Externa. Se coloca en 1 cuando la interrupción INT ocurre, es decir cuando

cambia de estado la línea RB0. INTCON

T0IF Desbordamiento del TMR0. Se coloca en 1 cuando el TMR0 pasa de 00FFh

a 00h, es decir cuando terminó de contar el timer TMR0 INTCON

RBIF

Por cambios en el PortB. Se coloca en 1 cuando una de las entradas ( RB4 a

RB7 ) cambia, es decir cuando cambia de estado de una las líneas de RB4 a

RB7 INTCON

EEIF

Finalización de escritura en la memoria EEPROM. Se coloca EEIF en 1

cuando la operación de escritura ha terminado, debe ser colocada a 0 por

software. PIR2

PSPIF Lectura/Escritura puerto paralelo. PIR1

ADIF Convertidor A/D. PIR1

RCIF Recepción USAR. PIR1

TXIF Transmisión USAR. PIR1

SSPIF Puerto Serie Síncrono. PIR1

CCP1IF Capturador/Comparador 1. PIR1

TMR2IF Temporizador TMR2. PIR1

TMR1IF Temporizador TMR1. PIR1

CCP2IF Capturador/Comparador 2. PIR2

BCLIF Indica la colisión en el bus SSP PIR2

Importante. Una vez conocida cual de las banderas está activada, el control de interrupción

debe generar la interrupción correspondiente.

7.5. Retorno de un control de interrupción

Page 6: 7 Manejo de Interrupciones PIC

6

Cuando se genera una interrupción el PIC deshabilita automáticamente el bit GIE ( Global

Interrupt Enable ) del registro INTCON, de modo que deshabilita todas las interrupciones

restantes. Para poder retornar al programa principal y reinicializar este bit se debe utilizar la

instrucción:

RETFIE

7.6. Proceso de reconocimiento de una interrupción

Cuando se cumplen las siguientes tres o cuatro condiciones simultáneamente:

• El bit GIE está activado (en alto)

• El bit PEIE está activado (en alto), en las respectivos eventos

• Se produce un evento que solicita interrupción (se activa alguna de las banderas de

interrupción)

• Está activada la máscara correspondiente a la bandera activada.

Entonces la CPU es interrumpida inmediatamente y ejecuta lo siguiente:

• Termina la ejecución de la instrucción actual.

• Desactiva el bit GIE (GIE=0) para bloquear cualquier otra solicitud de

interrupción.

• La dirección de programa de la siguiente instrucción a ejecutar es guardada en el stack.

• Ejecuta un salto a la localidad de programa 0004h denominada vector de

interrupción, en donde el usuario deberá haber colocado el inicio de la rutina de

atención a la interrupción.

• Ejecuta la rutina de atención a la interrupción escrita por el usuario, en la cual éste

podrá constatar la fuente de interrupción consultando por poleo las banderas de

interrupción.

• La rutina de atención a la interrupción deberá limpiar los bits de las banderas que

solicitó la interrupción antes de rehabilitar las interrupciones, para evitar

interrupciones recursivas.

• La rutina de atención deberá terminar con una instrucción RETFIE, la cual activa

nuevamente el bit GIE (GIE=1) y lee el stack para continuar la ejecución del

programa que fue interrumpido en la siguiente instrucción.

7.7. Diagrama lógico de las interrupciones

La lógica de activación de máscaras y banderas descrita arriba puede entenderse en términos

del diagrama lógico mostrado en la siguiente figura. En este diagrama se muestran las 14

fuentes de interrupción de los microcontroladores de la familia PIC16F87x y se usan los

nombres específicos de cada fuente de interrupción para sus respectivas banderas y máscaras

de interrupción.

Page 7: 7 Manejo de Interrupciones PIC

7

La siguiente tabla se muestra las diferencias entre los dos modelos de 28 y 40 pines:

7.8. Salvar el contexto durante una interrupción

Dado que el programa principal no puede prever en qué punto será interrumpido, la

rutina de atención a la interrupción debe ser tal que no altere ninguno de los registros que

requiere paso a paso el programa principal para su operación normal. Estos registros

son los que van guardando el contexto del programa (tal como en qué banco está, el

resultado de la última operación, etc.) y son:

Registro STATUS

Registro W

Registro PCLATH (si se están usando las páginas 1, 2 o 3).

Estos microcontroladores disponen de ocho niveles de Stack y cuando se produce una

interrupción sólo se salva en él la dirección de retorno (PC).

Cualquier operación que se realice en la subrutina de interrupciones podrá destruir, o modificar,

el contenido de los datos almacenados en ciertos registros y que podrían ser necesarios cuando se

retorne de la, subrutina de servicio de interrupciones. Si esto fuera así, se deberán guardar los

datos de los registros cuyo contenido sea de interés y que vayan a ser modificados a lo largo de

la subrutina de servicio de interrupciones.

Una vez finalizada la subrutina, se deberán recuperar para que queden en su estado original. Un

ejemplo para salvar los registros de estado, W y PCLATH en memoria puede ser el siguiente:

Page 8: 7 Manejo de Interrupciones PIC

8

El siguiente es un ejemplo del código que deberá incluirse al inicio y al final de la rutina de

atención a la interrupción para salvar y recuperar el contexto:

;* Salva información de contexto previo a la ruitna de atención a la interrupción

MOVWF W_Temp ;Salva el registro W en en un registro temporal

SWAPF STATUS,W ;Copia STATUS en W (usa SWAP para no alterarlo al copiarlo)

CLRF STATUS ;Banco cero, sin importar banco actual

MOVWF STATUS_temp ;Salva STATUS en STATUS_temp (Banco 0)

; MOVF PCLATH,W ;sólo se requiere si se están usando las páginas 1,2,y/o 3

; MOVWF PCLATH_temp ;salva PCLATH

; CLRF PCLATH ;página 0 sin importar página actual ...

;aquí se escribe el código de la rutina de atención a la interrupción

...

;* A continuación restablece la información de contexto que salvó al inicio

; MOVF PCLATH_Temp.,W ;rescata PCLATH

; MOVWF PCLATH ;si se usan las paginas 1,2 y/o 3

SWAPF STATUS_temp,W ;rescata el STATUS original

MOVWF STATUS ;restablece banco original

SWAPF W_temp,F ;rescata el W original

SWAPF W_temp,W ;sin alterar el STATUS ya rescatado.

RETFIE

El programa está dividido en dos partes, la primera guarda el contenido de los registros y se

ejecutan las instrucciones propias de la subrutina de servicio de interrupciones (comprobar quién

ocasionó la interrupción, etc.) y la segunda recupera de la memoria los registros previamente

almacenados. La instrucción RETFIE llevará el flujo del programa a la dirección siguiente a la

última instrucción ejecutada (recupera el PC del Stack) con los registros ya actualizados.

7.9. REGISTROS INVOLUCRADOS

1. REGISTRO INTCON (Dirección 0Bh, 8Bh, l0Bh, 18Bh)

El registro INTCON es un registro de lectura y escritura que contiene los bit de habilitación de

interrupciones por desbordamiento de TMR0 por cambio de nivel en el PORTB e interrupciones

externas por la línea RBO/INT. � � �

R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-x

GIE PEIE T0IE INTE RBIE T0IF INTF RBIF

Bit 7 Bit 0

bit 7: GIE: bit de habilitación global de Interrupciones

1= Habilita el permiso de interrupciones

0= Inhabilita todas las interrupciones

bit 6: PEIE: bit de habilitación de interrupciones de los periféricos que no se controla con el registro

INTCON

1= Habilita el permiso de interrupciones de los periféricos

0= Inhabilita las interrupciones de los periféricos

bit 5: T0IE: bit de habilitación de la interrupción por desbordamiento del TMR0

Page 9: 7 Manejo de Interrupciones PIC

9

1= Habilita la interrupción

0= Inhabilita la interrupción

bit 4: INTE: bit de habilitación de la interrupción externa por el pin RB0/INT

1= Habilita la interrupción

0= Inhabilita la interrupción

bit 3: RBIE: bit de habilitación de interrupción por cambio de nivel en el PORTB

1= Habilita la interrupción

0= Inhabilita la interrupción

bit 2: T0IF: flag de indicación de desbordamiento de TMR0

1= El TMR0 se ha desbordado. Se borra por software

0= El TMR0 no se ha desbordado

bit 1: INTF: flag de estado de la interrupción externa INT

1= La interrupción externa se ha producido. Se borra por software

0= La interrupción externa no se ha producido

bit 0: RBIF: flag de indicación de interrupción por cambio de nivel en PORTB

1= Se ha producido un cambio de nivel en los pines RB7:RB4. Se borra por software.

0= No se ha producido un cambio de nivel en los pines RB7:RB4

2. REGISTRO PIR1 (Dirección 0Ch)

El registro de PIR1 contiene los flags individuales que indican las interrupciones provocadas por

los periféricos.

� � � � � � � �

R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-x

PSPIF ADIF RCIF TXIF SSPIF CCP1IF TMR2IF TMR1IF

Bit 7 Bit 0

bit 7: PSPIF: Flag de Lectura/Escritura por el Puerto Paralelo esclavo

1= Concedido el permiso de interrupción para la puerta paralela esclava al realizar una

operación de Lectrura/Escritura. En los modelos de 40 pines 0= No está permitida la interrupción

bit 6: ADIF: Flag de final de conversión del convertidor A/D

1= El convertidor A/D ha finalizado la conversión

0= El convertidor A/D no ha finalizado la conversión

bit 5 RCIF: Flag de recepción por el USAR

1= El buffer de datos recibidos por el USAR está lleno

0= El buffer de datos recibidos por el USAR no está lleno

bit 4: TXIF: Flag de transmisión el USAR

1= El buffer de datos a transmitir no está lleno

0= El buffer de daos a transmitir está lleno

Page 10: 7 Manejo de Interrupciones PIC

10

bit 3: SSPIF: Flag de interrupción del Puerto Serie Síncrono (SSP)

1= La condición del SSP ha ocurrido, debe ponerse a cero por software antes de volver

del programa de atención a la interrupción. Las condiciones que soporta este bit son: SPI

Ha tenido lugar una Transmisión / Recepción I2C Slave

Ha tenido lugar una Transmisión / Recepción

I2C Master Ha tenido lugar una Transmisión / Recepción

La condición de salida iniciada se completó por el módulo de SSP.

La condición de parada inicio se completó por el módulo de SSP.

La condición de reinicialización se completo por el módulo SSP

Una condición de la salida se ha realizado mientras el módulo de SSP estaba en estado de

espera (sistema de Multimaster).

0 = no ha ocurrido ninguna condición de interrupción del módulo SSP

bit 2: CCP1IF: Flag de interrupción de CCPI Modo Captura

1= Ocurrió una captura de TMR1 (debe ponerse a cero por software)

0= No ocurrió ninguna captura de TMR1 Modo Comparación

1= Se ha realizado una comparación de TMR1 Con el registro emparejado /debe ponerse

a cero por Software)

0= No se ha realizado comparación Modo PWM

Este modo no se utiliza

bit 1: TMR2IF: Flag de interrupción de TMR2 emparejado con PR2

1= TMR2 emparejado con PR2 ocurrió (debe ponerse a cero por software)

0= No ha ocurrido el emparejamiento de TMR2 con PR2

bit 0: TMR1IF: Flag de desbordamiento de TMRI

1 =el registro se desbordo (debe ponerse a cero por software) 0 = el registre¡ de TMRI no se desbordo

Nota 1. PSPIF está reservado para los dispositivos de 28 pines; se mantiene siempre a cero.

3. REGISTRO PIR2 (Dirección 0Dh)

El registro de PIR2 contiene los flags que indican la interrupción del CCP2, de la colisión del

bus SSP y la interrupción de la escritura en la EEPROM

� � � � � � � �

U-0 R/W-0 U-0 R/W-0 R/W-0 U-0 U-0 R/W-x

--- (1) --- EEIF BCLIF --- --- CCP2IF

Bit 7 Bit 0

bit 7: No implementado: se lee como “0”

bit 6: Reservado: Mantiene este bit siempre a cero

Page 11: 7 Manejo de Interrupciones PIC

11

bit 5: No implementado: se lee como “0”

bit 4: EEIF: Flag que indica si se ha producido escritura en al EEPROM

1 = Se ha completado la escritura en la EEPROM (Se pone a cero por software)

0 = No se ha finalizado la escritura o no se ha comenzado

bit 3: BCLIF: Flag que indica la colisión en el bus

1 = Se ha producido una colisión en el bus SSP, cuando se configura en el modo I2C Master.

0 = No se ha producido colisión en el bus

bit 2-1:No implementados: se leen como “0”

bit 0: CCP21F: Flag de ininterrupción de CCP2

Modo Captura

1 = Ha ocurrido una captura del registro TMR1 (debe ponerse a cero por software)

0= No se ha producido captura

Modo Comparación

1 = Se ha producido una comparación de TMR1 con su pareja (debe ponerse a cero por

software).

0 = No se ha producido comparación

Modo PWM

No se utiliza

4. REGISTRO PIE1 (Dirección 8Ch)

Este registro contiene los bits individuales de habilitación de interrupciones de los periféricos.

Nota. El bit PEIE (INTCON <6>) debe esta a uno para habilitar las interrupciones de cualquiera

de los periféricos.

R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0

PSPIE(1)

ADIE RCIE TXIE SSPIE CCP1IE TMR2IE TMR1IE

Bit 7 Bit 0

bit 7: PSPIE: bit de habilitación de interrupción por lectura / escritura en el Puerto Paralelo Esclavo.

Para los modelos de 40 pines.

1 = Habilita la interrupción por lectura/escritura en el PSP

0= inhabilita la interrupción por lectura/escria en el PSP

bit 6: ADIF: bit de habilitación de interrupción por finalización de la conversión A/D

l = Habilita la interrupción del convertidor A/D

0 = Inhabilita la interrupción del convertidor A/D

bit 5: RCIE: bit de habilitación de interrupción en recepción por el USAR, cuando se llena el buffer,

1 = Habilita interrupción por recepción en el USAR

0 = Inhabilita interrupción por recepción en el USAR

bit 4: TXIE: bit de interrupción al transmitir por el USAR, cuando se vacía el buffer.

Page 12: 7 Manejo de Interrupciones PIC

12

1 = Habilita la interrupción de transmisión por el USAR

0 = Inhabilita la interrupción de transmisión por el USAR

bit 3: SSPIE: bit de habilitación de interrupción por el Puerto Serie Síncrono (SSP)

1= Habilita la interrupción del SSP

0= Inhabilita la- interrupción del SSP

bit 2: CCP1IE: bit de habilitación de interrupción del módulo CCPI cuando se produce una captura o

una comparación.

1= Habilita la interrupción del CCPI

0=. Inhabilita la interrupción del CCPI

bit 1: TMR2IE: bit de habilitación de interrupción por desbordamiento de TMR2 que

está emparejado con el registro PR2 (92h)

1= Habilita la interrupción por desbordamiento de TMR2 emparejado a PR2

0= Inhabilita la interrupción de TMR2 emparejado a PR2

bit 0: TMR1IE: bit de habilitación de interrupción por desbordamiento del TMRI

1= Habilita la interrupción por desbordamiento de TMR1

0= Inhabilita la interrupción por desbordamiento de TMR1

Nota 1. PSPIE para los dispositivos de 28 pines, siempre mantiene este bit a cero.

5. REGISTRO PIE2 (Dirección 8Dh)

El registro de PIE2 contiene los bits individuales que habilita las interrupciones del periférico

CCP2, la interrupción por colisión del SSP y la interrupción de escritura en la EEPROM.

U-0 R/W-0 U-0 R/W-0 R/W-0 U-0 U-0 R/W-0

--- 0 --- EEIE BCLIE -- -- CCP2IE

Bit 7 Bit 0

bit 7: No implementado: se lee como “0’

bit 6 Reservado, Mantiene este bits a cero

bit 5: No implementado: se lee como “0”

bit 4: EEIE: Habilita la interrupción por escritura en la EEPROM de datos

1= Habilita la interrupción por escritura de la EEPROM de datos

0 =Deshabilita la interrupción por escritura en la EEPROM de datos

bit 3: BCLIE: Habilita la interrupción por colisión en el bus SSP cuando dos o más maestros tratan de

transferir al mismo tiempo.

1 = Habilita la interrupción por colisión de bus SSP

0 = Deshabilita la interrupción por colisión en el bus SSP.

bit 2-1 No implementados, se leen como “0”

Page 13: 7 Manejo de Interrupciones PIC

13

bit 0: CCP2IE: Habilita la interrupción del modulo CCP2

1 = habilita la interrupción de CCP2

0 = inhabilita la interrupción de CCP2

Ejemplo 1

Medidor de periodo mejorado por Interrupciones

Como ya se dijo para el ejemplo Medidor de periodo del Modo captura, éste tiene

limitantes muy grandes especialmente en el límite superior de frecuencia que n o puede

procesar correctamente, debido a que durante el tiempo empleado en la transmisión del

dato no puede detectar ninguna transición de la señal de entrada. Esto puede corregirse si

primero se detecta la captura y con la interrupción de ésta se realiza la transición. La

modificación se muestra en el siguiente listado.

;****************************************************************

;* Este programa mide el periodo de una señal oscilatoria en la *

;* patita RC2/CCP1. Por INTERRUPCIONES generadas por la captura *

;* de cada transición de 0 a 1 en dicha patita. *

;* El valor de periodo capturado representa el número de ciclos *

;* Tcy por periodo. Dicho valor se envía continuamente por *

;* el puerto serie. Se supone un cristal de 14.7456 Mhz *

;****************************************************************

Include "p16f877.inc"

msnib EQU 0x20

lsnib EQU 0x21 STATUS_temp EQU 0x70

W_temp EQU 0x71

org 0x0000 ;inicia con un reset

GOTO inic

org 0x0004 ;vector de interrupción

GOTO interr ;salta a la rutina de atención a la interrupción

inic CALL initrans ;inicializa puerto serie como transmisor

BSF STATUS,RP0 ;Banco1

BSF TRISC,2 ;patita RC2/CCP1 como entrada

BCF STATUS,RP0 ;Banco 0

MOVLW 0x01

MOVWF T1CON ;Configura Timer1 modo temporizador, preesc 1/1

CLRF TMR1H ;Inicializa en cero el timer 1

CLRF TMR1L ;apaga el módulo CCP para inicializar

CLRF CCP1CON ;limpia latch de CCP1

BSF CCP1CON,CCP1M2 ;Habilita modulo CCP1 para modo de captura

BSF CCP1CON,CCP1M0 ;en transición de subida

BCF PIR1,CCP1IF ;limpia bandera de interrupcion.

BSF STATUS,RP0 ;banco 1

BSF PIE1,CCP1IE ;Habilita interrupciones del CCP1

BCF STATUS,RP0 ;banco 0

BSF INTCON,PEIE ;Habilita interrupciones de periféricos

BSF INTCON,GIE ;Habilita interrupciones globales

;** Programa principal:

;** Lazo infinito

main

GOTO main ;repite

;***** rutina de atención a la interrupción

interr

MOVWF W_temp ;salva contexto

SWAPF STATUS,W

Page 14: 7 Manejo de Interrupciones PIC

14

CLRF STATUS

MOVWF STATUS_temp

;Envío a la PC

MOVF CCPR1H,W ;copia periodo capturado

CALL Envbyte ;y lo envía por el puerto serie

MOVF CCPR1L,W

CALL Envbyte

MOVLW 0x0D ;envía separador CALL envia

MOVLW 0x0A

CALL envia

;Checa bandera CCP1IF y pone TMR1 = 0

BTFSS PIR1,CCP1IF ;checa bandera de captura de evento

GOTO ret ;si no es bandera de captura retorna

BCF PIR1,CCP1IF ;si es bandera de captura, la limpia

CLRF TMR1L ;limpia la cuenta del timer 1

CLRF TMR1H

ret SWAPF STATUS_temp,W ;restablece contexto

MOVWF STATUS

SWAPF W_temp,F

SWAPF W_temp,W

RETFIE

;***************************************************************

; Subrutina que envía el byte en W por el puerto serie, separado

; en los códigos ASCII de sus dos nibbles hexadecimales

;***************************************************************

Envbyte:

MOVWF msnib ;pone byte en msnib

MOVWF lsnib ;y una copia en lsnib

SWAPF msnib,1 ;intercambia nibbles en lsnib

MOVLW 0x0F ;máscara para limpiar el nibble alto ANDWF msnib,1 ;limpia parte alta de msnib

ANDWF lsnib,1 ;limpia parte alta de lsnib

MOVF msnib,W ;carga msnib en W

CALL asc ;obtiene código ASCII equivalente

CALL envia ;lo envía por el puerto serie

MOVF lsnib,W ;carga lsnib en W

CALL asc ;obtiene código ASCII equivalente

CALL envia ;lo envía por el puerto serie

RETURN

asc ADDWF PCL,1 ;Calcula el código a retornar

;Saltando W instrucciones adelante

DT "0123456789ABCDEF"

;****************************************************************

;Subrutina para inicializar el puerto serie USART como transmisor

;a 9600 Bauds, considerando un cristal de reloj de 14.7456 MHZ

;****************************************************************

initrans:

BCF STATUS,RP1

BSF STATUS,RP0 ;banco 1

BCF TXSTA,BRGH ;pone bit BRGH=0 (velocidad baja)

MOVLW 0x17 ;valor para 9600 Bauds (Fosc=14.7456 Mhz)

MOVWF SPBRG ;configura 9600 Bauds

BCF TXSTA,SYNC ;limpia bit SYNC (modo asíncrono)

BSF TXSTA,TXEN ;pone bit TXEN=1 (habilita transmisión) BCF STATUS,RP0 ;regresa al banco 0

BSF RCSTA,SPEN ;pone bit SPEN=1 (habilita puerto serie)

RETURN

;***************************************************************

;Subrutina para enviar el byte guardado en W por el puerto serie

;***************************************************************

Page 15: 7 Manejo de Interrupciones PIC

15

envia BSF STATUS,RP0 ;banco 1

esp BTFSS TXSTA,TRMT ;checa si el buffer de transmisión

GOTO esp ;si está ocupado espera

BCF STATUS,RP0 ;regresa al banco 0

MOVWF TXREG ;envía dato guardado en W

RETURN

end

Análisis del código

En primer lugar configuramos el registro T1CON, CCP1CON, PIR1, PIE1 e INTCON.

Registro T1CON

T1CON=0x01

--- --- T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON

0 0 0 0 0 0 0 1

Bit 7 Bit 0

Divisor de frecuencia del preescaler a 1/1,

T1CKPS1=0

T1CKPS0=0

TMR1CS=0, selección de la fuente de reloj a modo temporizador

TMR1ON=1, habilitación del Timer1

Registro CCP1CON:

--- --- CCP1X CCP1Y CCP1M3 CCP1M2 CCP1M1 CCP1M0

0 0 0 1 0 1

Bit 7 Bit 0

configurado el Módulo CCP1 para modo captura por flanco ascendente en RCy/CCPx, como se muestra

en la siguiente figura:

CCP1M3=0

CCP1M2=1

CCP1M1=0

CCP1M0=1

Registro PIR1:

Limpia la bandera de interrupción.

BCF PIR1,CCP1IF ;limpia bandera de interrupcion.

Registro PIE1:

Habilita interrupciones del CCP1.

BSF PIE1,CCP1IE ;Habilita interrupciones del CCP1

Page 16: 7 Manejo de Interrupciones PIC

16

Registro INTCON:

Habilita interrupciones de periféricos y habilita interrupciones globales.

BSF INTCON,PEIE ;Habilita interrupciones de periféricos

BSF INTCON,GIE ;Habilita interrupciones globales

Programa principal. Este programa mide el periodo de una señal oscilatoria en la patita RC2/CCP1.

El valor de periodo capturado representa el número de ciclos Tcy por periodo y se envía

continuamente por el puerto serie.

Repitiendo continuamente:

main

GOTO main ;repite

Subrutina de Interrupción: interr

En primer lugar la rutina de atención a la interrupción interr, salva el contexto (W y STATUS):

MOVWF W_temp ;salva contexto

SWAPF STATUS,W

CLRF STATUS

MOVWF STATUS_temp

Aquí realiza propiamente las acciones de la subrutina de la interrupción interr. Copia periodo

capturado y lo envía por el puerto serie, luego envía el separador 0x0D y 0x0A.

A continuación checa bandera de captura de evento; si no es bandera de captura retorna, si es

bandera de captura, la limpia, y también limpia la cuenta del timer 1.

BTFSS PIR1,CCP1IF ;checa bandera de captura de evento

GOTO ret ;si no es bandera de captura retorna

BCF PIR1,CCP1IF ;si es bandera de captura, la limpia

CLRF TMR1L ;limpia la cuenta del timer 1

CLRF TMR1H

Por último, la rutina de atención a la interrupción interr reestablece el contexto (W y STATUS):

ret SWAPF STATUS_temp,W ;restablece contexto

MOVWF STATUS

SWAPF W_temp,F SWAPF W_temp,W

Subrutinas. Son tres, envbyte, initrans y envia:

envbyte, subrutina que envía el byte en W por el puerto serie, separado en los códigos ASCII de

sus dos nibbles hexadecimales.

initrans, subrutina para inicializar el puerto serie USART como transmisor a 9600 Bauds,

considerando un cristal de reloj de 14.7456 MHZ.

envia, subrutina para enviar el byte guardado en W por el puerto serie.

Page 17: 7 Manejo de Interrupciones PIC

17

Ejemplo 2

Ejemplo práctico de control de interrupción

Se toma como base de partida el código de la aplicación LED.ASM para realizar un led ( LED1 )

intermitente, en donde este programa tiene un ciclo continuo y retardo de software mediante una

subrutina Delay.

Adicionalmente, presionando una de las teclas SW1 a SW4 ubicadas en los pines RB4 a RB7

respectivamente, se accede temporalmente al LED2 con la ejecución del programa principal,

encendiéndose inmediatamente y permanece encendido por un tiempo para 3 intermitencias del

LED1, sin influenciar de manera evidente la frecuencia intermitente del LED1.

El circuito a ser realizado se presenta a continuación:

El código de este ejemplo está disponible en INTRB.ASM y se muestra a continuación:

;**************************************************

; Pic by example

; INTRB.ASM

;

;**************************************************

PROCESSOR 16F877

RADIX DEC

INCLUDE "P16F877.INC"

;Setup of PIC configuration flags

;XT oscillator

;Disable watch dog timer

;Enable power up timer

;Disable code protect

__CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

Page 18: 7 Manejo de Interrupciones PIC

18

LED1 EQU 0

LED2 EQU 1

LED3 EQU 2

LED4 EQU 3

Count EQU 0x20

Count1 EQU 0x21

nTick EQU 0x22 ;Registro utilizado para contar el número de ;intermitencias del LED 1

;Reset Vector

;Punto de inicio del programa al reset de la CPU.

ORG 00H

;Salta al cuerpo principal del programa. Puesto que el salto es

;necesario, para evitar toda la parte de código de la gestión de

;la interrupción.

goto Start

;Interrupt vector

;Punto de inicio para toda la subrutina de gestión de la

;interrupción.

ORG 04H

;**********************************************************************

; Interrupt handler

;**********************************************************************

;Accede al led 2 para segnalare che c'e' stato un interrupt

bsf PORTB,LED2

;Inicializa el contador de intermitencia del LED1

movlw 3

movwf nTick

;Encera nuevamente el flag RBIF para consentirse la 'interrupt

;de repetirse

bcf INTCON,RBIF

;Retorna al programa principal

retfie

;**********************************************************************

; Programa principal

;**********************************************************************

Start:

;Conmuta al segundo banco de la memoria para acceder a los

;registros TRISA y TRISB

bsf STATUS,RP0

;Definición del puerto B

;La línea de RB0 a RB3 vengono programmate in uscita per

;essere collegate ai quattro led

;Le linee da RB4 a RB7 vengono programmate in ingresso per

;essere collegate ai quattro pulsanti

movlw 11110000B

movwf TRISB

;Conmuta al primer banco de la memoria

bcf STATUS,RP0

Page 19: 7 Manejo de Interrupciones PIC

19

;Spegne tutti i led collegati sulla porta B

bcf PORTB,LED1

bcf PORTB,LED2

bcf PORTB,LED3

bcf PORTB,LED4

;Habilita la interrupción del cambio de estado de las líneas

;RB4,5,6,7 movlw 10001000B

movwf INTCON

;**********************************************************************

; Loop principal

;**********************************************************************

MainLoop

call Delay ;Retardo de software

btfss PORTB,LED1 ;Led acceso ?

goto TurnOnLed1 ;No, lo accende

goto TurnOffLed1 ;Si, lo spegne

;Accensione led e decremento del contatore di lampeggi

TurnOnLed1

bsf PORTB,LED1

;Controlla se LED 2 di segnalazione dell'interrupt e' gia

;acceso.

;Se e' acceso decrementa el contador nTick ad ogni lampeggio

;di LED1. Quando nTick vale 0 spegne LED 2

btfss PORTB,LED2 ;LED2 acceso ? goto MainLoop ;No, continua a lampeggiare

decf nTick,1 ;Se, decrementa nTick

btfss STATUS,Z ;nTick = 0 ?

goto MainLoop ;No, continua a lampeggiare

bcf PORTB,LED2 ;Se, apaga LED2

goto MainLoop ;Continua a lampeggiare

;Spegnimento led

TurnOffLed1

bcf PORTB,LED1 ;Spegne LED 1

goto MainLoop ;Continua a lampeggiare

;**********************************************************************

; Subroutine

;**********************************************************************

;Subroutine de retardo de software

Delay

clrf Count

clrf Count1

DelayLoop

decfsz Count,1

Page 20: 7 Manejo de Interrupciones PIC

20

goto DelayLoop

decfsz Count1,1

goto DelayLoop

return

END

El acceso al LED 2 en correspondencia al presionar una tecla es ligeramente retardado, en cuanto

a la lectura de estado de la línea RB4-RB7 no será efectuada por el hardware de control de

interrupción del programa principal a cada ciclo del lazo. El rápido retardo es devuelto por la

presencia de la subrutina Delay dentro del lazo principal.

Análisis del código INTRB.ASM

Se parte de la dirección ORG 00H que sirve para posicionar el programa a partir del vector

reset, que es la localización 0.

La primera instrucción que el PIC encuentra es un desvío incondicionado para la etiqueta Start:

ORG 00H

goto Start

seguido de una nueva dirección:

ORG 04H

Que se entra al código de una subrutina de control de interrupción:

bsf PORTB,LED2

movlw 3

movwf nTick

bcf INTCON,RBIF

retfie

Como una interrupción de control se localiza necesariamente a partir de la dirección 04H, para

evitar que siga ejecutando esta posición se debe terminar con una instrucción de salto

incondicional. El código de control de interrupción, en este caso, es muy simple y se limita a

encender el LED2, que encera el registro existente nTick con el número de intermitencias hasta

llegar al LED2, deberá apagarse y encerar el flag RBIF para permitir al circuito la generación de

una nueva interrupción.

La instrucción RETFIE permite al PIC retornar al programa principal que fue interrumpido por

la interrupción y activar la máscara GIE para permitir una nueva interrupción.

1. Generación de la interrupción cuando se presiona una tecla cualquiera

Las instrucciones que configuran el registro INTCON son las siguientes:

movlw 10001000B

movwf INTCON

Page 21: 7 Manejo de Interrupciones PIC

21

donde se coloca en uno el bit GIE ( bit 7 ) que es la habilitación global de las interrupciones y

también se pone en uno el bit RBIF ( bit 3 ) que habilita la interrupción sobre la variación de

estado de la línea RB4-RB7.

En la práctica, habiendo conectado como llaves SW1, SW2, SW3 e SW4 sobre la línea de I/O

RB4, RB5, RB6 y RB7 , con la presión de cualquiera de las teclas se produce una variación de

estado que genera una interrupción.

2. El programa principal

Realiza la operación de encender y apagar el LED1, y en cada encendido de LED1 decrementa

el contador nTich hasta llegar a cero; en correspondencia con esto será apagado el LED2.

Ejemplo 3

Ejemplo práctico de control de varias interrupciones

Para controlar varias interrupciones simultáneamente se utiliza el siguiente circuito, en donde las

interrupciones a ser controladas son: la interrupción sobre la cuenta del registro TMR0 y la

interrupción al cambio de nivel de las líneas RB4 a RB7.

La aplicación establece la ejecución de las tres siguientes tareas a una velocidad tal que se

asemeja con una ejecución paralela:

• El LED1 es intermitente con la frecuencia de retardo de software mediante una subrutina

Delay,

• El LED2 se prende por tres ciclos del LED1 cuando se presiona una tecla cualquiera de las

líneas RB4 a RB7.

• El LED3 es intermitente a una frecuencia correspondiente a la frecuencias de oscilación del

cristal 4MHz dividido para 4 y una relación 1:256, el tiempo de prendido y apagado se

establece con la cuenta de TMR0 hasta producirse overflow.

El circuito a ser realizado se presenta a continuación:

Page 22: 7 Manejo de Interrupciones PIC

22

El código de este ejemplo está disponible en DBLINT.ASM y se muestra a continuación:

;**************************************************

; Pic by example

; DBLINT.ASM

;

;**************************************************

PROCESSOR 16F877

RADIX DEC INCLUDE "P16F877.INC"

;Setup of PIC configuration flags

;XT oscillator

;Disable watch dog timer

;Enable power up timer

;Disable code protect

__CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

LED1 EQU 0

LED2 EQU 1

LED3 EQU 2

LED4 EQU 3

Count EQU 0x20

Count1 EQU 0x21

nTick EQU 0x22

;Reset Vector

;Starting point at CPU reset

ORG 00H

;Jump to the main body of program to avoid the interrupt ;handler

;code.

Page 23: 7 Manejo de Interrupciones PIC

23

goto Start

;Interrupt vector

;Starting point at CPU interrupts

ORG 04H

;**********************************************************************

; Interrupt handler ;**********************************************************************

;Check the interrupt event

btfsc INTCON,T0IF

goto IntT0IF

btfsc INTCON,RBIF

goto IntRBIF

;**********************************************************************

; TMR0 Interrupt handler

;**********************************************************************

IntT0IF

;Turn on LED3 if it's off

btfsc PORTB,LED3

goto LED3_off

bsf PORTB,LED3

goto End_ih

LED3_off

bcf PORTB,LED3

goto End_ih

;********************************************************************** ; RB4-RB7 interrupt handler

;**********************************************************************

IntRBIF

;Turn on LED 2

bsf PORTB,LED2

;Starts the LED1 blink counter

movlw 3

movwf nTick

goto End_ih

;**********************************************************************

;Reset the T0IF and RBIF flags to re-enable the interrupts

End_ih

bcf INTCON,T0IF

bcf INTCON,RBIF

;Go back to the main program

retfie

;**********************************************************************

; Main body

;**********************************************************************

Start:

;Conmuta al segundo banco de la memoria para acceder al

;registro TRISB

Page 24: 7 Manejo de Interrupciones PIC

24

bsf STATUS,RP0

;Definición del puerto B

;Definición de la línea de I/O (0=Salida, 1=Ingreso)

;Le linee da RB0 a RB3 vengono programmate in uscita per

;essere collegate ai quattro led Le linee da RB4 a RB7 vengono

;programmate in ingresso per essere collegate ai quattro

;pulsanti

movlw 11110000B

movwf TRISB

;Assegna il PRESCALER a TMR0 e lo configura a 1:256

movlw 00000111B

movwf OPTION_REG

;Commuta sul primo banco dei registri

bcf STATUS,RP0

;Spegne tutti i led collegati sulla porta B

bcf PORTB,LED1

bcf PORTB,LED2

bcf PORTB,LED3

bcf PORTB,LED4

;Abilita l'interrupt sul TMR0 e sul cambiamento di stato delle

;linee RB4,5,6,7

movlw 10101000B

movwf INTCON

;********************************************************************** ; Loop principale

;**********************************************************************

MainLoop

call Delay ;Ritardo software

btfss PORTB,LED1 ;Led acceso ?

goto TurnOnLed1 ;No, lo accende

goto TurnOffLed1 ;Si, lo spegne

;Accensione led e decremento del contatore di lampeggi

TurnOnLed1

bsf PORTB,LED1

;Controlla se LED 2 di segnalazione dell'interrupt e' gia

;acceso.

;Se e' acceso decrementa il contatore nTick ad ogni lampeggio

;di LED1. Quando nTick vale 0 spegne LED 2

btfss PORTB,LED2 ;LED2 acceso ?

goto MainLoop ;No, continua a lampeggiare

decf nTick,1 ;Si, decrementa nTick btfss STATUS,Z ;nTick = 0 ?

goto MainLoop ;No, continua a lampeggiare

bcf PORTB,LED2 ;Si, spegne LED2

goto MainLoop ;Continua a lampeggiare

Page 25: 7 Manejo de Interrupciones PIC

25

;Spegnimento led

TurnOffLed1

bcf PORTB,LED1 ;Spegne LED 1

goto MainLoop ;Continua a lampeggiare

;**********************************************************************

; Subroutine

;**********************************************************************

;Subroutine di ritardo software

Delay

clrf Count

clrf Count1

DelayLoop

decfsz Count,1

goto DelayLoop

decfsz Count1,1

goto DelayLoop

return

END

Análisis del código DBLINT.ASM

El control de interrupción verifica el evento generado por una interrupción, por lo cual, se debe

realizar una verificación para determinar qué evento fue generado, esto se obtiene con las

siguientes instrucciones:

btfsc INTCON,T0IF

goto IntT0IF

btfsc INTCON,RBIF goto IntRBIF

en donde los flags T0IF y RBIF serán controlados para ver si el evento que provoca la

interrupción proviene del registro TMR0 o del puerto RB4-RB7 respectivamente, y luego será

puesta en ejecución la subrutina de control a partir de las etiquetas intT0IF e intRBIF.

Además, antes de devolver el control al programa principal se debe encerar los flag T0IF y

RBIF, para asegurar que el próximo evento pueda generar interrupción.