PDF de programación - Mundo EDUKIT08 - Las interrupciones en lenguaje C

Imágen de pdf Mundo EDUKIT08 - Las interrupciones en lenguaje C

Mundo EDUKIT08 - Las interrupciones en lenguaje Cgráfica de visualizaciones

Publicado el 13 de Marzo del 2019
793 visualizaciones desde el 13 de Marzo del 2019
442,2 KB
6 paginas
Creado hace 14a (21/12/2009)
COMENTARIO TECNICO

“Mundo EDUKIT08”

Por:

Ing. Roberto Simone
Ingeniero de aplicaciones
[email protected]

Ing. Daniel Di Lella
D.F.A.E
www.edudevices.com.ar
[email protected]
[email protected]

(MDO_EDUKIT_017)
Las interrupciones en lenguaje “C”.....

El lenguaje C nos plantea la necesidad de estructurar de manera diferente los
programas respecto de cómo se lo hace en ensamblador (Assembler).
El tratamiento de las interrupciones no escapa a este cambio del punto de vista
y en esta ocasión proponemos un programa de referencia que usa interrupciones.

Un ejemplo didáctico

No hay mejor manera de explicar un tema que ser concreto. Para ello analizaremos una
aplicación que utiliza el módulo timer y su interrupción, creada bajo el entorno
CodeWarrior. La propuesta será hacer destellar un LED.

No daremos detalles de como crear una aplicación desde cero utilizando el asistente del
CodeWarrior, ni como iniciar los puertos. En la edición anterior tratamos estos puntos y
son una buena referencia para quienes necesiten profundizar esos conceptos.

Daremos por sentado que la aplicación se diseñará para el EDUKIT08, usando la placa
PLUGIN_AW. Con esta premisa y el archivo de proyecto creado, iniciamos mediante
el Processor Expert los siguientes periféricos:

• El reloj, para que use un cristal externo de 20MHz.

• Al COP, lo deshabilitamos.

• El PORTA.4 como pin de salida.

Es lo requerido por el EDUKIT08 para utilizar al LED 1.

Configuración del timer.

El periférico más sencillo de utilizar probablemente es el timer. Y con el Processor
Expert se hace aún más sencillo. Desde la herramienta visual de configuración
hacemos cliq con el botón derecho sobre el módulo timer 1:

Se nos despliegan varias opciones para configurar el timer. Casi todas hablan por si
solas. Alguna permite utilizar al módulo en la función Input Capture, otra como
PWM, etc. En nuestro caso adoptamos la configuración TimerInt, que produce
interrupciones por timer overflow.

Apenas seleccionemos TimerInt nos aparecerá en la mitad derecha de la pantalla las
características de módulo timer. Una de ellas, Interrupt period, estará resaltada pues
no ha sido iniciada aún y se nos está invitando a hacerlo. Para establecer el tiempo entre
interrupciones de timer, basta hacer cliq en el pequeño botón a la izquierda de la
leyenda Unassigned timing.

Se nos despliega una ventana muy completa que nos permite cargar este tiempo. En la
mitad izquierda de esta ventana podemos ingresar este tiempo, en nuestro ejemplo 1
segundo. Este asistente nos permite cargar tanto el valor absoluto de este tiempo, como
su unidad: segundos, milisegundos o microsegundos.

Como sabemos, el módulo timer no siempre logra exactamente el tiempo buscado.
Pueden existir algunos microsegundos de diferencia. Es lo que nos señala este asistente
en el rincón inferior izquierdo, donde el tiempo real será de 0,99999 segundos que
supone un error del 0,00128%. Bastante exacto ¿no?

El manejo de la ISR.

El complemento de lo anterior es la rutina de servicio de la interrupción. Para
conocer como el CodeWarrior lidia con el tema podemos abrir un archivo fuente
llamado Vectors.c. En el encontraremos la tabla de vectores de interrupción:

