Desde el año pasado he mostrado el uso de las interrupciones y como todos sabrán, las interrupciones son secciones de un programa que se ejecuta cada vez que son llamadas es decir cada vez que la bandera de la interrupción se activa deteniendo temporalmente la ejecución del programa principal y ejecutando el programa realizado en la rutina de interrupción.
Para este caso se presentará un programa el cual muestra el funcionamiento de las interrupciones en general de forma visual en una simulación realizada en ISIS PROREUS utilizando para ello la interrupción INT0 y que el usuario pueda comprobar en realidad como funciona una interrupción.
DESCRIPCIÓN:
DEFINICIÓN DE VARIABLES:
En esta sección del código se definen los registros que se utilizaran para las acciones de operaciones lógicas, mover datos e inicializar bits en registros de entrada y salida así como los registros de configuración, los cuales en este caso son los de enmascaramiento de la interrupción INT0.
.equ EIMSKreal48=0x3d ;posicion real del registro EIMSK
Para aquellos que programen en ensamblador el microcontrolador ATMEGA48 declara la localización de su registro EIMSK en la localización 0x1D lo cual es incorrecto, la localización es 0x3D, el datasheet menciona que se debe sumar 0x20.
INICIALIZACIÓN DEL PROGRAMA:
En esta parte del código se establece el Stack Pointer al principio de la RAM:
ldi pila, high(RAMEND); Main program start
out SPH,pila ; Set Stack Pointer to top of RAM
ldi pila, low(RAMEND)
out SPL,pila
En seguida se declara como salida los PORTB y PORTC, y como entrada el PORTD:
;declaracion de salidas en puerto B
ldi ES,0xff
out DDRB,ES ;declara al puerto B como salidas
out PORTD,ES ;habilita resistencias de pull-up del puerto D
out DDRC,ES ;declara al puerto C como salidas
com ES ;complemento 1 de la variable ES
out DDRD,ES ;declara al puerto D como entradas
Se habilita la interrupción:
;habilitacion de interrupciones
clr temp ;limpia el contenido de la variable temp
ldi temp,(1<<INT0) ;setea el bit 0 de la variable temp
sts EIMSKreal48,temp ;habilita la mascara de interrupcion INT0
clr temp ;limpia la variable temp
ldi temp,(1<<ISC01) ;setea el bit 1 de la variable temp
sts EICRA,temp ;configuracion de interrupciones en flanco de bajada
sei ;habilita la interrupcion global
PROGRAMA PRINCIPAL BUCLE INFINITO:
La función de esta sección es la de presentar el valor guardado en el registro temp por medio del PORTC desplazando a la derecha el contenido del mismo con un retraso declarado con la subrutina rcall delay_1, una vez que la variable temp esta vacía coloca su contenido en el PORTC y retorna al inicio del bucle con la subrutina infinito.
RUTINA DE INTERRUPCIÓN:
La interrupción realiza el decremento de la variable ES, y la presenta por medio del PORTB y a continuación espera un tiempo y decremento el valor de ES, pregunta si se encuentra vacía la variable de ser así sale de la interrupción y continua con el programa exactamente donde fue interrumpido.
NOTA:
Se colocara el link del programa y la simulación a final para que pueda descargarlo, al realizar la simulación podrá notar de forma clara como funciona una interrupción para reducir las dudas que se tenga sobre todo si es es nuevo en la programación de microcontroladores. Alguna duda o sugerencia puede ingresarla en los comentarios para que pueda mejorar la forma de presentación de los programas.
PROGRAMA:
/** INTRRUPCION0.asm
*
* Created: 02/03/2014 18:04:19
* Author: TERRAFORMARS
*/
.include "m48def.inc"
;DEFINICION DE VARIABLES
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.def temp=r16
.def pila=r17
.def ES=r18
.def delay=r19
.def retraso_0=r20
.def retraso_1=r21
.equ EIMSKreal48=0x3d ;posicion real del registro EIMSK
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.org 0x000 ;origen del programa
rjmp start ;salto a principio del programa
.org INT0addr ;direccion de la interrrupcion INT0
rjmp int_0 ;salto a rutina de interrupcion
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;INICIALIZACION DEL PROGRAMA
start:
ldi pila, high(RAMEND); Main program start
out SPH,pila ; Set Stack Pointer to top of RAM
ldi pila, low(RAMEND)
out SPL,pila
;declaracion de salidas en puerto B
ldi ES,0xff
out DDRB,ES ;declara al puerto B como salidas
out PORTD,ES ;habilita resistencias de pull-up del puerto D
out DDRC,ES ;declara al puerto C como salidas
com ES ;complemento 1 de la variable ES
out DDRD,ES ;declara al puerto D como entradas
;habilitacion de interrupciones
clr temp ;limpia el contenido de la variable temp
ldi temp,(1<<INT0) ;setea el bit 0 de la variable temp
sts EIMSKreal48,temp ;habilita la mascara de interrupcion INT0
clr temp ;limpia la variable temp
ldi temp,(1<<ISC01) ;setea el bit 1 de la variable temp
sts EICRA,temp ;configuracion de interrupciones en flanco de bajada
sei ;habilita la interrupcion global
;PROGRAMA PRINCIPAL BUCLE INFINITO
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
infinito:
ldi temp,0x3F ;carga temp con el valor 0b01111111
desplazamiento_R: ;realiza el desplazamiento de la salida a la derecha
out PORTC,temp ;coloca el valor de temp en el puerto C
rcall delay_1 ;realiza un delay
lsr temp ;desplaza el contenido de temp
brne desplazamiento_R ;comprueba si la opeacion seteo la bandera Z, de no ser asi realiza el salto
out PORTC,temp ;coloca el valor de temp en el puerto C
rcall delay_1 ;realiza un delay
rjmp infinito ;realiza un salto
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;RUTINA DE INTERRUPCION
int_0:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
push temp
in temp,SREG
ldi ES,0xe3 ;carga la variable ES con 0xe3
decremento: ;rutina de reduccion de la variable ES
out PORTB,ES ;coloca ES en el puerto B
;DELAY
;;;;;;;;;;;;;;;;;
ldi delay,0xff
loop_1:
ldi pila,0xff
loop_2:
dec pila
brne loop_2
dec delay
brne loop_1
;;;;;;;;;;;;;;;;;;
dec ES ;decrementa a ES en 1
brne decremento ;salto a decremento si ES es diferente de 0, Z=0
clr delay ;limpia la variable delay
out PORTB,delay ;limpia el puerto B
out SREG,temp
pop temp
reti ;retorna al programa principal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;DELAY
delay_1:
ldi retraso_1,0xff
retrasar_1:
ldi retraso_0,0xff
espera_1:
dec retraso_0
brne espera_1
dec retraso_1
brne retrasar_1
ret
IMÁGENES:
SIMULACIÓN EN PROTEUS:
EJECUCIÓN DE PROGRAMA EN BUCLE
EJECUCIÓN DE RUTINA DE INTERRUPCIÓN:
ATMEL STUDIO:
LINK:
https://mega.co.nz/#!8g1BlQ6B!CN5YYpCh-NNFHXjpH-tZZ_bL7bKZcgdppbIxSZ3x_GI
No hay comentarios:
Publicar un comentario