Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Subrutinas e
Interrupciones
Programación de un uC AVR 8-bit
Setiembre 2022
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
Objetivos
Ejercicio
• Escribir el diagrama de flujo que muestre el número de autos
existentes en un estacionamiento con capacidad máxima de 99
carros. Considere que los autos ingresan y salen de uno a uno, y
que en ambas puertas existe un sensor de autos, el cual genera
un ‘1’ mientras el carro esté pasando frente al sensor. Considere
también que el resultado es mostrado en formato BCD.
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
SUBRUTINAS
SUBRUTINAS
SUBRUTINAS
Inicio
Cuenta ++
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
SUBRUTINAS
Pila (Stack)
• Usada para almacenar el PC de retorno luego de una llamada de
interrupción/subrutina
• En el AVR-8, la pila es implementada en la SRAM: limitada por su tamaño y uso
• La dirección del inicio de la pila (“puntero de pila” o “stack pointer - SP”) debe ser
definido por el programador al inicio del programa: ANTES DE USAR LAS
SUBRUTINAS/INTERRUPCIONES
• La dirección del SP es definida en los registros SPH:SPL
• Para guardar en la pila, use PUSH. Para recuperar de la pila, use POP
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
SUBRUTINAS
Pila (Stack)
• Estructura de datos
• No se usa el concepto de dirección de dato
• Acceso a datos según orden de llegada
FIFO: First Input First Output LIFO: Last Input First Output
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
FLASH
SUBRUTINAS SRAM (Mem. de datos) (Mem. de programa)
Dirección Programm
de mem. Counter (PC)
$00 R0 $00 $01 $00
$01 R1 $01 $02 $01
… $02 $04 $03
… $03 $06 $05
Dirección
I/0 …
SBI, CBI, IN,
OUT $1F R31
$00 $20
$21 PORT, DDR,
PIN, SPH,
I/O SPL
Usuario
SP-2
SP-1
SP
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
• Definir el puntero de pila (Stack Pointer): se recomienda usar última dirección de pila.
• Puede usar CALL/RCALL para llamar a la subrutina. Verifique la diferencia
• Para retornar use RET
• Definir el puntero de pila (Stack Pointer): se recomienda usar última dirección de pila.
• Puede usar CALL/RCALL para llamar a la subrutina. Verifique la diferencia
• Para retornar use RET
; Ejemplo de llamado de subrutina 0x0009 NOP
0x000A NOP
.DEF estado_leds = R17
;……
0x0000 LDI R16,LOW(RAMEND) ; SP en el
0x0001 OUT SPL,R16 ; final de ; SUBRUTINA CONMUTA
0x0002 LDI R16,HIGH(RAMEND); la memoria ; Evalúa el estado de leds y los
0x0003 OUT SPH,R16 ; SRAM conmuta
; Registros modificados:
0x0004 CLR estado_leds ; R17 (estado_leds)
0x0005 SER R16 CONMUTA:
0x0006 OUT DDRD, R16 ;Puerto D: salida 0x000B CPI estado_leds, 0xFF
Repite: 0x000C BREQ apaga
0x0007 RCALL CONMUTA 0x000D SER estado_leds; estaba apagado
0x0008 RJMP Repite 0x000E RJMP FIN_CONMUTA
0x0009 NOP apaga:
0x000A NOP 0x000F CLR estado_leds
;…… FIN_CONMUTA:
0x0010 OUT PORTD, estado_leds
0x0011 RET
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
• Definir el puntero de pila (Stack Pointer): se recomienda usar última dirección de pila.
• Puede usar CALL/RCALL para llamar a la subrutina. Verifique la diferencia
• Para retornar use RET
; Ejemplo de llamado de subrutina 0x0009 NOP
0x000A NOP
.DEF estado_leds = R17
PC ;……
0x0000 LDI R16,LOW(RAMEND) ; SP en el
PC 0x0001 OUT SPL,R16 ; final de ; SUBRUTINA CONMUTA
PC 0x0002 LDI R16,HIGH(RAMEND); la memoria ; Evalúa el estado de leds y los
0x0003 OUT SPH,R16 ; SRAM conmuta
; Registros modificados:
0x0004 CLR estado_leds ; R17 (estado_leds)
0x0005 SER R16 CONMUTA:
0x0006 OUT DDRD, R16 ;Puerto D: salida 0x000B CPI estado_leds, 0xFF
Repite: 0x000C BREQ apaga
0x0007 RCALL CONMUTA 0x000D SER estado_leds; estaba apagado
0x0008 RJMP Repite 0x000E RJMP FIN_CONMUTA
0x08FC
0x0009 NOP apaga:
0x000A NOP 0x08FD 0x000F CLR estado_leds
;…… FIN_CONMUTA:
0x08FE
0x0010 OUT PORTD, estado_leds
0x08FF SP 0x0011 RET
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
• Definir el puntero de pila (Stack Pointer): se recomienda usar última dirección de pila.
• Puede usar CALL/RCALL para llamar a la subrutina. Verifique la diferencia
• Para retornar use RET
; Ejemplo de llamado de subrutina 0x0009 NOP
0x000A NOP
.DEF estado_leds = R17
;……
0x0000 LDI R16,LOW(RAMEND) ; SP en el
0x0001 OUT SPL,R16 ; final de ; SUBRUTINA CONMUTA
0x0002 LDI R16,HIGH(RAMEND); la memoria ; Evalúa el estado de leds y los
0x0003 OUT SPH,R16 ; SRAM conmuta
; Registros modificados:
0x0004 CLR estado_leds ; R17 (estado_leds)
0x0005 SER R16 CONMUTA:
0x0006 OUT DDRD, R16 ;Puerto D: salida 0x000B CPI estado_leds, 0xFF
Repite: 0x000C BREQ apaga
PC 0x0007 RCALL CONMUTA 0x000D SER estado_leds; estaba apagado
0x0008 RJMP Repite 0x000E RJMP FIN_CONMUTA
0x08FC
0x0009 NOP apaga:
0x000A NOP 0x08FD 0x000F CLR estado_leds
;…… FIN_CONMUTA:
0x08FE
0x0010 OUT PORTD, estado_leds
0x08FF SP 0x0011 RET
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
• Definir el puntero de pila (Stack Pointer): se recomienda usar última dirección de pila.
• Puede usar CALL/RCALL para llamar a la subrutina. Verifique la diferencia
• Para retornar use RET
; Ejemplo de llamado de subrutina 0x0009 NOP
0x000A NOP
.DEF estado_leds = R17
;……
0x0000 LDI R16,LOW(RAMEND) ; SP en el
0x0001 OUT SPL,R16 ; final de ; SUBRUTINA CONMUTA
0x0002 LDI R16,HIGH(RAMEND); la memoria ; Evalúa el estado de leds y los
0x0003 OUT SPH,R16 ; SRAM conmuta
; Registros modificados:
0x0004 CLR estado_leds ; R17 (estado_leds)
0x0005 SER R16 CONMUTA:
0x0006 OUT DDRD, R16 ;Puerto D: salida PC 0x000B CPI estado_leds, 0xFF
Repite: 0x000C BREQ apaga
0x0007 RCALL CONMUTA 0x000D SER estado_leds; estaba apagado
0x0008 RJMP Repite 0x000E RJMP FIN_CONMUTA
0x08FC
0x0009 NOP apaga:
SP
0x000A NOP 0x08FD 0x000F CLR estado_leds
;…… FIN_CONMUTA:
0x08FE 00 0x0010 OUT PORTD, estado_leds
0x08FF 08 0x0011 RET
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
• Definir el puntero de pila (Stack Pointer): se recomienda usar última dirección de pila.
• Puede usar CALL/RCALL para llamar a la subrutina. Verifique la diferencia
• Para retornar use RET
; Ejemplo de llamado de subrutina 0x0009 NOP
0x000A NOP
.DEF estado_leds = R17
;……
0x0000 LDI R16,LOW(RAMEND) ; SP en el
0x0001 OUT SPL,R16 ; final de ; SUBRUTINA CONMUTA
0x0002 LDI R16,HIGH(RAMEND); la memoria ; Evalúa el estado de leds y los
0x0003 OUT SPH,R16 ; SRAM conmuta
; Registros modificados:
0x0004 CLR estado_leds ; R17 (estado_leds)
0x0005 SER R16 CONMUTA:
0x0006 OUT DDRD, R16 ;Puerto D: salida 0x000B CPI estado_leds, 0xFF
Repite: 0x000C BREQ apaga
0x0007 RCALL CONMUTA 0x000D SER estado_leds; estaba apagado
0x0008 RJMP Repite 0x000E RJMP FIN_CONMUTA
0x08FC
0x0009 NOP apaga:
SP
0x000A NOP 0x08FD 0x000F CLR estado_leds
;…… FIN_CONMUTA:
0x08FE 00 0x0010 OUT PORTD, estado_leds
PC
0x08FF 08 0x0011 RET
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
• Definir el puntero de pila (Stack Pointer): se recomienda usar última dirección de pila.
• Puede usar CALL/RCALL para llamar a la subrutina. Verifique la diferencia
• Para retornar use RET
; Ejemplo de llamado de subrutina 0x0009 NOP
0x000A NOP
.DEF estado_leds = R17
;……
0x0000 LDI R16,LOW(RAMEND) ; SP en el
0x0001 OUT SPL,R16 ; final de ; SUBRUTINA CONMUTA
0x0002 LDI R16,HIGH(RAMEND); la memoria ; Evalúa el estado de leds y los
0x0003 OUT SPH,R16 ; SRAM conmuta
; Registros modificados:
0x0004 CLR estado_leds ; R17 (estado_leds)
0x0005 SER R16 CONMUTA:
0x0006 OUT DDRD, R16 ;Puerto D: salida 0x000B CPI estado_leds, 0xFF
Repite: 0x000C BREQ apaga
0x0007 RCALL CONMUTA 0x000D SER estado_leds; estaba apagado
PC
0x0008 RJMP Repite 0x000E RJMP FIN_CONMUTA
0x08FC
0x0009 NOP apaga:
0x000A NOP 0x08FD 0x000F CLR estado_leds
;…… FIN_CONMUTA:
0x08FE 00 0x0010 OUT PORTD, estado_leds
La pila “no se borra” 0x08FF 08 SP 0x0011 RET
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
CONMUTA:
Ejemplo: modifique el anterior código para PUSH R16
IN R16, SREG
guardar los estados de las banderas de estado PUSH R16
CPI estado_leds, 0xFF
BREQ apaga
CONMUTA: SER estado_leds; estaba apagado
CPI estado_leds, 0xFF RJMP FIN_CONMUTA
BREQ apaga apaga:
SER estado_leds; estaba apagado CLR estado_leds
RJMP FIN_CONMUTA FIN_CONMUTA:
apaga: OUT PORTD, estado_leds
CLR estado_leds POP R16
FIN_CONMUTA: OUT SREG, R16
OUT PORTD, estado_leds POP R16
RET RET
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
• Debe guardar todos los registros utilizado en la subrutina que no se hayan definido
como modificables (salidas de la función)
• Tome en cuenta los cambios de contexto en subrutinas de interrupción: banderas,
etc.
• Pueden implementarse subrutinas anidadas (subrutinas que llaman a otras
subrutinas): límite de pila.
• Ejemplo: retardo como subrutina
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
SUBRUTINAS
Ejercicio
• Escribir el diagrama de flujo y programa (C y Assembler) que muestre
mediante 4 LEDs la posición del pulsador presionado más 3. Si son
presionados más de un pulsador, considere el de mayor valor. Para ello
considere 4 pulsadores conectados a los 4 LSB del puerto B (PB3..0). Por
ejemplo, si se presiona el pulsador PB2 (posición 2), debe mostrarse por LEDs
el valor 5: “0101”
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
INTERRUPCIONES
Se atiende: salta a
Ocurre
subrutina
interrupción
(IRQ)
Programa principal
INTERRUPCIONES
Smartphone
INTERRUPCIONES
• Los eventos externos de un CPU pueden ser atendidos por el programa de dos
maneras: sondeo o interrupciones
• Hasta ahora hemos trabajado con el sondeo de los eventos externos. Por ejemplo,
para saber si un pulsador fue presionado se tenía que leer constantemente la entrada
respectiva
• Durante el sondeo, el CPU no puede procesar nada más, lo cual reduce su eficiencia.
Además, el evento puede ocurrir en un momento en que no se está sondeando
• Al manejar los eventos externos por interrupción, no se evalúa constantemente dicho
evento. El evento “interrumpe” al programa principal, por lo que el CPU puede seguir
realizando otras tareas
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
INTERRUPCIONES
Consideraciones
• Al ocurrir la interrupción, el procesador ejecuta una subrutina especial llamada
Subrutina de Servicio de Interrupción – RSI (Interrupt Service Routine – ISR). Es decir,
cada evento de interrupción conlleva un diagrama de flujo diferente.
• El programa principal NUNCA llama a una RSI. Diagramas de flujo separados
• En el programa principal se deben habilitar y deshabilitar las interrupciones
individuales (internas/externas) y global (bandera I )
• Durante la ejecución del RSI el I=0, por lo que no se puede ejecutar ninguna otra
interrupción
• Las RSI deben ser lo más breves posibles: NO delays, NO espera de eventos
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
INTERRUPCIONES
Consideraciones
• Existen prioridades de interrupción (depende de arquitectura del uC)
• Si es posible implementar más de una interrupción, ¿a dónde salta el PC
cuando ocurre la interrupción?
• Vectores de interrupción pre-definidos
• Es mandatorio cuidar que al terminar la RSI todos los registros no dedicados
sean restaurados
• En algunas plataformas, se debe limpiar la bandera de evento de
interrupción del evento
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
INTERRUPCIONES
Inicio
Ejercicio
Define SP IRQ P2
IRQ P1
• Realice el DF de MM = 0
Salva registros Salva registros
un cronómetro el SS = 0
DD = 0
cual posee dos Estado=detenido No Estado= Sí MM = 0
detenido SS = 0
pulsadores para Configura Timer DD = 0
reiniciar la cuenta (0.1s)
Estado = detenido Estado = contando
Estado=detenido
y para detenerla. Habilita IRQ por
Recupera registros
Los valores son Timer y entrada Recupera registros
mostrados en el
Habilita IRQ global Fin Fin
formato
MM:SS:DD Muestra
MM:SS:DD
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
INTERRUPCIONES
IRQ_Timer
Inicio
Ejercicio Salva registros
Define SP
Estado=
Sí detenido
• Realice el DF de MM = 0 No
un cronómetro el SS = 0
DD = 0
Sí
DD < 9
No
cual posee dos Estado=detenido DD++ DD = 0
MM:SS:DD Fin
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
INTERRUPCINES
Condiciones para que se ejecute la interrupción
INTERRUPCINES
Condiciones para que se ejecute la interrupción
Evento_1-F
Evento_2-F
Evento_3-F
Evento_1-F
Evento_1-M
Evento_2-F
Evento_2-M
I ...
Evento_3-F
ISR_EV3 ISR_EV1 ISR_EV2 Evento_3-M IRQ
I
...
Evento_n-F
Asumiendo que el Evento_1 tiene mayor prioridad que el
Evento_n-M
Evento_2, y este mayor prioridad que el Evento_3
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
INTERRUPCIONES
Fuentes de interrupción en Atmega328P
• Evento externo INT0, INT1 (control individual)
• Cambio de estado de pin
• Watch dog timer
• 3 tipos de interrupción por los 3 timers
• Comunicación SPI
• Comunicación UART
• Conversión realizada ADC
• EEPROM disponible
• Comparador analógico
• Comunicación TWI (I2C)
• Disponibilidad de escritura en memoria FLASH
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
INTERRUPCIONES
Vectores de
interrupción en
Atmega328P
30
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
INTERRUPCIONES
Address Labels Code Comments
0x0000 jmp RESET ; Reset Handler
0x0002 jmp EXT_INT0 ; IRQ0 Handler
0x0004 jmp EXT_INT1 ; IRQ1 Handler
0x0006 jmp PCINT0 ; PCINT0 Handler
0x0008 jmp PCINT1 ; PCINT1 Handler
0x000A jmp PCINT2 ; PCINT2 Handler
0x000C jmp WDT ; Watchdog Timer Handler
0x000E jmp TIM2_COMPA ; Timer2 Compare A Handler
Vectores de 0x0010 jmp TIM2_COMPB ; Timer2 Compare B Handler
0x0012 jmp TIM2_OVF ; Timer2 Overflow Handler
interrupción en 0x0014
0x0016
jmp
jmp
TIM1_CAPT
TIM1_COMPA
; Timer1 Capture Handler
; Timer1 Compare A Handler
0x0018 jmp TIM1_COMPB ; Timer1 Compare B Handler
Atmega328P 0x001A jmp TIM1_OVF ; Timer1 Overflow Handler
0x001C jmp TIM0_COMPA ; Timer0 Compare A Handler
0x001E jmp TIM0_COMPB ; Timer0 Compare B Handler
0x0020 jmp TIM0_OVF ; Timer0 Overflow Handler
0x0022 jmp SPI_STC ; SPI Transfer Complete Handler
0x0024 jmp USART_RXC ; USART, RX Complete Handler
0x0026 jmp USART_UDRE ; USART, UDR Empty Handler
0x0028 jmp USART_TXC ; USART, TX Complete Handler
0x002A jmp ADC ; ADC Conversion Complete Handler
0x002C jmp EE_RDY ; EEPROM Ready Handler
0x002E jmp ANA_COMP ; Analog Comparator Handler
0x0030 jmp TWI ; 2-wire Serial Interface Handler
0x0032 jmp SPM_RDY ; Store Program Memory Ready Handler
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
INTERRUPCIONES
Proceso
• Se debe configurar el evento de interrupción
• Antes del lazo principal se deben activar las interrupciones generales, mediante la
instrucción ‘SEI’. Si se quiere desactivar las interrupciones, se usa CLI
• Al ocurrir el evento, automáticamente el la dirección actual (PC) + 1 se almacenará
en la pila para poder retornar al final de la ejecución de la subrutina de
interrupción. Además, PC irá al vector de interrupción, donde se debe colocar un
salto (JMP o RJMP) a la dirección donde está definida la subrutina de interrupción.
• En la subrutina de interrupción, se deben guardar en la pila el SREG y los registros
de trabajo usados.
• Al final de la subrutina de interrupción, se debe regresar al programa principal
mediante el uso de la instrucción RETI
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
INTERRUPCIONES
Atmega328P
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
Registros de configuración
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
Registros de configuración
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
Vector de interrupción
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
Ejemplo
Realizar un contador de números positivos de dos dígitos que incremente su
cuenta al presionar un pulsador P1, y la reduzca al presionar P2. P1 está conectado
a PD2 con una resistencia de pull-up, y P2 está conectado a PD3 con una
resistencia de pull-down. El resultado debe verse en el puerto B, siendo los 4 bits
menos significativos las unidades, y los 4 bits más significativos las decenas.
Inicio ISR_P0 ISR_P1
Configurar entradas y
salidas Cuenta <99 Cuenta = 0
No Sí
Configurar Sí No
interrupciones Cuenta ++ Cuenta --
Cuenta = 0
Recupero registros Recupero registros
Habilita
interrupciones Fin Fin
BIN2BCD
Muestra
cuenta
EL6004 - Introducción a Sistemas Embebidos Prof. Jimmy Tarrillo – Ingeniería Electrónica
Referencias