void (* near const _vect[])() @0xFFCC = { /* Interrupt vector table */
Cpu_Interrupt, /* Int.no. 25 Vrti (at FFCC) Unassigned */
Cpu_Interrupt, /* Int.no. 24 Viic1 (at FFCE) Unassigned */
Cpu_Interrupt, /* Int.no. 23 Vadc1 (at FFD0) Unassigned */
Cpu_Interrupt, /* Int.no. 22 Vkeyboard1 (at FFD2) Unassigned */
Cpu_Interrupt, /* Int.no. 21 Vsci2tx (at FFD4) Unassigned */
Cpu_Interrupt, /* Int.no. 20 Vsci2rx (at FFD6) Unassigned */
Cpu_Interrupt, /* Int.no. 19 Vsci2err (at FFD8) Unassigned */
Cpu_Interrupt, /* Int.no. 18 Vsci1tx (at FFDA) Unassigned */
Cpu_Interrupt, /* Int.no. 17 Vsci1rx (at FFDC) Unassigned */
Cpu_Interrupt, /* Int.no. 16 Vsci1err (at FFDE) Unassigned */
Cpu_Interrupt, /* Int.no. 15 Vspi1 (at FFE0) Unassigned */
Cpu_Interrupt, /* Int.no. 14 Vtpm2ovf (at FFE2) Unassigned */
Cpu_Interrupt, /* Int.no. 13 Vtpm2ch1 (at FFE4) Unassigned */
Cpu_Interrupt, /* Int.no. 12 Vtpm2ch0 (at FFE6) Unassigned */
Cpu_Interrupt, /* Int.no. 11 Vtpm1ovf (at FFE8) Unassigned */
Cpu_Interrupt, /* Int.no. 10 Vtpm1ch5 (at FFEA) Unassigned */
Cpu_Interrupt, /* Int.no. 9 Vtpm1ch4 (at FFEC) Unassigned */
Cpu_Interrupt, /* Int.no. 8 Vtpm1ch3 (at FFEE) Unassigned */
Cpu_Interrupt, /* Int.no. 7 Vtpm1ch2 (at FFF0) Unassigned */
Cpu_Interrupt, /* Int.no. 6 Vtpm1ch1 (at FFF2) Unassigned */
TI1_Interrupt, /* Int.no. 5 Vtpm1ch0 (at FFF4) Used */
Cpu_VicgInterrupt, /* Int.no. 4 Vicg (at FFF6) Used */
Cpu_Interrupt, /* Int.no. 3 Vlvd (at FFF8) Unassigned */
Cpu_Interrupt, /* Int.no. 2 Virq (at FFFA) Unassigned */
Cpu_Interrupt, /* Int.no. 1 Vswi (at FFFC) Unassigned */
_EntryPoint /* Int.no. 0 Vreset (at FFFE) Reset vector */
};

Al comienzo de la tabla encontramos la constante @0xFFCC que cumple un rol
equivalente a ORG $FFCC en ensamblador, pues en esta dirección comienza la tabla
de vectores.

Dentro de ella encontramos un elemento conocido _EntryPoint, que no es ni mas ni
menos que el vector de RESET. Otro elemento que nos llamará la atención es
TI1_Interrupt que es el vector de interrupción por timer 1 overflow. El elemento
simbólico TI1_Interrupt es el nombre de una función, que cumple el papel de ISR.

Si abrimos el archivo TI1.c encontraremos la función TI1_Interrupt:

ISR(TI1_Interrupt)
{
(void)TPM1C0SC;

clrReg8Bits(TPM1C0SC, 0x80);
TI1_OnInterrupt();
}

Esto nos debe quedar presente: la tabla de vectores está toda definida en un único
archivo, Vectors.c, mientras que cada ISR está en un archivo asociado con el periférico
en cuestión. En nuestro ejemplo, el timer 1, con su ISR definida en TI1.c.

Recordemos que para atender la interrupción por timer overflow se requieren 2 pasos:

• Leer el registro TPMxC0SC.

• Limpiar el bit CH0F del TPMxC0SC.

Lo primero se lleva a cabo mediante la muy poco comprensible sentencia:

(void)TPM1C0SC;

En realidad lo que pretende esta sentencia es leer el registro TPM1C0SC pero sin
hacer nada con él, ni una asignación ni una función.

El segundo paso se cumple llamando a la función clrReg8Bits provista por el
CodeWarrior. Su función es limpiar uno o varios bits de un registro. En este caso el bit
7 del registro TPM1C0SC.

Lo último que hace la ISR es invocar a la función TI1_OnInterrupt() que es una
función brindada por el Processor Expert al desarrollador para que escriba allí el código
que desee ejecutar cuando se produce la interrupción. Esta función estará vacía y es el
programador quien debe completarla con código.

Este enfoque que puede resultar muy enredado a quien se inicia en la programación en
C con el CodeWarrior, es muy provechoso. El programador debe olvidarse de los
detalles que cada módulo tiene para atender la interrupción, pues el Processor Expert
ya ha escrito esa parte de programa por nosotros. El desarrollador debe escribir
únicamente la sección de la ISR que es particular de la aplicación.

En nuestro caso, cambiar el estado del LED 1:

if(PTAD.PTAD_PTAD4 == 0)
PTAD_PTAD4 = 1;
else
PTAD_PTAD4 = 0;

No utilizamos etiquetas para darle mayor claridad al código, pero vemos claramente que
cambiamos el estado del LED 1, conectado al PORTA.4.

Cuando escribimos un programa en C bajo el entorno CodeWarrior podemos
considerar a la función T1_OnInterrupt como la ISR, aunque en un sentido estricto no
lo sea. Solo falta decir que la función TI1_OnInterrupt se haya definida en el archivo
Events.c. En este archivo estarán definidas todas las ISR de los módulos que empleen
interrupciones.

Nota de Radacción: El lector puede descargar este capítulo y capítulos anteriores desde
la sección “Artículos Técnicos” (“Mundo EDUKIT08”) en el sitio web de
EduDevices (www.edudevices.com.ar )
  • Links de descarga
http://lwp-l.com/pdf15490

Comentarios de: Mundo EDUKIT08 - Las interrupciones en lenguaje C (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad