Ir ao conteúdo
  • Cadastre-se

Usando interrupções timer de PIC posso executar outras tarefas?


Angelo Eletronic

Posts recomendados

Seguindo a linha de raciocinio do pessoal acima, pode sim, mas voce deve tomar cuidado cada vez que usa um interrupção, deve - se sempre limpar o flag da interrupção gerada, para que ela possa acontecer outras vezes, salvar contexto, e desabilitar outras interrupções temporariamente.

abs.

Link para o comentário
Compartilhar em outros sites

Uma pergunta:

Como vocês fazem quando há possibilidade de 2 ou mais interrupcoes acontecerem simultaneamente?

Ou então:

- Vamos supor que aconteceu uma interrupcao e o MCU desviou para uma rotina

- Dentro dessa rotina de interrupcao as interrupcoes globais foram desativadas

- Durante dessa mesma rotina aconteceu interrupcao de outro periferico (estando as interrupcoes globais desativadas)

- E só depois da rotina de interrupcao ser executada completamente as interrupcoes globais foram habilitadas novamente.

Como se faria pra tratar a interrupcao que ocorreu no outro periferico? Testando as flags de interrupcao? Ou há outro método melhor que este?

Link para o comentário
Compartilhar em outros sites

Amigo maskador,

Se voce desabilitou as interrupções globais, não vai ter nenhuma outra interrupção , concorda ? Ou seja, vai perder alguma coisa .....

Na verdade, quando voce tem várias interrupts que podem acontecer, voce tem que atender a primeira interrupção, salvar o contexto, descobrir qual foi o módulo do PIC que gerou a interrupt, e imediatamente re-habilitar as interrupções globais novamente, então prossegue o atendimento da interrupção.

voce apenas não habilita a interrupção do módulo responsável pela interrupção que está sendo atendida no seu trecho de programa.

Ao final dessa interrupção, voce reabilita essa interrupção novamente, e finalmente sai da rotina de interrupts ....

Parece complicado, mas é só a primeira vez heheheh

Mas não manjo nada de C, então os amigos vão te ajudar mais ok ?

Paulo

Link para o comentário
Compartilhar em outros sites

Amigo maskador,

Se voce desabilitou as interrupções globais, não vai ter nenhuma outra interrupção , concorda ? Ou seja, vai perder alguma coisa .....

Na verdade, quando voce tem várias interrupts que podem acontecer, voce tem que atender a primeira interrupção, salvar o contexto, descobrir qual foi o módulo do PIC que gerou a interrupt, e imediatamente re-habilitar as interrupções globais novamente, então prossegue o atendimento da interrupção.

voce apenas não habilita a interrupção do módulo responsável pela interrupção que está sendo atendida no seu trecho de programa.

Ao final dessa interrupção, voce reabilita essa interrupção novamente, e finalmente sai da rotina de interrupts ....

Parece complicado, mas é só a primeira vez heheheh

Mas não manjo nada de C, então os amigos vão te ajudar mais ok ?

Paulo

Sim, entendi ^_^

Mas deixa eu fazer uma outra pergunta:

Vamos supor que eu estou usando interrupcao por:

- Recepcao de bytes na UART

-Timer1

Supondo que aconteceu int da uart. Dentro da rotina de interrupcao é feito GIE = 0, executado as intrucoes necessarias, e GIE = 1 novamente.

Mas se o timer1 estourar enquanto o GIE = 0? Eu teria que testar se a flag de estouro de Timer1 está em 1, executar a rotina da int de Timer1 e limpar a flag nao? Pois se eu nao limpar a flag de interrupcao por t1, ela nao irá ocorrer mais, visto que a flag nunca seria resetada.

Está correto isso?

Link para o comentário
Compartilhar em outros sites

Mas se o timer1 estourar enquanto o GIE = 0? Eu teria que testar se a flag de estouro de Timer1 está em 1, executar a rotina da int de Timer1 e limpar a flag nao? Pois se eu nao limpar a flag de interrupcao por t1, ela nao irá ocorrer mais, visto que a flag nunca seria resetada.

Está correto isso?

Negativo, uma vez desabilitado o GIE, toda e qualquer interrupção sera desabilitada, ou seja mesmo que o flag seja setado, seria como se o bit TMR1IE estivesse desabilitado, ou seja no seu software voce deve planejar a sicronização para que não ocorra esse caso, pois voce "queima" uma interrupção perdendo desempenho!

abs.

Link para o comentário
Compartilhar em outros sites

Negativo, uma vez desabilitado o GIE, toda e qualquer interrupção sera desabilitada, ou seja mesmo que o flag seja setado, seria como se o bit TMR1IE estivesse desabilitado, ou seja no seu software voce deve planejar a sicronização para que não ocorra esse caso, pois voce "queima" uma interrupção perdendo desempenho!

abs.

Sim, concordo com você que com GIE = 0 nao iria ocorrer a interrupcao de T1. Mas a flag T1IF seria setada nao? aí eu poderia em algum trecho do programa testar se essa flag (T1IF) está em 1 e limpá-la (fazer T1IF = 0).

Link para o comentário
Compartilhar em outros sites

Este tópico me deixou em dúvida.

Será que em meus programas onde estão habilitadas mais de uma interrupção estou perdendo alguma interrupção, pois, nunca apaguei ou setei o bit GIE nas minhas rotinas de interrupção.

Então, consultei o manual da Microchip e me certifiquei de que não estava errado.

