Sei sulla pagina 1di 6

8.

Interrupciones
Con las interrupciones en un microcontrolador vamos a poder hacer que el dispositivo pare de
repente la tarea que está realizando para que haga o realice una función con urgencia y después
continúe haciendo su rutina habitual. Por ejemplo. cuando hacemos el llamado de funciones
desde el main, lo que se hace es que el programa ejecute un subprograma y luego regrese al
programa principal, sin embargo el programador esta definiendo en que momento debe saltar a
ejecutar la función mediante las instrucciones, por esta razón se considera sincronas.
Las interrupciones son desviaciones de flujo de control del programa
originadas asincrónicamente por diversos sucesos que no dependen del programador, es decir,
ocurren en cualquier momento.
Las interrupciones ocurren por sucesos externos como la generación de un flanco o nivel en un
PIN del microcontrolador o eventos internos tales como el desbordamiento de un contador,
terminación del conversor análogo a digital, entre otras.

El comportamiento del microcontrolador ante


la interrupción es similar al procedimiento que se sigue al llamar una función desde el programa
principal. En ambos casos se detiene la ejecución del programa en curso, se guarda la dirección
a donde debe retornar cuando termine de ejecutar la interrupción, atiende o ejecuta el programa
correspondiente a la interrupción y luego continua ejecutando el programa principal, desde
donde lo dejo cuando fue interrumpido.
Aqui nombramos 10 diferentes causas que producen una interrupción, por lo tanto el primer
paso de la rutina de interrupción será identificar la causa de la interrupción.

 Interrupción externa RB0/INT


 Interrupción por cambio lógico en el puerto B (pines RB7 a RB4)
 Interrupción por desborde del timer 0 (TMR0)
 Interrupción por desborde del timer 1 (TMR1)
 Interrupción por comparación exitosa exitosa en TMR2
 Interrupción del comparador
 Interrupción del transmisor del USART
 Interrupción del receptor del USART
 Interrupción del módulo CCP
 Interrupción del EEPROM
En este post vamos a tratar la interrupción externa por cambio de estado en la patica RB0.

Los pasos que se deben seguir para atender una interrupción, son los siguientes
 Digitar la función correspondiente a la interrupción. La función debe comenzar con # y la interrupción
correspondiente, por ejemplo para la función de interrupción por RB0 se digita #int_EXT
 En el programa principal, habilitar las interrupciones en forma global, con la
instrucción: enable_interrupts(GLOBAL);
 En el programa principal, habilitar la interrupción correspondiente, como ejemplo se muestra como
habilitar la interrupción externa por RB0: enable_interrupts(INT_EXT);
 Ejemplo 1
 Hacer un programa que me incremente un contador de 0 a 9, cuando ocurra una
interrupción externa por RB0. Cuando el contador llegue a 9, comienza de nuevo en
cero. (El código de implementación se encuentra al final del post)

Vemos el video donde explico el proceso del código.

Flancos de Subida y Flancos de Bajada


En algunos casos, puede interesarnos leer unicamente los flancos de subida o los flancos de
bajada de algún tren de pulsos que esté entrando al microcontrolador como lo vemos en la
siguiente imagen
Este tipo de señales es bastante común en sensores como encoders los cuales son muy
utilizados para medir posición o velocidad angular.

Para configurar la lectura del FLANCO DE SUBIDA en el Compilador CCS C Compiler


debemos utilizar el siguiente comando:

1 ext_int_edge(H_TO_L);

Para configurar la lectura del FLANCO DE BAJADA en el Compilador CCS C Compiler


debemos utilizar el siguiente comando:

1 ext_int_edge(L_TO_H);

Ejemplo 2. Medidor de Velocidad de un Motor DC


Vamos a realizar un medidor de Velocidad de un Motor DC, utilizando como sensor un
Encoder de 10 Pulsos por Revolución. Para eso vamos a necesitar configurar el MOTOR-
ENCODER del proteus dando doble click y colocando los 10 pulsos. Este ejemplo es una
adaptación del ejemplo visto en la entrada de PWM, si todavia no has estudiado el PWM te
recomiendo primero veas esa entrada (click aqui para ir a la entrada) y luego regreses aqui
para hacer la práctica del medidor de Velocidad.

A través de un potenciometro, regularemos la velocidad del motor 12VDC, utilizando un


mosfet en la etapa de potencia. El motor tiene acoplado un Encoder que entrega un tren de
pulsos. Ese tren de pulsos debe ser conectado en el PIN RB0 del PIC y por medio de la
interrupción Externa y por lectura bien sea del flanco de subida o flanco de Bajada, se debe
calcular la velocidad en RPM (Revoluciones por Minuto) y mostrarlas en una pantalla LCD. (El
código de implementación se encuentra al final del post)
Otro Tipo de Interrupciones
Existen diferentes tipos de interrupción en el microcontrolador, algunas de ellas se
mencionan a continuación:
#INT_EXT INTERRUPCIÓN EXTERNA
#INT_RTCC DESBORDAMIENTO DEL TIMER0(RTCC)
#INT_RB CAMBIO EN UNO DE LOS PINES B4,B5,B6,B7
#INT_AD CONVERSOR A/D
#INT_EEPROM ESCRITURA EN LA EEPROM COMPLETADA
#INT_TIMER1 DESBORDAMIENTO DEL TIMER1
#INT_TIMER2 DESBORDAMIENTO DEL TIMER2

