Página de inicio Mi Correo






   » Foro
   » Nuevo Foro
   » Mi Correo
   » Mis Actividades...


--- Novedades ---



    
  » Microcontroladores » Interrupciones y Temporizaciones (4 de 15)  

.: Codificando interrupciones

Ya estoy de regreso nuevamente, y a ver quién me sigue... que esta vez haré un programa que a muchos les puede resultar bobo, así que... a no criticar, que ya lo advertí...

Comenzamos...???

Bien, el programa consiste en preparar todo para el encendido de un LED que conectaremos en RB1, pero como dije, sólo prepararemos todo, porque luego haremos dormir al micro hasta que interrumpamos su sueño para atender un pulsador conectado a RB0/INT, momento en el cual deberá encender el LED, y regresar a dormir nuevamente, y cuando vuelvas a presionar el pulsador haremos que lo apague y otra vez lo despacharemos a dormir.

Esto ya lo hicimos anteriormente, sólo que ahora lo haremos con interrupciones, ok...???

Allá vamossss...!!!

;---------------Encabezado-------------

	LIST	P=16F84
	#include	<P16F84.INC>

;-------Configuración de puertos-------

	ORG	0x00               
	GOTO	inicio
	ORG	0x04          
	GOTO 	ISR
	ORG	0X05

inicio	BSF	STATUS,RP0       ; configurando puertos
	MOVLW	0x01	         ; carga w con 0000 0001
	MOVWF	TRISB	         ; RB0/INT es entrada
	BCF	OPTION_REG,6   ; seleccionamos flanco descendente
	BCF	STATUS,RP0

;-------Habilitación de interrupciones-------

	BSF	INTCON,GIE      ; habilitamos todas las interrupciones
	BSF	INTCON,INTE     ; que sean interrupciones externas
	CLRF	PORTB	        ; limpio el puerto B
sueño	SLEEP
	GOTO	sueño                ; Dulces sueños...!!!

;-------------Rutina de servicio de interrupciones-------------

ISR	BTFSC	PORTB,0           ; verificamos que suelten el pulsador		
	GOTO 	ISR

	BTFSC	PORTB,1	        ; y ahora sí, si el led está a 1
	GOTO	off_led	        ; ire a off_led para apagarlo
	BSF	PORTB,1	        ; sino, enciendo el LED
	BCF	INTCON,INTF     ; borro bandera de interrupción	
	RETFIE
	
off_led	BCF	PORTB,1	        ; apago el LED
	BCF	INTCON,INTF     ; borro bandera de interrupción
	RETFIE

;------------------------------------------
	END
;------------------------------------------

Desde nuestros primeros tutoriales hemos alcanzado a conocer varias de las instrucciones que se encuentran en este trozo de código, razón por la cual no las describiré, así es que vamos por aquello que está en rojo...

ORG      0x04
GOTO    ISR


La primera línea es el vector de interrupción, y cuando ésta se produzca, el código de programa apuntará a esta dirección y continuará con la siguiente instrucción, es decir GOTO ISR, la cual es un salto a ISR (Rutina de Servicio de Interrupciones) para atender dicha interrupción.

Configuramos el puerto B, como habrás notado, hemos configurado RB0/INT como entrada y el resto de los bits como salida, luego...

BCF      OPTION_REG,6     seleccionamos flanco descendente

En la página anterior dijimos que podíamos seleccionar el flanco con el cual se producirá la interrupción, pues eso es lo que estamos haciendo con esta instrucción, entonces vamos al registro OPTION y ponemos el BIT6 a "0" de este modo la interrupción se producirá cuando suelten el pulsador.

Ahora pasamos a lo más interesante, la habilitación de las interrupciones...

BSF     INTCON,GIE       ; habilitamos todas las interrupciones
BSF     INTCON,INTE     ; que sean interrupciones externas


Observa que la habilitación de interrupciones se hace en el banco0 ya que el Registro INTCON se encuentra en este banco. Bien, En la primera línea hacemos una habilitación general de todas las interrupciones, hacemos GIE=1, en la segunda línea, habilitamos interrupciones externas, hacemos INTE=1, recuerda que la bandera para la interrupción por el pin RB0/INT es INTF, no lo olvides, pues esta cambiará cuando la interrupción se produzca y luego de atenderla deberemos volverla a cero.

Lo que viene ahora es simplemente limpiar el puerto B, y luego...

sueño    SLEEP
              GOTO     sueño


