9 votos

¿Cómo son los controladores de interrupción implementado en CMSIS de Cortex M0?

Tengo un LPC1114 kit. Últimos días he estado cavando hasta CMSIS implementación de Cortex M0 a encontrar la forma de hacer las cosas en él. Hasta ahora he entendido cómo cada uno de los registros se asignan y cómo puedo acceder a él. Pero todavía no sé cómo las interrupciones son implementadas en ella. Todo lo que sé acerca de las interrupciones en CMSIS es que hay algunos controlador de interrupción nombres mencionados en el archivo de inicio. Y puedo escribir mi propio controladores con sólo escribir una función en C con los mismos nombres mencionados en el archivo de inicio. Lo que me confunde es que en la guía del usuario, se dice que todos los GPIO puede ser utilizado como externa de interrupción de las fuentes. Pero sólo hay 4 PIO interrupciones mencionadas en el archivo de inicio. Así que dime:

  1. ¿Cómo puedo implementar controladores de interrupción externa para otros GPIOs?
  2. Donde está la tabla de interrupción asignada en el CMSIS?
  3. ¿Cuáles son las principales diferencias entre NVIC y la interrupción de la aplicación en AVRs/PICs? (excepto NVIC puede ser asignada a cualquier lugar en el flash)

14voto

JEzell Puntos 351

La siguiente información es, además de Igor excelente respuesta.

A partir de una programación C perspectiva, los controladores de interrupción se definen en el cr_startup_xxx.c archivo (por ejemplo, cr_startup_lpc13.archivo c para LPC1343). Todos los posibles controladores de interrupción se define como un DÉBIL alias. Si no se define su propio XXX_Handler() para una interrupción de la fuente, entonces la predeterminada de controlador de interrupción de la función definida en este archivo se utilizará. El vinculador ordenar que la función de incluir en la final binario junto con el vector de interrupción de la tabla de cr_startup_xxx.c

Ejemplo de GPIO de las interrupciones de los puertos se muestra en la demo archivos en gpio.c. Hay una interrupción de la entrada a la NVIC por puerto GPIO. Cada bit individual en el puerto puede ser habilitado/deshabilitado para generar una interrupción en ese puerto. Si usted requiere de interrupciones en los puertos PIO1_4, y PIO1_5 por ejemplo, puede permitir que el individuo PIO1_4 y PIO1_5 interrupción de bits en GPIO0IE. Cuando su PIOINT0_Handler() controlador de interrupción de la función de los incendios, es hasta usted para determinar cuál de PIO1_4 o PIO1_5 (o ambos) que las interrupciones están pendientes por leer el GPIO0RIS registro y manejo de la interrupción de forma adecuada.

10voto

Mark McDonald Puntos 246

(Por favor, tenga en cuenta que los puntos 1 y 2 son los detalles de implementación y no limitaciones arquitectónicas.)

  1. En las grandes chips NXP (como LPC17xx) hay un par de dedicado interrumpir pines (EINTn) que tienen su propio controlador de interrupción. El resto de los GPIOs tiene que usar uno común de interrupción (EINT3). Luego puede sondear el registro de estado de interrupción para ver qué pines han provocado la interrupción.
  2. No estoy muy familiarizado con LPC11xx pero parece que tiene una interrupción por puerto GPIO. De nuevo tendrá que comprobar el registro de estado a la figura de los pines. También hay hasta 12 pines que pueden actuar como wakeup fuentes. No estoy seguro de si usted puede apropiarse de ellos como general de interrupciones (es decir, que probablemente sólo se activará cuando en estado de reposo).
  3. El controlador predeterminado de la tabla se coloca en la dirección 0 (que es en flash). La primera entrada es el valor de reset para el registro SP, el segundo es el vector de reset, y el resto son de otras excepciones y los vectores de interrupción. Un par de las primeras (como NMI y HardFault) son fijados por el BRAZO, el resto son de chip específico. Si necesita cambiar los vectores en tiempo de ejecución, puede reasignar a la RAM (primero debe copiar la tabla). En LPC11xx la reasignación se fija para el inicio de la SRAM (0x10000000), otros chips puede ser más flexible.
  4. El NVIC está optimizado para un eficiente manejo de la interrupción:
    • programable por nivel de prioridad de 0-3 para cada interrupción. Una mayor prioridad de la interrupción se antepone a menor prioridad (anidación). La ejecución de la prioridad más baja se reanuda cuando la mayor prioridad de la interrupción que está terminado.
    • apilamiento automático del procesador de estado en la interrupción de la entrada; esto permite escribir controladores de interrupción directamente en C y elimina la necesidad de envoltorios de ensamblaje.
    • la cola de cadena: en lugar de aparecer y empujando el estado de nuevo, la próxima interrupción pendientes se maneja de inmediato
    • tardías: si una de mayor prioridad de la interrupción llega mientras apilamiento el procesador del estado, se ejecuta inmediatamente en lugar de la pendiente.

Puesto que usted está familiarizado con Fotos, eche un vistazo a esta Aplicación Nota: La migración de Microcontroladores PIC a Cortex-M3

Se trata de M3, pero la mayoría de los puntos se aplican a M0.

8voto

bugaboo Puntos 31

Austin y Igor respuestas son lo suficientemente detalladas. Sin embargo, quiero responder de otra manera, tal vez usted encontrará que es útil.

El LPC11xx (Cortex-M0) tiene 4 niveles para los pines GPIO, todos los pines de GPIO0.0 a GPIO0.n comparten el mismo número de interrupción, y todas las estacas de GPIO3.0 a GPIO3.m comparten el mismo número de interrupción.

Hay seis pasos para inicializar GPIO de interrupción en LPC11xx

   1. Set up the pin function by modifying Pin Connection Block Registers.

   2. Set up the pin direction by modifying GPIO data direction register (default value is input).

   3. Setup the interrupt for each individual pin, you have to go to the GPIO interrupt mask register GPIOnIE and set the bit (that corresponds to the pin) logic 1. 

   4. Set up the interrupt for rising edge or falling edge or both by modifying the GPIO interrupt sense registers GPIOnIBE and GPIOnIS. 

   5. Enable the interrupt source either PIO_0/PIO_1/PIO_2/PIO_3 in Nested Vectored Interrupt Control using CMSIS functions.   

   6. Set interrupt priority by using CMSIS functions.

Implementaciones de código. Se necesitan dos funciones: una inicializar 6 pasos anteriores, y el segundo es el controlador de interrupción, que es necesario que sea el mismo nombre que el controlador se define en el inicio de los códigos, startup_LPC11xx.s archivo. Los nombres son de PIOINT0_IRQHandler a PIOINT3_IRQHandler. Si utiliza un nombre diferente, usted tiene que cambiar los nombres de archivo.

   /*Init the GPIO pin for interrupt control */
void GPIO_Init(){
  LPC_IOCON-> =..            //Pin configuration register
  LPC_GPIO1->FIODIR = ...    //GPIO Data direction register
  LPC_GPIO1->FIOMASK = ..    //GPIO Data mask register - choose  the right pin
  LPC_GPIO1->GPIOnIE = ..    //Set up falling or rising edge 
  NVIC_EnableIRQ(PIO_1);      //Call API to enable interrupt in NVIC
  NVIC_SetPriority(PriorityN); //Set priority if needed

}

 /*Must have the same name as listed in start-up file startup_LPC11xx.s */
   void PIOINT1_IRQHandler(void){
   //Do something here
   }

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X