jueves, 19 de marzo de 2015

Manejo de Interrupciones con el Atmega164p por David Torres parte 2



Otro tipo de interrupciones que posee el microcontrolador Atmega164p son las interrupciones por cambio de estado (Internas).

¿Qué registros se deben configurar en este tipo de interrupción?

Registro PCICR: este registro nos permite activar la interrupción del puerto del Atmega164p  que vamos a utilizar.

-
-
-
-
PCIE 3
PCIE 2
PCIE 1
PCIE 0
 
De donde   PCIE 0: interrupciones del portA desde PCINT 0 hasta PCINT 7
                   PCIE 1: interrupciones del portB desde PCINT 8 hasta PCINT 15
                   PCIE 2: interrupciones del portC desde PCINT 16 hasta PCINT 23
                   PCIE 3: interrupciones del portD desde PCINT 24 hasta PCINT 31

 


Los últimos cuatro bits más significativos de este registro son reservados y no se configuran se los deja con cero.

Ejemplo 1 de configuración:

ldi    r16,0b00001000     ;activa las interrupciones del portD
sts    pcicr,tempo       ;carga el valor de r16 al registro pcicr

Registro PCMSK#: al configurar este registro lo que logramos es indicar que interrupción y de que puerto se va activar. Para entender esto el # representa el número al puerto correspondiente de donde vamos activar esas interrupciones teniendo así:

PCMSK0: corresponde al puerto A
PCINT 7
6
5
4
3
2
1
PCINT 0
 
PCMSK1: corresponde al puerto B
PCINT 15
14
13
12
11
10
9
PCINT 8

PCMSK2: corresponde al puerto C
PCINT 23
22
21
20
19
18
17
PCINT 16

PCMSK3: corresponde al puerto D
PCINT 31
30
29
28
27
26
25
PCINT 24

Ejemplo 2.1 de configuración:

Ldi          r16, 0b00000011              ; activo dos interrupciones del Puerto A PCINT0 y PCINT1
Sts          pcmsk0, r16                       ; cargo el valor del registro r16 en pcmsk0 

Ejemplo 2.2 de configuración:

Ldi          r16, 0b00010000              ; activo una interrupción del puerto D PCINT 28
Sts          pcmsk3, r16                       ; cargo el valor de r16 en pcmsk3 correspondiente al puerto D

Ejemplo de aplicación:

Se desea implementar un sistema en el que se tiene dos usuarios, estos tienen dos pulsadores el usuario que aplaste más rápido 5 veces seguidas encenderá un led, su respectivo led verde usuario A y led rojo usuario b, una vez que cualquier de los dos haya ganado se desactivara el programa y solo se pondrá en marcha de nuevo si se aplasta el reset del sistema. Utilice un Atmega164p e interrupciones por cambio de estado.

Solución: se escogerá dos interrupciones del puerto A en la que se colocara los pulsadores y en el mismo puerto, se colocara los 2 leds para mostrar el ganador, los leds para indicar el ganador serán los dos últimos bits más significativos del puerto A.

*  Created: 19/03/2015 16:59:31
 *   Author: David Torres Herrera
 */

 .include"m164pdef.inc"
 .def  tempo = r16
 .def  contaa = r17
 .def  contab = r18
 .def  ant       = r19

 .cseg
 .org        0x00         ; direccion del vector de interrupcion RESET
 rjmp        inicio       ; salta a etiqueta inicio

 .org        0x08         ; direccion de la interrupcion por cambio PCINT 0
 rjmp        interrup     ; salta a interrup cuando detecta la interrupcion de cualquier usuario

 inicio:
 //configuro el puerto A como entrada y salidas
ldi          tempo,0b11000000
out          ddra,tempo
ldi          tempo,0b00000011
out          porta,tempo

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

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

//configuro las interrupciones
ldi          tempo,0b00000001
sts          pcicr,tempo
ldi          tempo,0b00000011
sts          pcmsk0,tempo


 ldi          tempo,0b00000010   ;activa la bandera
 out          pcifr,tempo            ; z

 sei                       ;activa interrupciones
 in          ant,pina     ;se lee el estado del puerto A primero


 lazo:
 rjmp         lazo          ; lazo infinito no hace nada






// subrutina donde se realiza el anlisis y deteccion de la interrupcion
 interrup:

 push  r16                 ; se salva el estado con esto
 in          r16,sreg     ; n ose tiene problemas con
 push   r16                ; el sreg


 in          r16,pina     ; leo el puerto A
 eor   r16,ant             ; realizo una eor para q ver q cambio con el registro ant
 in          ant,pina     ; leoel puerto A y guardo en ant

 sbrc  r16,0        ;compruebo si cambio el bit 0 del r16
 rcall usuarioA     ; si cambio llamo a usuairoA
 sbrc  r16,1        ;compruebo si cambio el bit 1 del r16
 rcall usuarioB     ; si cambio llamo a usuairoB

 pop   r16                
 out   sreg,r16
 pop   r16
 reti                      ;regresa de nuevo a lazo infinito

//si el pulsador A es aplastod ejecuta estas lineas
 usuarioA:
 inc   contaa       ;incrementa el contador A
 cpi   contaa,5     ;compara si ya llego a 5
 breq  ledA         ;si llego a 5 salta a ledA
 escA:
 ret                       ;retorna

 ledA:
 sbi   porta,6                    ;llego a 5 prende led
 ldi   r20,0b00000000      ;descativo las interrupciones del puerto A
 sts   pcicr,r20           ;solo valdra de nuevo si aplasto el reset
 rjmp  escA                ;salta a escA y sale


// si el pulsador B es aplastado ejecuta estas lineas
 usuarioB:
 inc   contab              ;incrementa el contador
 cpi   contab,5            ;compara si llego a cinco
 breq  ledB                ;si llego salta a ledB
 escB:
 ret                             ;regresa

 ledB:
 sbi   porta,7                    ;prende el led 7 del puerto A
 ldi   r20,0b00000000      ;desactiva la interrupcion del puerto A
 sts   pcicr,r20           ;solo valdra de nuevo si se aplasta el reset
 rjmp   escB               ;salta a escB


Imágenes del programa simulado:

Circuito con los pulsadores y leds colocados como pide el ejercicio


Led rojo ganador B



Se aplasta el reset y queda encerado el sistema
 

Led verde ganador A