AVR: Interrupções - Parte 2
As interrupções externas são acionadas pelos pinos INT0 e INT1. Observe que se ativados, mesmo se os pinos forem configurados como saída, será gerado um evento de interrupção. Isto é útil quando se deseja gerar interrupção via software.
A interrupção externa é gerada se o bit SREG-I for definida e se for habilitada a interrupção.
Pulsos que duram mais que um período do relógio interno irá gerar interrupção. Caso contrário não será gerado a interrupção.
São destinados os vetores 0x0002 (IVT_ADDR_INT0) para Interrupção Externa 0 e 0x0004 (IVT_ADDR_INT1) para Interrupção Externa 1.
REGISTROS:
EICRA - External Interrupt Control Register A
ISC11:ISC10 - Interrupt Sense Control 1
Controla o modo da interrupção INT1:
00 - Nível baixo em INT1 irá gerar interrupção.
01 - Mudança de nível lógico em INT1 irá gerar interrupção.
10 - Borda de descida em INT1 irá gerar interrupção.
11 - borda de subida em INT1 irá gerar interrupção.
ISC01:ISC00 - Interrupt Sense Control 0
Controla o modo da interrupção INT0:
00 - Nível baixo em INT0 irá gerar interrupção.
01 - Mudança de nível lógico em INT0 irá gerar interrupção.
10 - Borda de descida em INT0 irá gerar interrupção.
11 - Borda de subida em INT0 irá gerar interrupção.
EIMSK - External Interrupt Mask Register
INT1 - External Interrupt 1 Enable
1 - Ativa a interrupção externa 1
0 - Desabilita a interrupção externa 1
INT0 - External Interrupt 0 Enable
1 - Ativa a interrupção externa 0
0 - Desabilita a interrupção externa 0
EIFR - External Interrupt Flag Register
Sinalização de que uma interrupção foi gerada ou não.
INTF1 - External Interrupt Flag 1
1 - Foi gerado uma interrupção INT1, a flag é limpa automaticamente.
0 - Não foi gerado uma interrupção INT1
INTF0 - External Interrupt Flag 0
1 - Foi gerado uma interrupção INT0, a flag é limpa automaticamente.
0 - Não foi gerado uma interrupção INT0
EXEMPLO:
void InterrupcaoExterna0() iv IVT_ADDR_INT0 ics ICS_OFF { PINB = 255; //alterna o estado de todas as saidas da PORTB } void main() { DDRB = 255; //PORTB definido como saída //Interrupçao INT0 por Borda de subida EICRA.ISC01 = 1; EICRA.ISC00 = 1; //////////////// EIMSK.INT0 = 1; //habilita interrupcao externa INT0 SREG_I_Bit = 1; //Habilita interrupção global }
INTERRUPÇÃO POR MUDANÇA DE ESTADO DOS PINOS
0x0006 (IVT_ADDR_PCINT0) destinado a interrupção dos pinos PCINT7:PCINT0
0x0008 (IVT_ADDR_PCINT1) destinado a interrupção dos pinos PCINT14:PCINT8
0x000A (IVT_ADDR_PCINT2) destinado a interrupção dos pinos PCINT23:PCINT16
REGISTROS:
PCICR - Pin Change Interrupt Control Register
PCIE2 - Pin Change Interrupt 2 Enable
1 - Ativa a interrupção por mudança de estados dos pinos PCINT23:PCINT16
0 - Desabilita a interrupção por mudança de estados dos pinos PCINT23:PCINT16
PCIE1 - Pin Change Interrupt 1 Enable
1 - Ativa a interrupção por mudança de estados dos pinos PCINT14:PCINT8
0 - Desabilita a interrupção por mudança de estados dos pinos PCINT14:PCINT8
PCIE0 - Pin Change Interrupt 0 Enable
1 - Ativa a interrupção por mudança de estados dos pinos PCINT8:PCINT0
0 - Desabilita a interrupção por mudança de estados dos pinos PCINT8:PCINT0
PCIFR - Pin Change Interrupt Flag Register
PCIF2 - Pin Change Interrupt 2 Flag
1 - Ocorreu uma mudança de estados nos pinos PCINT23:PCINT16, a flag é limpa automaticamente.
0 - Não ocorreu uma mudança de estados nos pinos PCINT23:PCINT16
PCIF1 - Pin Change Interrupt 1 Flag
1 - Ocorreu uma mudança de estados nos pinos PCINT14:PCINT8, a flag é limpa automaticamente.
0 - Não ocorreu uma mudança de estados nos pinos PCINT14:PCINT8
PCIF0 - Pin Change Interrupt 0 Flag
1 - Ocorreu uma mudança de estados nos pinos PCINT7:PCINT0, a flag é limpa automaticamente.
0 - Não ocorreu uma mudança de estados nos pinos PCINT7:PCINT0
PCMSK2:PCMSK1:PCMSK0 - Pin Change Mask Register
Cada bit seleciona o pino que irá gerar a interrupção. Se definido com 1 estará habilitado.
EXEMPLO:
void InterrupcaoDosPinos_PCINT0_PCINT1() iv IVT_ADDR_PCINT0 ics ICS_OFF { PINC = 255; //alterna o estado das saidas da PORTC } void main() { DDRC = 255; //PORTC definido como saída PCICR.PCIE0 = 1; //ativa a interrupção dos pinos PCINT7:PCINT0 PCMSK0 = 0b00000011; //escolhe os pinos PCINT0 e PCINT1 p/ gerar interrupção SREG_I_Bit = 1; //Habilita interrupção global }
OUTRO EXEMPLO:
//Pino PCINT0 (PB0) void EXT_PCINT0() iv IVT_ADDR_PCINT0 ics ICS_OFF { PINC.F0 = 1; //alterna o estado do pino PC0 } //Pino PCINT23 (PD7) void EXT_PCINT23() iv IVT_ADDR_PCINT2 ics ICS_OFF { PINC.F1 = 1; //alterna o estado do pino PC1 } //Pino INT0 (PD2) void EXT_INT0() iv IVT_ADDR_INT0 ics ICS_OFF { PINC.F2 = 1; //alterna o estado do pino PC2 } //Pino INT1 (PD3) void EXT_INT1() iv IVT_ADDR_INT1 ics ICS_OFF { PINC.F3 = 1; //alterna o estado do pino PC3 } void main() { DDRC = 255; //PORTC definido como saída DDRB = 0; //PORTB definido como entrada DDRD = 0; //PORTD definido como entrada PORTB = 0b00000001; //habilita os pull-up do pino PCINT0 PORTD = 0b10001100; //habilita os pull-up dos pinos INT0, INT1, PCINT23 //Configurando Interrupcao Externa 0 EICRA.ISC00 = 1; //Interrupção por borda de subida EICRA.ISC01 = 1; EIMSK.INT0 = 1; //Habilita interrupão INT0 //configurando Interrupçao Externa 1 EICRA.ISC10 = 0; //Interrupção por borda de descida EICRA.ISC11 = 1; EIMSK.INT1 = 1; //Habilita interrupão INT1 //Configurando Interrupçao do pino PCINT0 PCMSK0 = 0b00000001; //define somente o pino PCINT0 PCICR.PCIE0 = 1; //Habilita interrupção PCINT7:PCINT0 //Configurando Interrupção do pino PCINT23 PCMSK2 = 0b10000000; //define somente o pino PCINT23 PCICR.PCIE2 = 1; //Habilita interrupção PCINT23:PCINT16 SREG_I_Bit = 1; // Habilita interrupção global PORTC = 0; }
No próximo post, falarei das outras interrupções.
Nenhum comentário