Actualmente estoy jugando con algunos BRAZO Ensamblador en el lpc2378, yo he escrito un bucle de control de un horno de temperatura, sin embargo; creo que la necesidad de implementar algún tipo de control de interrupción para completar mi proyecto.

Cuando se ejecuta la aplicación, entra en un bucle, que se espera que Button_1 de entrada, el bucle, a continuación, lleva y pasa por varias fases, pero no puede llegar a esperar para Button_2 de entrada para que la aplicación funcione.

Así que un par de preguntas, ¿cómo funciona exactamente el controlador de interrupción de trabajo? y cómo puedo aplicarlo en mi aplicación.

Aquí está mi Button_1 código:

;=========================================================================
; Wait for BUT1 to be pressed
;=========================================================================
WaitBUT1
  STMFD r13!,{r0,r5,r14}   ; Push r0, r5 and LR

WaitForBUT1Pressed
    ldr r0, = IO0PIN            ; Address of FIO0PIN register 
    ldr r1, [r0]                ; Read FIO0PIN in to r1
    ands r1, r1, # B1_MASK      ; Mask out BUT1
    beq BUT1Pressed             ; Exit LED toggle loop if button is pressed
    B WaitForBUT1Pressed
BUT1Pressed

  LDMFD r13!,{r0,r5,r14}   ; Pop r0, r5 and LR
  mov pc, r14              ; Put link register back into PC

y mi Button_2 código:

;=========================================================================
; Wait for BUT2 to be pressed
;=========================================================================
WaitBUT2
  STMFD r13!,{r0,r5,r14}   ; Push r0, r5 and LR

WaitForBUT2Pressed
    ldr r0, = IO0PIN            ; Address of FIO0PIN register 
    ldr r1, [r0]                ; Read FIO0PIN in to r1
    ands r1, r1, # B2_MASK      ; Mask out BUT1
    beq BUT2Pressed             ; Exit LED toggle loop if button is pressed
    B WaitForBUT2Pressed
BUT2Pressed

  LDMFD r13!,{r0,r5,r14}   ; Pop r0, r5 and LR
  mov pc, r14              ; Put link register back into PC

y también mi horno lazo de control:

LoopStart

   BL WaitBUT1 ; wait until button 1 is pressed
   BL heaterOn ; turn heater on
   BL systemLedOn ; turn system LED on
   BL readTemp ; Check ADC for temp
   BL checkTemp ; Count down, check ADC for temp
   CMP r3, #5 ; Compare timer with delay
   BGT errorVal
   SUBS r4, r2, r7  ;Performs r7 = r4 - r2 and sets condition register
   BEQ LoopStart ; if equal nothing to do
   BGT overTemp ; r7 < 0 case
   BL errorLedOn
   BL heaterOn
   BL FanOff
   B LoopStart

overTemp
   BL errorLedOn
   BL heaterOff
   BL FanOn
   B LoopStart


   BL WaitBUT2
   BL FanOff
   BL errorLedOff
   BL systemLedOff
   BL heaterOff

       B LoopStart

Gracias de antemano.

OriginalEl autor user1080390 | 2012-05-18

