miércoles, 11 de marzo de 2015

Manejo de Interrupciones con el Atmega164p por David Torres parte 1




El manejo de interrupciones es una de las aplicaciones más útiles que le podemos dar a un microcontrolador. El manejo de los registros de un atmega164p es el mismo en lenguajes como el Basic, el lenguaje C o el lenguaje ensamblador.
Cuantos tipos de interrupciones posee un atmega164p?
Este microcontrolador posee 2 tipos de interrupciones, la primera es una interrupción externa y la segunda es una interrupción interna (cambio de estado).

Interrupciones Externas       
El atmega164p posee 3 interrupciones externas que se las designa como INTX, INT 1 está en PD2, INT 2 está en PD3 mientras que INT 3 está en PB2.

 

Este tipo de interrupciones trabaja detectando el flanco que pasa por el pin determinado puede haber interrupciones por flanco de subida por flanco de bajada o que se detecte los dos estados antes mencionados.
Registros a configurar para la activación de las interrupciones externas
EICRA:
7
6
5
4
3
2
1
0
-
-
ISC 21
ISC 20
ISC 11
ISC 10
ISC 01
ISC 00



Al configurar esos bits le indicamos al microcontrolador como queremos que detecte la interrupción. 

Ejemplo 1 de configuración:
Ldi          r16, 0b00000010   ; configuro la int0 con flanco de bajada
sts          eicra, r16                ; cargo valor en eicra

Ejemplo 2 de configuración:
Ldi          r16, 0b00001110; configuro la int0 con flanco de bajada y la int1 con flanco de subida
sts          eicra, r16                ; cargo valor en eicra

EIMSK:
Al configurar el registro se activa o se desactiva la interrupción (con 1 lógico activo interrupción)
7
6
5
4
3
2
1
0
-
-
-
-
-
INT 2
INT 1
INT 0

Ejemplo 1 de configuración
Ldi          r16, 0b00000011; cargo el valor  en el registro r16
out         eimsk, r16           ; cargo el valor al registro.

Ejemplo de Aplicación:
Se requiere hacer el control de encendido de 3 leds los cuales se encenderán mediante pulsadores (no switch) utilice interrupciones externas para poder realizar el problema.


/*
 * interrupcion_externa.asm
 *  Created: 10/03/2015 13:54:50
 *   Author: David Torres Herera
 */

 .include"m164pdef.inc"
 .def  tempo = r16         ;se define las variablea a utilizar
 .def  conta1 = r17        ;en el programa
 .def  conta2 = r18
 .def  conta3 = r19

 .cseg                     ;empieza la linea de codigo

 // se debe poner en orden de direccion ya que caso contrario nos producira en error
 .org  0x00        
 rjmp  inicio

 .org  0x02         ;direccion del vector de la int0
 rjmp  uno          ;subrutina de la int0

 .org  0x04         ;direccion del vector de la int1
 rjmp  dos          ;subrutina de la int1

 .org  0x06         ;direccion del vector de la int2
 rjmp  tres         ;subrutina de la int2

 // aqui configuro interrupciones asi como el pull up
 // y el stack pointer
 inicio:

 ldi   tempo,0
 out   ddrd,tempo          ;configuo puertod y
 out   ddrb,tempo          ;puertob como salidas
 com   tempo               ;saco complmento de tempo queda con 0b11111111
 out   portd,tempo         ;pongo a uno para el
 out   portb,tempo         ;pull-up de esos dos puertos

 //configuro puertoA como salidas
 out   ddra,tempo
 ldi   tempo,0
 out   porta,tempo

 //configuro el pull-up
 in    tempo,mcucr
 andi  tempo,0b11101111
 out   mcucr,tempo

 //configuro el stack pointer por las interrupciones
 ldi   tempo,high(ramend)
 out   sph,tempo
 ldi   tempo,low(ramend)
 out   spl,tempo

 ldi   tempo,0b00101010 ; configuro las 3 interrupciones con flanco de bajada
 sts   eicra,tempo     ;cargo el valor en el registro eicra
 ldi   tempo,0b00000111 ;activo las interrupciones int0,int1,int2
 out   eimsk,tempo         ;cargo el valor en el registro eimsk
 out   eifr,tempo          ;cargo valor anterior para mantener interrupcion

 sei ; coloca a 1 logica la bandera I para q reconosca cualquier interupcion

 lazo:              ;lazo infinito solo salta
 rjmp  lazo          ;de esta lazo si hay interrupcion


 //lazos de interrupciones no se salva estado no es necesario
 uno:
 cpi   conta1,1     ;comparo para ver si se enciendo el led
 breq  apago1       ;salta a apagar el led
 sbi   porta,0      ;si no es asi prendo el led 1
 ldi   conta1,1
 salir1:
 reti  ;retorna a lazo   
 apago1:
 cbi   porta,0      ;apago el led1
 ldi   conta1,0     ;cargo con 0 para que se encienda led en nueva interrupción
 rjmp  salir1       ;retorno a etiqueta salir del lazo uno

 //las siguientes lineas  tienen la misma logica solo se
 //se cambia el pin especifico del puertoA

 dos:
 cpi   conta2,1
 breq  apago2
 sbi   porta,1
 ldi   conta2,1
 salir2:
 reti  ;retorna a lazo
 apago2:
 cbi   porta,1
 ldi   conta2,0
 rjmp  salir2

  //las siguientes lineas  tienen la misma logica solo se
 //se cambia el pin especifico del puertoA

 tres:
 cpi   conta3,1
 breq  apago3
 sbi   porta,2
 ldi   conta3,1
 salir3:
 reti  ;retorna a lazo
 apago3:
 cbi   porta,2
 ldi   conta3,0
 rjmp  salir3


Imágenes del programa funcionando:

 

 




No hay comentarios.:

Publicar un comentario