Página 1 de 1
Interrupção durante Interrupção

Enviado:
22 Mar 2009 12:56
por Francesco
É possível executar uma interrupção durante o tratamentod e outra? Se não, ela aguarda o fim da primeira para processar a segunda?
Um exemplo, se estou processando uma interrupção de timer e um dado chega pela serial. O timer termina de processar antes da interrupção da serial ou a rotina de interrupção do timer pára para processar a serial?

Enviado:
22 Mar 2009 15:09
por barboza
Isso depende de como esta configurado a prioridade de cada interrupção.

Enviado:
22 Mar 2009 18:51
por enigmabox
Tem algumas mpus e cpus que dão pra bricar em multitarefa, assim pode-se criar um sistema para que gerencie as interrupções deste modo.
Agora se tiver configurado as interrupções por prioridade, a cpu/mpu vai ter que esperar terminar uma para partir para outra interrupção. No 8051, vc pode definir qual interrupção tem maior prioridade, veja os registros IP, IE.
Se for habilitado todas as interrupções o 8051 vai obedecer a seguinte prioridade:
INT ext 0 Maior prioridade
Timer 0
INT ext 1
Timer 1
Canal Serial Menor prioridade

Enviado:
22 Mar 2009 19:13
por brasilma
Creio que a questão da prioridade seja apenas para interrupções silmultãneas, no caso de uma estar sendo atendida é necessário aguardar seu final (RETI) para a outra.

Enviado:
22 Mar 2009 21:06
por Francesco
Basilma,
Eu acredito que seja isso mesmo. Estou tentando fazer um teste, mas não estou conseguindo...

Enviado:
23 Mar 2009 08:02
por enigmabox
Se nao quiser habilitar todas as interrupçoes, pode se definir apenas a que vai ser utilizada. Ex>
Maior prioridade Timer0
Menor prioridade Serial
Assim a cpu passará a atender a interrupção serial após ter atendido a interrupção do Timer0.
No caso do 8051, não há flag para interrupção pendente, como em outras cpu, assim usando o hardware interno do 8051, se vier algum dado na serial durante a interrupção do Timer0, o dado fica no buffer ou vai "encavalar".

Enviado:
23 Mar 2009 08:33
por brasilma
Na prática creio que tudo funcione bem, pois um byte serial demora para ser recebido e dá tempo para concluir a outra interrupção e tratá-la.
Sou prova disso, em um de meus sistemas tenho a varredura de teclado sendo continuamente executada por interrupção, e nunca se perde nada que venha pela serial.
"Taca o pau" que vai dar certo.

Enviado:
23 Mar 2009 10:19
por enigmabox
Tb já fiz um projetinho, com 8051, onde usei todas as interrupções, usando um encoder incremental e os timers 0 para contar eventos e o timer1 como gerador de baud rate. Esta placa se comunicava com outras atraves da interface serial. Digo que não tive nenhum problema de comunicação.

Enviado:
23 Mar 2009 10:21
por Francesco
Estava tentando fazer o teste da seguinte forma, um teclado ligado à Interrupção externa 0 e 1.
O main() pisca o LED indicando que o programa entrou.
Eu ligaria a interrupção 0, ela piscaria um LED para indicar que entrou e travaria o processo em um loop infinito.
Nisso eu ligaria a interrupção externa 1, se ele acender o LED é porque tratou durante a interrupção externa 0.
No entanto, não funciona... nada acende, pisca ou faz coisa alguma. Estou fazendo algo errado?
- Código: Selecionar todos
#include <8052.h>
void interrupcaoExterna0( void ) interrupt 0
{
int i , j ;
// O Led acende com 0.
P0_0 = 0 ;
// Atraso.
for( j = 0 ; j < 10 ; j++ )
for( i = 0 ; i < 30000 ; i++ )
;
// O Led apaga com 1.
P0_0 = 1 ;
// Trava o processamento.
for( ; ; )
;
}
void interrupcaoExterna1( void ) interrupt 2
{
// O Led acende com 0.
P0_0 = 0 ;
}
void main( void )
{
int i , j ;
// Habilita interrupção externa.
EX0 = 1 ;
EX1 = 1 ;
EA = 1 ;
// Acende o Led com 0.
P0_0 = 0 ;
// Atraso.
for( j = 0 ; j < 10 ; j++ )
for( i = 0 ; i < 30000 ; i++ )
;
// Apaga o Led com 1.
P0_0 = 1 ;
for( ; ; )
;
}

