Práctica
5.b Interrupciones internas
Las
interrupciones internas son generadas por módulos contenidos en la
pastilla del microcontrolador, estos módulos pueden ser el UART, los
temporizadores(Timer), el PWM, etc. En esta práctica se verá el uso
de la interrupción generada por “Timer 1”.
En
la práctica 3 se usó el “Timer 1” para generar un retardo.
Como se recordará el “Timer” se puede ver como un contador. El
conteo lo inicia en 0 y guarda en el registro TMRx la cuenta que
lleva. El número hasta el que va a contar(periodo) lo pone el
usuario en el registro PRx, y cuando TMRx es igual a PRx se levanta
una bandera y/o se genera una interrupción. En la práctica 3, el
CPU estuvo vigilando la bandera, sin realizar otro trabajo. Esta
manera de usar el “Timer” tiene varias deficiencias, la más
importante es que el CPU está dedicado a vigilar el estado de la
bandera, otra deficiencia es que se complica obtener periodos
precisos, ya que cada vez que se inicia un periodo se lleva a cabo un
cambio de contexto en el caso de que la configuración y arranque del
“Timer” se encuentren en una función, además de los Tcy’s
necesarios para hacer las configuraciones y comparaciones al vigilar
el estado de la bandera del “Timer”.
Pasos
para configurar la interrupción del “Timer 1”
- Elegir modo, ya sea mono ó multi-vector, si es multi-vector se pone a uno el bit MVEC(12) del registro INTCON
- Se establecen las propiedades de la interrupción. En la figura 5.1, se puede ver que la interrupción generada por el “Timer 1” Tiene el vector 4, su bandera se encuentra en el bit 4 de IFS0, el bit de habilitación se encuentra en el bit 4 de IEC0 y su prioridad se fija en los bits 4, 3 y 2 del registro IPC1 y la sub-prioridad en los bits 1 y 0 del mismo registro IPC1.
- Se define la función que se ejecutará cuando se active la interrupción (DS51686E-p133). Esta función ya se encuentra predefinida y esta definición es la misma para todas las interrupciones, tanto internas como externas. En esta práctica queda definida de la siguiente manera: void __ISR(4, IPL7AUTO) invierte_led(void)
Se
usa el mismo equipo y material de la práctica 5a
El
circuito usado es el del sistema mínimo, no se requiere el circuito
que se agrega en la figura 5.1, y por lo tanto tampoco se requieren
esos componentes(“push-button” y la resistencia de 1k)
El
programa
/*
*
x32_05b.c
*
Autor: Jesus Acosta
* 12
Abril 2019
*
Ejemplo de interrupci'on timer 1
* Usa
oscilador FRCPLL
* Micro
= PIC32MX220F032B
* No
requiere el uso de plib.h
*/
#include
<p32xxxx.h>
#include
<sys/attribs.h> //Para las macros de Interrupciones
#pragma
config ICESEL = ICS_PGx2 //PGEC = pin 22
//PGED
= pin 21
#pragma
config JTAGEN = OFF // Deshabilita JTAG
#pragma
config FSOSCEN = OFF // Deshabilita oscilador secundario
#pragma
config FWDTEN = OFF // Deshabilita watchdog timer
#pragma
config FNOSC=FRCPLL // Usa oscilador FRC con PLL [8MHz]]
//#pragma
config FPLLIDIV=DIV_4 // Pero como PLL FPLLIDIV no lo divide
//
Entonces entran 4MHZ
#pragma
config FPLLMUL=MUL_16 // Multiplica por 16 [Ahora 64MHz]
#pragma
config FPLLODIV=DIV_8 // Divide entre 8 [Ahora 8MHz]
#pragma
config FPBDIV = DIV_1 // Divide entre 1 el reloj a los
//
periféricos
#pragma
config DEBUG = OFF // Se pone a ON/OFF para depuraci'on
//
usando ICD3
void
retardo1ms(void ); //Prototipo función
void
__ISR(4, IPL7AUTO) invierte_led(void); //Prototipo funci'on
int
main(void); //Prototipo funcion main
//**************
Programa principal **********************
int
main(void){
TRISACLR
= 0x0010; //Se pone a cero bit 4 de TRISA (Output)
LATASET
= 0x0010; //Se pone a uno bit LATA4
//Configura
la interrupci'on del timer 1
__builtin_disable_interrupts();
//Deshabilita todas las interrupciones
IEC0bits.T1IE
= 0; // Inhabilita interrupci'on timer 1
INTCONbits.MVEC
= 1; // Multivector habilitado
IPC1bits.T1IP
= 7; // Prioridad, 7 la mas alta
IPC1bits.T1IS
= 3; // Sub-prioridad 3, la mas alta
IFS0bits.T1IF
= 0; // Se baja bandera
IEC0bits.T1IE
= 1; // Habilita interrupci'on T1
__builtin_enable_interrupts();
//Habilita todas las interrupciones
retardo1ms();
//Se configura y arranca el “timer 1” solo una vez
//Ciclo
infinito haciendo nada
while(1){
asm("nop");
//Hace nada
}
}
void
retardo1ms(void ){
/* Se
asegura el reset del timer 1 */
T1CON =
0;
TMR1 =
0;
PR1 =
7999; //Se pone el periodo
IFS0bits.T1IF
= 0; //Baja bandera
IEC0bits.T1IE
= 1; //Habilita interrupci'on del timer 1
T1CON =
0x8000; //Configura T1CON=1000 0000 0000 0000
//con
prescaler 1:1
return;
}
//Funci'on
que se ejecuta con la interupci'on de T1
void
__ISR(4, IPL7AUTO) invierte_led(void){
LATAINV
= 0x0010; //Invierte estado bit LATA4
IFS0bits.T1IF
= 0; //Baja bandera
}
Descripción
del programa:
Esta
práctica consiste en un programa donde el CPU por única vez
configura y arranca al “Timer 1”, después se queda ejecutando un
ciclo infinito en cuyo interior solo se encuentra la instrucción
“nop” que es un periodo Tcy inactivo del CPU. Cuando PR1 y TMR1
son iguales el “Timer 1” genera una interrupción y reinicia la
cuenta poniendo a cero TMR1. La interrupción fuerza a que el CPU
abandone el ciclo infinito que estaba ejecutando y realice las
acciones que están programadas en la función asociada al “Timer
1”, esta función cambia el estado del puerto RA4. Si tenía un
uno, cambia a cero, y si tenía un cero cambia a uno. Después el CPU
regresa a continuar ejecutando el ciclo infinito.
Bibliografía:
Capítulo
7 del manual de referencia del pic32 (DS60001168K)
Capítulo
12 del manual de referencia del pic32 (DS60001168K)
Proyecto:
Realizar
un contador de revoluciones por minuto (RPM) y desplegar el resultado
en un LCD.
No hay comentarios.:
Publicar un comentario