Paso 10: Ser como Kanye - interrupción!
Así que ahora a escribir lo que es posiblemente la parte más importante del código; las interrupciones.El manejador de interrupción se encargará de la 'reacción' a insumos externos. En este caso, los insumos externos son comandos de teclas (adelante, vuelta, etc.) y los sensores de tacto. Queremos que el robot para moverse hacia adelante cuando se detecta una cierta clave, hacia atrás y así sucesivamente.
Así, sin más preámbulos, el manejador de interrupción:
. Data
theChar: .byte ' ' # el carácter que se envía. Es leído por nuestro programa y sobrescribir el controlador de interrupción.
/ * Esta es la función principal del robot caminante. */
.Section .exceptions, "hacha"
.align 2
controlador:
Addi sp, sp-12 #save ea, et, ctl1 de pila
STW et, 0(sp)
rdctl et, ctl1
STW et, 4(sp)
STW ea, 8(sp)
Addi sp, sp -32
STW r15,28(sp)
STW r14,24(sp)
STW r13,20(sp)
STW r12,16(sp)
STW r11,12(sp)
STW r10,8(sp)
STW r9,4(sp)
STW r8,0(sp)
rdctl et, ctl4 / * comprobar la interrupción pendiente de registro (ctl4) * /
Andi et, et, LEGO_IRQ11 / * comprobar si la interrupción pendiente de GPIO JP1 * /
Bne et, r0, handle_sensor
rdctl et, ctl4 / * comprobar la interrupción pendiente de registro (ctl4) * /
Andi et, et, LEGO_IRQ8 / * comprobar si la interrupción pendiente de JTAG UART * /
Bne et, r0, handle_JTAG
exit_handler br
handle_sensor:
/ * Comprobar falsa interrupción * /
r2 de movia, LEGO #_IRQ11 / * cargar GPIO JP1 en r2 * /
r4 ldwio, 0(r2)
SRLI r4, r4, 27
Andi r4, r4, 0x01f
cmpeqi r5, r4, 0x01f
r5 de la BNE, r0, exit_handler / * interrupción false * /
cmpeqi r5, r4, 0x01e / * comprobar sensor 0 * /
r5 de la BNE, r0, handle_sensor_left
cmpeqi r5, r4, 0x01d / * comprobar sensor 1 * /
r5 de la BNE, r0, handle_sensor_right
exit_handler br
handle_JTAG:
movia r7, JTAG_UART
ldwio r2, 0(r7)
Andi r13, r2, 0x8000 # comprueben que 15 es 1 (leído válido)
BEQ r13, r0, exit_handler
Andi r2, r2, 0xff bytes más bajo de #mask
/ * comprobar 'w' * /
movia r12, # 'w' 'w'
BEQ r2, r12, handle_forward
/ * comprobar de ' * /
movia r12, de ' # de
BEQ r2, r12, handle_stop
/ * comprobar 'x' * /
r12 de movia, 'x' #' x'
BEQ r2, r12, handle_reverse
/ * comprobar 'a' * /
movia r12, 'a' #' a'
BEQ r2, r12, handle_left
/ * comprobar si había ' * /
r12 de movia,'d ' # había '
BEQ r2, r12, handle_right
exit_handler br
handle_sensor_left:
Addi sp, sp -32
STW r15,28(sp)
STW r14,24(sp)
STW r13,20(sp)
STW r12,16(sp)
STW r11,12(sp)
STW r10,8(sp)
STW r9,4(sp)
STW r8,0(sp)
r4 de movia, LEDR
llamada de lightup
r4 de movia, LEGO / * pasar LEGO a r4, por lo que pueden hacer referencia a funciones motoras * /
llamar al wall_escape_right
r4 de movia, LEDR
llamada lightdown
LDW r8,0(sp)
LDW r9,4(sp)
LDW r10,8(sp)
LDW r11,12(sp)
LDW r12,16(sp)
LDW r13,20(sp)
LDW r14,24(sp)
LDW r15,30(sp)
Addi sp, sp, 32
movi et, 0 x 1 / * volver a habilitar las interrupciones * /
wrctl ctl0, et / * pastel paquete de bits se establece en 1 (enable interrumpe) * /
exit_handler br
handle_sensor_right:
Addi sp, sp -32
STW r15,28(sp)
STW r14,24(sp)
STW r13,20(sp)
STW r12,16(sp)
STW r11,12(sp)
STW r10,8(sp)
STW r9,4(sp)
STW r8,0(sp)
r4 de movia, LEDR
llamada de lightup
r4 de movia, LEGO / * pasar LEGO a r4, por lo que pueden hacer referencia a funciones motoras * /
llamar al wall_escape_left
r4 de movia, LEDR
llamada lightdown
LDW r8,0(sp)
LDW r9,4(sp)
LDW r10,8(sp)
LDW r11,12(sp)
LDW r12,16(sp)
LDW r13,20(sp)
LDW r14,24(sp)
LDW r15,30(sp)
Addi sp, sp, 32
movi et, 0 x 1 / * volver a habilitar las interrupciones * /
wrctl ctl0, et / * pastel paquete de bits se establece en 1 (enable interrumpe) * /
exit_handler br
handle_forward:
movia r7, JTAG_UART
ldwio r7,0(r7)
movi et, 0 x 1 / * volver a habilitar las interrupciones * /
wrctl ctl0, et / * pastel paquete de bits se establece en 1 (enable interrumpe) * /
Addi sp, sp -32
STW r15,28(sp)
STW r14,24(sp)
STW r13,20(sp)
STW r12,16(sp)
STW r11,12(sp)
STW r10,8(sp)
STW r9,4(sp)
STW r8,0(sp)
r4 de movia, LEGO / * pasar LEGO a r4, por lo que pueden hacer referencia a funciones motoras * /
llamar al motors_forward
LDW r8,0(sp)
LDW r9,4(sp)
LDW r10,8(sp)
LDW r11,12(sp)
LDW r12,16(sp)
LDW r13,20(sp)
LDW r14,24(sp)
LDW r15,30(sp)
Addi sp, sp, 32
exit_handler br
handle_reverse:
movia r7, JTAG_UART
ldwio r7,0(r7)
movi et, 0 x 1
wrctl ctl0, et
Addi sp, sp -32
STW r15,28(sp)
STW r14,24(sp)
STW r13,20(sp)
STW r12,16(sp)
STW r11,12(sp)
STW r10,8(sp)
STW r9,4(sp)
STW r8,0(sp)
r4 de movia, LEGO
llamar al motors_backward
LDW r8,0(sp)
LDW r9,4(sp)
LDW r10,8(sp)
LDW r11,12(sp)
LDW r12,16(sp)
LDW r13,20(sp)
LDW r14,24(sp)
LDW r15,30(sp)
Addi sp, sp, 32
exit_handler br
handle_left:
movia r7, JTAG_UART
ldwio r7,0(r7)
movi et, 0 x 1
wrctl ctl0, et
Addi sp, sp -32
STW r15,28(sp)
STW r14,24(sp)
STW r13,20(sp)
STW r12,16(sp)
STW r11,12(sp)
STW r10,8(sp)
STW r9,4(sp)
STW r8,0(sp)
r4 de movia, LEGO
llamar al motors_turn_left
LDW r8,0(sp)
LDW r9,4(sp)
LDW r10,8(sp)
LDW r11,12(sp)
LDW r12,16(sp)
LDW r13,20(sp)
LDW r14,24(sp)
LDW r15,30(sp)
Addi sp, sp, 32
exit_handler br
handle_right:
movia r7, JTAG_UART
ldwio r7,0(r7)
movi et, 0 x 1
wrctl ctl0, et
Addi sp, sp -32
STW r15,28(sp)
STW r14,24(sp)
STW r13,20(sp)
STW r12,16(sp)
STW r11,12(sp)
STW r10,8(sp)
STW r9,4(sp)
STW r8,0(sp)
r4 de movia, LEGO
llamar al motors_turn_right
LDW r8,0(sp)
LDW r9,4(sp)
LDW r10,8(sp)
LDW r11,12(sp)
LDW r12,16(sp)
LDW r13,20(sp)
LDW r14,24(sp)
LDW r15,30(sp)
Addi sp, sp, 32
exit_handler br
handle_stop:
movia r7, JTAG_UART
ldwio r7,0(r7)
movi et, 0 x 1 / * volver a habilitar las interrupciones * /
wrctl ctl0, et / * pastel paquete de bits se establece en 1 (enable interrumpe) * /
Addi sp, sp -32
STW r15,28(sp)
STW r14,24(sp)
STW r13,20(sp)
STW r12,16(sp)
STW r11,12(sp)
STW r10,8(sp)
STW r9,4(sp)
STW r8,0(sp)
r4 de movia, LEGO
llamar al motors_stop / * partió todos los motores y desactivar todos los sensores * /
stwio r9, 0(r2)
LDW r8,0(sp)
LDW r9,4(sp)
LDW r10,8(sp)
LDW r11,12(sp)
LDW r12,16(sp)
LDW r13,20(sp)
LDW r14,24(sp)
LDW r15,30(sp)
Addi sp, sp, 32
exit_handler br
exit_handler:
movia r9, LEGO_Edge / * borrar el disparador de borde del sensor de lego * /
stwio r0,0(r9)
LDW r8,0(sp)
LDW r9,4(sp)
LDW r10,8(sp)
LDW r11,12(sp)
LDW r12,16(sp)
LDW r13,20(sp)
LDW r14,24(sp)
LDW r15,30(sp)
Addi sp, sp, 32
LDW et, 0(sp)
LDW 4(sp) # restore ctl1, ea, et, et
wrctl ctl1, et
LDW ea, 8(sp)
Addi sp, sp, 12 # restaurar el puntero de pila
subi ea, ea, # 4 Asegúrese de que ejecutar la instrucción que se interrumpió. EA/r29 apunta a la instrucción después de que
ERET # retorno de interrupción (esto restablece ctl0? estado anterior de s que se guardó en el pc ctl1 y no = ea)
Para ser claros, este código en incluido en el archivo main.s para descargar en la página anterior.
Ahora que la interrupción ha sido cuidada, vamos a añadir algunas LED parpadeante y una función superior en código C para envolver todo!