Enviado:
23 Mar 2009 12:48
por brasilma
Olá Francesco,
Sou meio deficiente em C para 51 (não sei como vai ficar o compilado dessas rotinas), se fosse assembler te responderia na hora.
Mas com certeza algum outro colega vai ajudar.
Abraços.

Enviado:
23 Mar 2009 13:12
por Francesco
Também fiz a rotina em Assembly, ficou assim... a idpeia é a mesma, trava na interrupção externa 0 e tenta executar a interrupção externa 1.
- Código: Selecionar todos
$mod51
ORG 0000h
LJMP INICIO
ORG 0003h
LJMP TRATAI0 ; Trata interrupção externa 0.
ORG 0013h
LJMP TRATAI1 ; Trata interrupção externa 1.
TRATAI0:
MOV P0,#0 ; Acende LED no P0.
; Rotina de atraso.
MOV R0,#255
MOV R1,#255
PULO0:
DJNZ R0,PULO0
MOV R0,#255
DJNZ R1,PULO0
MOV P0,#255 ; Apaga LED no P0.
TRAVAI0:
SJMP TRAVAI0 ; Trava o processamento na interrupção 0.
RETI ; Apenas para constar.
TRATAI1:
MOV P0,#0 ; Acende LED no P0.
; Rotina de atraso.
MOV R0,#255
MOV R1,#255
PULO1:
DJNZ R0,PULO1
MOV R0,#255
DJNZ R1,PULO1
MOV P0,#255 ; Apaga LED no P0.
RETI
INICIO:
MOV IE,85h ; Ativa as interrupções externas.
MOV P0,#0 ; Acende LED no P0.
; Rotina de atraso.
MOV R0,#255
MOV R1,#255
PULO2:
DJNZ R0,PULO2
MOV R0,#255
DJNZ R1,PULO2
MOV P0,#255 ; Apaga LED no P0.
TRAVA:
SJMP TRAVA ; Trava o processamento do programa principal.
END
O programa faz a mesma coisa que em C, a rotina principal pisca o LED e trava. Quando a Interrupção Externa 0 é chamada, pisca o LED e trava dentro da interrupção externa 0.
Se a interrupção externa 1 for chamada, ela acende o LED. Na execução do programa, eu aciono a interrupção externa 0 e em seguida a 1, se ela acender para a 1 também, significa que o sistema executa uma interrupção dentro de outra.
No entanto, sem a piscada da rotina principal o sistema está gerando. Se eu removo o tratamento das interrupções externas, a rotina principal pisca o LED.
O que acontece?

Enviado:
23 Mar 2009 13:37
por brasilma
Agora está no meu dominio...
Bom para começar um errinho de estrutura, vc deve dar um endereço para montar "INICIO" acima do espaço para os vetores de interrupção, tipo assim: ORG 30H ; INICIO:... .
Outros detalhes são que precisa ligar todas a interrupções "EA", uma boberinha é que não precisa recarregar R0 com 255 nos seus delays.
Abraços.

Enviado:
23 Mar 2009 16:02
por Sergio38br
senhores, uma pergunta qdo se esta atendendo uma interrupção , antes do reti, que outra interrupção pode ser chamada???
[ ]'s
Sergio

Enviado:
24 Mar 2009 08:36
por brasilma
Olá Sergio,
Foi boa sua pergunta, meu Databook do 51 está em casa então estou "pelado" do saber, então resolvi fazer uma pesquisinha na NET para ver se ajudava.
Isso foi bom pois encontrei uma informação diferente (ainda não confirmada - qdo pegar o databook retorno) do que havia passado acima, uma interrupção de menor prioridade pode ser interrompida por uma de maior prioridade.
Isso responde a pergunta do colega e explica um procedimento comum, qdo não se deseja que isto ocorra, que é no inicio de uma rotina de tratamento de int de se colocar um CLR EA (desabilita todas interrupções).
Abraços.