2 Comentarios

  1. 11

    Si usted no tiene ya usted necesita para obtener el BRAZO (BRAZO de Arquitectura Manual de Referencia). solía haber sólo uno, pero hay muchos núcleos de ahora tienen que dividirlo para las diferentes arquitecturas. http://infocenter.arm.com a lo largo del lado izquierdo de Arquitectura ARM, a continuación, Manuales de Referencia, a continuación, ARMv5, sí sé que tiene una ARMv4 (ARM7TDMI). El ARMv5 manual es lo que solía ser, EL manual.

    Cubrirá la excepción de los vectores y tal.

    Usted probablemente ya sabe que en el inicio, la instrucción en la dirección 0 x 00000000 es ejecutado.
    Para las interrupciones de la instrucción en la dirección de 0x00000018 se llama.

    .globl _start
    _start:
        b   reset     ;@ 0x00000000 reset
        b   handler   ;@ 0x00000004 undefined instruction
        b   handler   ;@ 0x00000008 software interrupt swi
        b   handler   ;@ 0x0000000C prefetch abort
        b   handler   ;@ 0x00000010 data abort
        b   handler   ;@ 0x00000014 dont know
        b    irq_handler   ;@ 0x00000018 irq
        b   handler   ;@ 0x000000
    

    Del BRAZO también debe asegurarse de que los registros están situadas, en particular r13 el puntero de la pila, hay un puntero de pila cuando está en modo de interrupción. Así, en el arranque, cuando usted está configurando su pila normal también desea la instalación de algún espacio para la interrupción de la pila.

    reset:
    ;@//mov r0, #(PSR_IRQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS)
    mov r0,#0xD2
    msr cpsr_c, r0
    ldr sp, =0xD600C000
    
    ;@//mov r0, #(PSR_SVC_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS)
    mov r0,#0xD3
    msr cpsr_c, r0
    ldr sp, =0xD600B000
    

    en algún momento usted necesita para habilitar la interrupción en la cpsr. usted puede esperar en este hasta que han permitido a lo interrumpir en cualquier periférico (en el chip, fuera del núcleo).

    ;@ SVC MODE, IRQ ENABLED, FIQ DIS
    mov r0,#0x53
    msr cpsr_c, r0
    

    Usted tendrá que leer el manual de la lpc parte a entender cómo habilitar la interrupción, así como la forma de desactivar la interrupción cuando sucede.

    La primera cosa que usted necesita hacer en el controlador de interrupción (el código de rama en rama en la dirección 0x18) es preservar la compartida (no bancarizados) registros en la pila, de modo que usted no meterse con ellos. Si no, cuando vuelva al código que fue interrumpido los registros se han cambiado y que el código no funcione. Desde el proyecto parece estar en ASM es posible usar algunos registros en la aplicación y la reserva de algunos regsiters sólo para el isr y no en la configuración de la pila. Si usted va a utilizar bl en cualquier lugar en el controlador que necesita para salvar a lr en la pila.

    En algún punto de su controlador necesita desactivar la interrupción en el periférico de modo que no se dispara de nuevo hasta la siguiente interrupción, tengo que leer la lpc manual. Sí, cuando digo lpc me refiero NXP anteriormente Philips…

    La última cosa es que si te han empujado a lr, pop, pop y otros registros, si los había empujado, a continuación, utilizar esta instrucción exacta y el brazo de retorno y el interruptor de modos de vuelta al modo en que fue interrumpido (conmutación para el uso de los bancos de registros).

    subs pc,lr,#4
    

    Nota también puede ser necesario, y es generalmente una buena idea con el BRAZO, para obtener la TRM (Técnico-Manual de Referencia) para la central específicas, en su caso, el ARM7TDMI-S. En el centro de información de la página, el lado izquierdo de ir a ARM7 de Procesadores, no ARMv7 bajo arquitectura pero inferior donde se ha ARM11, ARM9, ARM7.

    Botones puede ser desordenado con interrupciones como rebotan y causa muchas aristas en el pin I/O. Busca en tu otro post no veo a donde usted necesita una interrupción. Usted debe, en general, evitar las interrupciones a menos que sea necesario. son complicados en general. Hay diseños que usted no puede evitar el uso de uno, sin duda. Y hay evento impulsado diseños en los que todo el código es un controlador de interrupción y no hay nada en la solicitud, pero el código de arranque y un bucle infinito (o algún tipo de sueño).

    Puede utilizar las interrupciones de rebote, por ejemplo, si la instalación de un temporizador de interrupción y muestra los terminales de e/S para los botones dentro de la interrupción, a evitar una gran cantidad de la rebotando, pero también el riesgo de falta pulsar un botón. Sólo porque el botón de pin de e/S es valer dos interrupciones en una fila que no es de dos prensas, de cambiar una variable de estado en algún lugar, y cuando se suelta el botón de cambiar la variable de estado. borde cambios en el estado de la variable de interés para la aplicación. cuando el botón se va de sin prensar a presionado, hacer algo, si se va de pulsado, sin prensar, no hacer nada, esperar a cambio de no comprimidas a presionado como un ejemplo.

    También se puede utilizar el mismo temporizador de interrupción para iniciar o una muestra de la adc.

    Puesto que no se han resuelto su problema, que también es mencionado aquí, yo no ir cerca de las interrupciones. La figura de ese problema, en primer lugar, a continuación, decidir si hay una característica que requiere una interrupción. Como aun/regular de muestreo del adc.

    que debería ser más que suficiente para empezar. Si intenta hacer las interrupciones NO trate de ellos como parte de esta aplicación, crear una completamente independiente de la aplicación, por ejemplo un led intermitente. cambiar el estado del led en el controlador de interrupción, y/o cambiar una variable global o registro en el controlador y tener el primer plano del reloj para que y cambiar el led como resultado. Siempre dividir sus problemas/ejercicios de aprendizaje en cada una de las piezas, la resolución de aquellos, a continuación, pegarlos juntos añadir una pieza de prueba, agregar una pieza de prueba.

    Hay más fiable maneras de lidiar con el interruptor de rebote. Por ejemplo, un conmutador de interrupción de establecer una marca de tiempo de un temporizador, si un posterior interrupción se produce dentro de decir 10ms de la primera, lo ignoran. O en un interruptor de interrumpir, desactivar la interrupción, el inicio de un temporizador para decir 10ms, luego de la expiración del temporizador de interrupción de volver a activar el interruptor de interrupción.
    asegúrese de que, de muchas maneras para hacerlo, sólo señalar que no es tal cosa (interruptor de rebote) por lo que el cartel podría ir a buscarlo..
    Dwelch por favor explique este punto de la suya,por Lo que en el arranque, cuando usted está configurando su pila normal también desea la instalación de algún espacio para la interrupción de la pila. También el código para restablecer la configuración de interrupción de la pila?

    OriginalEl autor old_timer

  2. 1

    En este caso un controlador de interrupción parece innecesario, usted podría simplemente encuesta botón 2 en el ciclo principal en lugar de utilizar la «espera» de la función. Agregar esto al final de su bucle:

    ldr r1, [r0]                ; Read FIO0PIN in to r1
    ands r1, r1, # B2_MASK      ; Mask out BUT1
    beq STOP
    

    donde la PARADA es un objetivo que realiza la caja fuerte del horno apagado (es decir, no salir corriendo indefinidamente).

    Tenga en cuenta que el bucle incluye una espera para button1 – sin duda que debe ser antes de LoopStart? De lo contrario, el bucle de control va a esperar a que se pulse un botón en cada iteración sin necesidad de realizar acciones de control – posiblemente una situación peligrosa si la última acción fue un heaterOn!

    Más allá de eso, tenga en cuenta que antes de la ARM-Cortex núcleos (LPX2378 es un ARM7TDMI-S core), el núcleo ARM sólo define dos fuentes de interrupción IRQ y FIQ, la mayoría de las piezas tienen un controlador de interrupción independiente externo al núcleo ARM sí mismo, y este controlador de interrupción es específico de cada fabricante. Por lo tanto, para determinar cómo GPIO interrumpe, por ejemplo, son manejados por su parte, tendrá que hacer referencia a que el dispositivo manual de referencia del lugar de BRAZO documentación.

    ARM Cortex-M de los dispositivos basados están reemplazando rápidamente los ARM7 dispositivos, y usted puede ser mejor con un dispositivo de este tipo. En particular manejo de la interrupción es mucho más sencillo, flexible y eficiente. Ver este artículo de cómo Cortex-M mejora en ARM7.

    OriginalEl autor Clifford

Dejar respuesta

Please enter your comment!
Please enter your name here