Microcontrolandos

O Blog está passando por uma fase de mudanças. Todos os posts estão sendo atualizados, códigos, links e imagens estão sendo arrumados. Conteúdos novos ainda estão por vir.

Utilizando as interrupções do PIC

Share:

INTERRUPÇÕES DO PIC




As interrupções são muito utilizadas no mundo dos microcontroladores. Um exemplo típico são nossos microcomputadores PC. Sempre que pressionamos uma tecla, uma interrupção é gerada para o microprocessador, solicitando o tratamento desta. Assim, o PC não é obrigado a varrer constantemente o teclado em busca de uma tecla. Porém é claro que para que isso seja feito, “alguém ou alguma coisa” deve fazer esta varredura por ele. Isso é feito por um microcontrolador dedicado, interno em todos os teclados de PC. Assim temos a geração de uma interrupção no processamento central por parte de um “periférico”.


No caso do PIC16F877A existem as seguintes interrupções:

Interrupção por overflow do Timer0;
Interrupção RB (mudança de estado das portas B);
Interrupção externa;
Interrupção de conversão analógico/digital;
Interrupção de transmissão de dados da porta serial (RS232);
Interrupção de recepção de dados da porta serial (RS232);
Interrupção por overflow do Timer1;
Interrupção por comparação do Timer2;
Interrupção do módulo CCP1 e CCP2;
Interrupção de atividade da comunicação SPI ou I2C;
Interrupção de colisão de dados do barramento;
Interrupção de escrita da EEPROM;
Interrupção de evento do comparador.

Em todas as interrupções é necessário habilitar as interrupção global e interrupção dos periféricos(exceto algumas), configurando o seguinte registro:


GIE: Habilita a interrupção global:
0 - Desabilitado
1 - Habilitado

PEIE: Habilita a interrupção dos periféricos:
0 - Desabilitado
1 - Habilitado




Interrupção por Overflow do TIMER0
Esta interrupção ocorre quando acontece o overflow do TIMER0, ou seja, quando a contagem do TIMER0 estoura de 255 para 0.

O bit que habilita essa interrupção é o INTCON.TMR0IE - (habilita com 1).
A flag de sinalização dessa interrupção é o INTCON.TMR0IF- (habilita com 1).




Interrupção RB ou interrupção por mudança de estados da Porta B
Esta interrupção ocorre quando qualquer um dos pinos (RB4 - RB7) muda de estado.

O bit que habilita essa interrupção é o INTCON.RBIE - (habilita com 1).
A flag de sinalização dessa interrupção é o INTCON.RBIF - (habilita com 1).





Interrupção Externa
Esta interrupção ocorre quando a entrada do pino RB0/INT recebe um sinal de nivel logico 1.

O bit que habilita essa interrupção é o INTCON.INTE - (habilita com 1).
A flag de sinalização dessa interrupção é o INTCON.INTF - (habilita com 1).



Outros registros que configura as demais interrupções:







Interrupção de conversão do módulo ADC
Esta interrupção ocorre quando a conversão analógico/digital foi concluída.

O bit que habilita essa interrupção é o PIE1.ADIE - (habilita com 1).
A flag de sinalização dessa interrupção é o PIR1.ADIF - (habilita com 1).




Interrupção de transmissão de dados RS232
Esta interrupção quando houver uma transmissão de dados no canal da porta serial.

O bit que habilita essa interrupção é o PIE1.RCIE - (habilita com 1).
A flag de sinalização dessa interrupção é o PIR1.RCIF - (habilita com 1).




Interrupção por overflow do TIMER1
Esta interrupção ocorre quando acontece o overflow do TIMER1, ou seja quando a contagem estoura de 65536 para 0.

O bit que habilita essa interrupção é o PIE1.TMR1IE - (habilita com 1).
A flag de sinalização dessa interrupção é o PIR1.TMR1IF - (habilita com 1).




Interrupção por comparação entre TMR2 e PR2
Esta interrupção ocorre quando há uma comparação entre o registro TMR2 e o registro PR2.

O bit que habilita essa interrupção é o PIE1.TMR2IE - (habilita com 1).
A flag de sinalização dessa interrupção é o PIR1.TMR2IF - (habilita com 1).




Interrupção do módulo CCP1 e CCP2
Ocorre quando houver uma captura ou comparação do módulo correspondente.