O próprio MCU zera o bit GIE até que retorne da rotina de interrupção, quando ele é setado.

Se outra interrupção ocorrer enquanto a primeira estava sendo tratada, quando o MCU retornar da interrupção será novamente desviado para o vetor da interrupção.

Ou seja, não precisa ou melhor, não se deve zerar o bit GIE ou setá-lo enquanto estiver dentro de uma rotina de interrupção.

Retirado do manual da Microchip:

"The Global Interrupt Enable bit, GIE (INTCON<7>), enables (if set) all un-masked interrupts or disables (if cleared) all interrupts. Individual interrupts can be disabled through their corresponding enable bits in the INTCON register. The GIE bit is cleared on reset.

The “return from interrupt” instruction, RETFIE, exits the interrupt routine as well as sets the GIE bit, which allows any pending interrupt to execute.

The INTCON register contains these interrupts: INT Pin Interrupt, the RB Port Change Interrupt, and the TMR0 Overflow Interrupt. The INTCON register also contains the Peripheral Interrupt

Enable bit, PEIE. The PEIE bit will enable/disable the peripheral interrupts from vectoring when the PEIE bit is set/cleared.

When an interrupt is responded to, the GIE bit is cleared to disable any further interrupt, thereturn address is pushed into the stack and the PC is loaded with 0004h. Once in the interrupt

service routine the source(s) of the interrupt can be determined by polling the interrupt flag bits.

Generally the interrupt flag bit(s) must be cleared in software before re-enabling the global interrupt to avoid recursive interrupts.

Once in the interrupt service routine the source(s) of the interrupt can be determined by polling the interrupt flag bits. Individual interrupt flag bits are set regardless of the status of their corresponding mask bit or the GIE bit.

Note 1: Individual interrupt flag bits are set regardless of the status of their corresponding mask bit or the GIE bit.

Note 2: When an instruction that clears the GIE bit is executed, any interrupts that were pending for execution in the next cycle are ignored. The CPU will execute a NOP in

the cycle immediately following the instruction which clears the GIE bit. The interrupts which were ignored are still pending to be serviced when the GIE bit is set again."

O que vocês me dizem?

Link para o comentário
Compartilhar em outros sites

Certinho , Mulder, como sempre !!!!!

Eu também não me preocupo com esse flag, apenas me preocupo com os flags de interrupt dos periféricos. Não fiz nada muito sofisticado com os Pics, mas pelo que eu ví também não perdia nenhuma interrupt.

Mas o esp[ecialista em assembler aqui é você hehehe , como eu faço em Basic, pode ser que ele acabe "mascarando" alguma coisa que eu não tenha percebido.

Paulo

Link para o comentário
Compartilhar em outros sites

Bom eu sempre prefiro optar por desabilitar as interrupções restantes, temporariamente, mas não pelo GIE, eu limpo o bit de habilitação de cada periférico, ou seja interrupção do tmr0 eu limpo o TMR0IE para que ela não ocorra enquanto estou realizando alguma ISR.

abs.

Link para o comentário
Compartilhar em outros sites

Note 1: Individual interrupt flag bits are set regardless of the status of their corresponding mask bit or the GIE bit.

Note 2: When an instruction that clears the GIE bit is executed, any interrupts that were pending for execution in the next cycle are ignored. The CPU will execute a NOP in the cycle immediately following the instruction which clears the GIE bit. The interrupts which were ignored are still pending to be serviced when the GIE bit is set again."

Eram exatamente essa minhas incertezas, mas agora ficou claro :D

1) Quando ocorre um evento gerador de interrupcao, a flag da mesma é setada independentemente do valor do GIE.

2) Se por EX: eu estou "tratando" uma interrupcao e dentro desta acontece outra interrupcao, o programa nao voltara ao vetor de interrupcao novamente depois que o GIE vai para 0. Eu terei então que tratar a segunda interrupcao que aconteceu testando a flag desta interrupcao em algum techo do programa.

Mas eu geralmente nao uso interrupcoes, e sim fico testando as flags

Minha duvida foi mais pelo fato de eu estar programando em C no CCS e no MPLAB C18, nos quais o programa e deslocado automaticamente para uma funcao que executa a rotina de itnerrupcao, faz mais de 2 anos que nao uso mais assembly e ja me esqueci de varias coisas.

No compilador CCS, eu tenho as interrupcoes tratadas da seguinte forma

#INT_RDA //RS232 receive data available

void trata_recepcao (void)

{

___procedimentos();

}

#INT_TIMER1 //Timer 1 overflow

void trata_timer1 (void)

{

___procedimentos();

}

sempre que ocorre interrupcao de T1, a funcao void trata_timer1 é chamada

Link para o comentário
Compartilhar em outros sites

1) Quando ocorre um evento gerador de interrupcao, a flag da mesma é setada independentemente do valor do GIE.

Correto.

2) Se por EX: eu estou "tratando" uma interrupcao e dentro desta acontece outra interrupcao, o programa nao voltara ao vetor de interrupcao novamente depois que o GIE vai para 0.

Correto.

Eu terei então que tratar a segunda interrupcao que aconteceu testando a flag desta interrupcao em algum techo do programa.

Errado.

Após sair da rotina de interrupção, ele desvia novamente para o vetor de interrupção, pois, a outra interrupção ainda está pendente.

Quanto ao código em C, desculpe, mas, não posso lhe ajudar.

Link para o comentário
Compartilhar em outros sites

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...