Codigo de Implementación:
A continuación se presenta el Código de Implementación de los dos ejemplos de vistos en
esta entrada con relación a las interrupciones externas por RB0. Recuerda que para ver el
código, solo basta con compartir la información de este post con alguno de los siguientes tres
botones.

Código Ejemplo 1
1 #INCLUDE <16F887.H>
2 #FUSES XT,NOLVP,NOWDT,PUT
3 #USE DELAY(CLOCK=4000000)
4 Byte CONST display[10]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x67};
5 #BYTE PORTC = 7
6 #BYTE PORTB = 6
7 INT CONT=0;
8
9
10 #INT_EXT //Funcion de la Interrupcion
11 VOID INTERRUPCION()
12 {
13 DELAY_MS(200); //Retardo
14 CONT++; //Incremente la variable CONT
15 IF(CONT==10) //Si la variable CONT es igual a 10
16 CONT=0; //Ponga en cero la variable CONT
17 }
18
19 VOID MAIN()
20 {
21 SET_TRIS_B(0B11111111); //Configurar el puerto B
22 SET_TRIS_C(0); //Configurar el puerto C
23 ENABLE_INTERRUPTS(GLOBAL); //Habilita todas las interrupciones
24 ENABLE_INTERRUPTS(INT_EXT); //Habilita la interrupción externa
25 WHILE(TRUE)
26 {
27 PORTC= (display[CONT]); //Muestra lo que hay en la variable CONT en el display
28 }
29 }
Pueden descargar el código y el diseño en proteus aqui:

>>>>>8. Interrupciones<<<<<<<<

Código Ejemplo 2

1 #INCLUDE <16F887.h>
2 #DEVICE ADC=10
3 #USE DELAY(CLOCK=4000000)
4 #FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
5 #INCLUDE <LCD.C>
6
7 #BYTE PORTA= 5
8 #byte PORTB= 6
9 #byte PORTC= 7
10 #BYTE PORTD= 8
11
12 long contador=0;
13 int16 duty=0;
14 int Timer2,Poscaler;
15 double RPM;
16
17 //Interrubción por cambio en RB0
18 #INT_EXT
19 ext_isr()
20 {
21 contador++;
22 }
23 void main()
24 {
25 //Configura los Puertos del PIC
26 set_tris_a(0x01);
27 set_tris_b(0x01); //RB0 como entrada
28 set_tris_d(0);
29
30 //Configura la Entrada Analoga
31 setup_adc_ports(sAN0); //Configurar ADC (Lectura de temperatura)
32 setup_adc(adc_clock_internal); //Reloj interno para la conversion analoga digital)
33
34 //Configura el PWM
35 // Generemos una Señal cuadrada de 1 Khz
36 Timer2=249; //Se carga timer 2 con 249 como lo vimos en la pagina
37 //Preescaler=4; //Preescaler solo puede tomar valores de: 1 - 4 - 16
38 //Para el preescaler colocamos "t2_div_by_4"
39 Poscaler=1; //Preescaler solo puede tomar valores de: 1
40
41 setup_timer_2(t2_div_by_4,Timer2,Poscaler); //Configuracion de Timer 2 para establecer frec. PWM a 1kHz
42 setup_ccp1(ccp_pwm); //Configurar modulo CCP1 en modo PWM
43
44 //Habilita las Interrupcciones
45 enable_interrupts(int_ext); //Activa interrupcion por RB0
46 ext_int_edge(L_TO_H); //Activa interrupción por flanco de bajada
47 enable_interrupts(global); //Habilita interrupciones de forma global
48
49 lcd_init();
50 lcd_gotoxy(1,1);
51 LCD_PUTC("VELOCIDAD MOTOR");
52
53 //Hace por siempre
54 while(1)
55 {
56
57 //Lectura del Potenciometro
58 set_adc_channel(0); //Escoge el canal 0 de los puertos analogos
59 delay_us(100);
60 duty=read_adc(); //Almacena en duty el valor del voltaje del pot
61 set_pwm1_duty(duty);//10 bits= 1023 y 8bit= 255
62
63 //Espera por 1 segundo
64 delay_ms(999);
65
66 //Despues de 1 segundo multiplica el valor de los pulsos contados en
67 //contador y los multiplica por 60 (para pasarlo a minutos) y lo divide
68 //por el numero de pulsos que tiene el encoder, en este caso el encoder
69 //da 10 pulsos en 1 giro completo
70 RPM=contador*60/10;
71
72 //Reinicia el contador de Pulsos
73 contador=0;
74
75 //Visualiza la Velocidad
76 lcd_gotoxy(1,2);
77 printf(lcd_putc,"RPM: %f ",RPM);
78
79 }
80
81 }
Click aqui para descargar los archivos del medidor de velocidad del motor DC

>>>>Velocidad del Motor DC <<<<<<<<<


Ayuda compartiendo la información de la pagina en redes sociales, dale un like, twittea o un plus (+) en
google, para que mas personas puedan acceder a la información del sitio web.

Potrebbero piacerti anche