Interrupção durante Interrupção

Software e Hardware para linha x51

Moderadores: 51, guest2003, Renie, gpenga

Interrupção durante Interrupção

Mensagempor Francesco » 22 Mar 2009 12:56

É 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?
Avatar do usuário
Francesco
Word
 
Mensagens: 699
Registrado em: 04 Mar 2008 00:22
Localização: São Paulo - SP

Mensagempor barboza » 22 Mar 2009 15:09

Isso depende de como esta configurado a prioridade de cada interrupção.
Os homens mentiriam muito menos se as mulheres fizessem menos perguntas.
Avatar do usuário
barboza
Word
 
Mensagens: 948
Registrado em: 17 Out 2006 13:42
Localização: Longe de onde gostaria de estar

Mensagempor enigmabox » 22 Mar 2009 18:51

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
enigmabox
 

Mensagempor brasilma » 22 Mar 2009 19:13

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.
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor Francesco » 22 Mar 2009 21:06

Basilma,

Eu acredito que seja isso mesmo. Estou tentando fazer um teste, mas não estou conseguindo...
Avatar do usuário
Francesco
Word
 
Mensagens: 699
Registrado em: 04 Mar 2008 00:22
Localização: São Paulo - SP

Mensagempor enigmabox » 23 Mar 2009 08:02

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".
enigmabox
 

Mensagempor brasilma » 23 Mar 2009 08:33

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.
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor enigmabox » 23 Mar 2009 10:19

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.
enigmabox
 

Mensagempor Francesco » 23 Mar 2009 10:21

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( ; ; )
                ;
}
Avatar do usuário
Francesco
Word
 
Mensagens: 699
Registrado em: 04 Mar 2008 00:22
Localização: São Paulo - SP

Mensagempor brasilma » 23 Mar 2009 12:48

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.
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor Francesco » 23 Mar 2009 13:12

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?
Avatar do usuário
Francesco
Word
 
Mensagens: 699
Registrado em: 04 Mar 2008 00:22
Localização: São Paulo - SP

Mensagempor brasilma » 23 Mar 2009 13:37

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.
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra

Mensagempor Sergio38br » 23 Mar 2009 16:02

senhores, uma pergunta qdo se esta atendendo uma interrupção , antes do reti, que outra interrupção pode ser chamada???

[ ]'s
Sergio
Avatar do usuário
Sergio38br
Word
 
Mensagens: 759
Registrado em: 22 Nov 2007 13:39
Localização: São Paulo - SP

Mensagempor brasilma » 24 Mar 2009 08:36

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.
" A Teoria orienta e a Prática decide" ;-)
Avatar do usuário
brasilma
Dword
 
Mensagens: 3621
Registrado em: 11 Out 2006 15:39
Localização: Planeta Terra


Voltar para 8051

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante

x