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