O bit que habilita essa interrupção CCP1 é o PIE1.CCP1IE - (habilita com 1).
A flag de sinalização dessa interrupção CCP1 é o PIR1.CCP1IF - (habilita com 1).
O bit que habilita essa interrupção CCP2 é o PIE2.CCP2IE - (habilita com 1).
A flag de sinalização dessa interrupção CCP2 é o PIR2.CCP2IF - (habilita com 1).




Interrupção por colisão de dados do barramento
Esta interrupção ocorre quando acontece uma colisão nos dados no barramento do MCU.

O bit que habilita essa interrupção é o PIE2.BCL1IE - (habilita com 1).
A flag de sinalização dessa interrupção é o PIR2.BCL1IF - (habilita com 1).




Interrupção de operação de escrita na EEPROM
Esta interrupção ocorre quando houver uma ação de escrita na EEPROM.

O bit que habilita essa interrupção é o PIE2.EE1IE - (habilita com 1).
A flag de sinalização dessa interrupção é o PIR2.EE1IF - (habilita com 1).




Interrupção do Comparador

O bit que habilita essa interrupção é o PIE2.CMIE - (habilita com 1).
A flag de sinalização dessa interrupção é o PIR2.CMIF - (habilita com 1).




Exemplo com uma interrupção:
void interrupt()
{
    ...;
    PIR1.TMR1IF = 0;
}


Exemplo com duas interrupções:
void interrupt()
{
   if(PIR1.TMR1IF)
   {
      ...;              // atendimento da interrupção de TIMER1
      PIR1.TMR1IF = 0;
   }

   if(PIR1.TXIF)
   {
      ...;             // atendimento da interrupção de Transmissão pela UART
      PIR1.TXIF = 0;
   }

}


12 comentários:

  1. Oi, não entendi direito. Depois que eu habilitar as interrupções posso escrever o programa todo normalmente e criar uma subrotina que, ao gerar a interrupção, o programa se desvia para ela? e depois é só botar um return no fim dessa sub-rotina que ele volta pra onde estava no programa?

    Obrigado

    ResponderExcluir
    Respostas
    1. Voce está programando em assembly? Porque pra sair da rotina de interrupção utiliza-se a instrução RETFIE

      Excluir
    2. No caso estou programando em C, no CCS. Não entendi direito onde eu crio a rotina de interrupção dentro do programa e o que acontece quando ocorre a interrupção (quando o pic detecta).

      Excluir
    3. //Cria-se a rotina da interrupção
      #int_EXT //identifica a interrupção( timer0, externa, etc... )
      void rotina_isr()
      {
      //seu código
      }


      //Dentro da rotina principal vc deve ativar a int. global e a int. desejada
      void main()
      {
      enable_interrupts(global); //habilita int. global
      enable_interrupts(int_ext); //habilita a interrupção, no caso, habilita a int. externa

      while(TRUE)
      {
      //código atual
      }
      }


      Quando ocorre uma interrupção, o PIC deixa de executar o código atual , pra executar o código da rotina de interrupção. Apos executada, volta ao código atual.

      Excluir
    4. Criei um programa simples e deu certo mas, por algum motivo, ele funciona só uma vez. botei um pushbutton no rb0 com pull-down de 10k e fiz ele acender um led por um segundo, mas ai só funciona de novo quando eu desligo. também usei o clear_interrupt (int_ext).

      Muito obrigado, seu blog ajuda muito :)

      Excluir
    5. Só funcionou uma vez provavelmente porque você não limpou a flag de interrupção. No exemplo que ele deu do timer 1, a flag era "PIR1.TMR1IF = 0;" tem que ver qual interrupção voce usou e limpar a flag na saída da interrupção para que ela possa ocorrer novamente.

      Excluir
    6. Eu posso estar enganado mas acho que o CCS já limpa a flag automaticamente, sem precisar incluir a instrucao clear_interrupt()

      Excluir
  2. Ola, eu estou fazendo um projeto de despertador em PIC, que no caso o despertador irá parar de tocar a buzina, quando houver a mudança em uma entrada de 1 para 0 ou de 0 para 1.
    No caso, eu usaria essa técnica que você mostrou ai?

    Obrigado

    ResponderExcluir
  3. Ola gostaria de saber quando ocorre a interrupcao no codigo atual ele volta de onde parou?

    ResponderExcluir
    Respostas
    1. sim.
      No momento que ocorre a interrupção, o PIC salva o endereço da próxima instrução que iria executar na pilha; executa então a rotina de interrupção; recupera o endereço salvo na pilha e volta a executar as instruções a partir desse endereço.

      Excluir
  4. Bom dia para todos,que Deus ilumine vossas mentes.

    ResponderExcluir