SLEEP es la instrucción que pone al micro en estado de bajo consumo, es como que todo se detiene y éste pasa a modo de reposo, (consulta el set de instrucciones para mayor detalle...) debí haber puesto simplemente SLEEP pero veamos, si se ejecutaría la instrucción SLEEP el micro entraría en reposo hasta que se produce la interrupción, lo cual dijimos anteriormente que es como una llamada (un call), cuando regrese se encontrará con GOTO sueño y lo volveremos a dormir.

Te imaginas...??? si no pusiéramos el GOTO sueño, cuando regrese de la interrupción pasaría a la ISR (Rutina de servicio de interrupción), y lo peor de todo, es que lo haría sin que se produzca la interrupción, gran dolor de cabeza...!!!

Pero bueno, ahora nos quedamos a dormir con el micro hasta que un chico travieso active el pulsador de RB0/INT ...Felices sueñosssss...!!!!

chico malo...!!!, que siempre me pones a prueba, Ya veo que no pudiste esperar y presionaste el pulsador...

De acuerdo... sabes a donde me llevaste...??? justo a...

ORG      0x04
GOTO    ISR


Entonces vamos hacia allá, ahora te daré para que tengas, guardes y repartas...

Lo que viene, es la rutina de servicio de interrupción ISR y comenzamos con un...

ISR    BTFSC    PORTB,0    ; verificamos que suelten el pulsador
          GOTO     ISR


ISR no es una instrucción, sino la etiqueta que atiende la interrupción (pude haber puesto rut_serv u otra cosa, en fin...). Con BTFSC PORTB,0, prevenimos los rebotes, no se si era necesario ya que seleccionamos flanco descendente para este pin, pero por si las moscas lo puse, en realidad suele pasar que cuando se libera el pulsador se genera una pequeña chispa, la cual ya conocemos como rebote eléctrico, sólo lo puse por prevención.

Ahora si atenderemos la interrupción, comenzando por...

BTFSC    PORTB,1

BTFSC PORTB,1 es probar si el segundo bit (Bit1 de PORTB) está en 0, es decir si el LED está apagado y saltar un línea si es así.

En lecciones anteriores utilizamos un registro llamado cont con el cual sabíamos si el LED estaba prendido o apagado, y aquí tienes una forma de optimizar ese código, espero que no te pierdas con esto...!!!

Bien... como recién iniciamos, el LED está apagado, por lo tanto saltamos una línea y pasamos a...

BSF    PORTB,1

es decir hacemos RB1=1 (prendemos el LED). Perfecto, la interrupción ya fue atendida, pero ahora debemos habilitarla de nuevo así permitimos que se vuelva a ejecutar, y como tenemos un único pulsador el cual me cambió la bandera INTF, deberemos borrarla nuevamente, así es que...

BCF    INTCON,INTF    ; borro bandera de interrupción

Obviamente al producirse la interrupción se hizo GIE=0 para darnos lugar a atenderla, entonces...

RETFIE

y ahora GIE=1, las interrupciones están nuevamente habilitadas la bandera de RB0/INT está lista para una nueva interrupción y retornamos a ...

sueño    SLEEP
              GOTO     sueño


y esperaré a que pulses RB0, pues si ya lo hiciste habrás ido por segunda vez a ...

ORG      0x04
GOTO    ISR


prevenimos los rebotes y luego vamos a...

BTFSC    PORTB,1

es decir, prueba y salta si el Bit1 de PORTB es cero, y como esta vez el LED está prendido... simplemente harás un...

GOTO    off_led    ; ire a off_led para apagarlo

un salto a la etiqueta off_led...

off_led    BCF    PORTB,1    ; sino, apago el LED

no se si requiere explicación pero bueno, pones a cero el Bit1 de PORTB. Finalmente...

BCF    INTCON,INTF    ; borro bandera de interrupción
RETFIE


Ahora estamos listos para comenzar de nuevo...

te gustó...???, bieeeenn, aplausos para quien logró comprender...

y ahora la pregunta del millón...

que pasó con el mapa de memoria...???, donde se definieron las posiciones de memoria para los registros TRISB, PORTB, el registro OPTION..??? y el INTCON...???, donde demonios se definieron estas posiciones de memoria que supuestamente deben estar en el encabezado...???

No me digas que no te percataste de eso...!!!  :-O

La respuesta la tendremos en el próximo tutorial, y por la misma web ...ahí nos vemosssss...!!!

:o))



R-Luis...

<-- Anterior   Introducción   Siguiente -->
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15
Tabla de Referencias


    
--| |--