Dúvida sobre interrupção

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Dúvida sobre interrupção

Mensagempor casebsantos » 23 Jan 2008 19:53

Olá a todos.

Bem, fiz um pequeno programa em picbasic para poder entender o funcionamento da interrupção externa no pino "RB0/INT", só que algo estranho ocorreu.

O programa funciona da seguinte maneira:

Há uma chave pushpull em RB0 (ao ser acionada ocorrerá uma interrupção), um LED conectado em RB3 que sempre fica ligado indicando o funcionamento do programa, um LED conectado em RB2 que é acionado somente quando pressiono a chave que está em RB0 (o que indica que ocorreu uma interrupção) sendo que depois que solto a tecla este LED desliga; e mais um display conectado na PORTA. Bem, até aqui tudo OK; só que resolvi fazer uma pequena modificação no programa, ou seja, acrescentei uma instrução para mostrar uma contagem em um display sendo que ficou assim:

Trecho original:

...
Inicio:
LED_executa=1
LED_interrupcao=0
goto Inicio
Disable
...


Após modificação:

...
Inicio:
LED_executa=1
LED_interrupcao=0
for i = 0 to 40
LCDOut $fe,1,#i
pause 300
next i
goto Inicio
Disable
...


Depois que executei o programa com esta modificação, quando pressiono a chave em RB0 o LED que indica que ocorreu a interrupção só desliga quando a contagem no display termina!!! Funcionou totalmente ao contrário do programa original.
Pergunto: Depois que tirasse o dedo da chave (RB0) o LED que indica a interrupção não teria que desligar independente da contagem no display terminar ou não?

O que eu fiz de errado? Alguém poderia me ajudar?

O programa original é este aqui:

'********************************************************
'* Nome : Interrupção externa no pino RB0/INT *
'********************************************************
DEFINE OSC 4
DEFINE LCD_DREG PORTA
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTA
DEFINE LCD_RSBIT 4
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 1
DEFINE LCD_BITS 4

symbol LED_executa = PORTB.3 ' Indica que o programa está sendo executado
symbol LED_interrupcao = PORTB.2 ' Indica que houve uma interrupção
i var byte
OPTION_REG.7 = 0

TRISB = %00000011
CMCON = %00000111


On Interrupt Goto ISR
INTCON = %10010000 ' Habilita interrupção RB0

Inicio:
LED_executa=1
LED_interrupcao=0
for i = 0 to 40
LCDOut $fe,1,#i
pause 300
next i
goto Inicio
Disable ' Desabilita interrupções


ISR:
if INTCON.1 = 1 then INTF 'Uma interrupção externa foi acionada pelo pino RB0/INT

INTF:
LED_interrupcao=1 'Aciona LED, indicando que ocorreu uma interrupção
Pause 500
INTCON.1 = 0 ' Flag de interrupção INTF é resetado
goto Exit_ISR

Exit_ISR:
Resume 'Retorna ao programa principal
Enable 'Habilita interrupções
End
******************************************

Se alguém precisar do arquivo que simulei no Proteus posso enviar.

Desde já agradeço.
casebsantos
Bit
 
Mensagens: 32
Registrado em: 19 Fev 2007 19:41
Localização: Belém-PA

Mensagempor LeandroPIC » 24 Jan 2008 11:23

Não vi direito, mas não é aconselhavem atualizar display na int vc marca uma variavel e atualiza o display na rotina principal.
Avatar do usuário
LeandroPIC
Byte
 
Mensagens: 163
Registrado em: 06 Jul 2007 12:19

Mensagempor casebsantos » 24 Jan 2008 21:34

LeandroPIC escreveu:Não vi direito, mas não é aconselhavem atualizar display na int vc marca uma variavel e atualiza o display na rotina principal.


Primeiramente obrigado pela sua atençaõ Leandro.

Bem, se você notar o comando para acionar o display está na rotina principal e não na rotina de interrupção, e é aí que estou achando estranho o funcionamento do programa, pois ele está se comportando como se estivesse na rotina de interrupção!!!

Alguma outra dica?

Já tentei fazer outras mudanças mas não surtiram o resultado desejado.
casebsantos
Bit
 
Mensagens: 32
Registrado em: 19 Fev 2007 19:41
Localização: Belém-PA

Mensagempor otavio luiz » 25 Jan 2008 07:22

Bem, pelo que vejo o programa esta funcionando do jeito que voce programou olha só:

Inicio:
LED_executa=1 " aqui voce liga o led executa
LED_interrupcao=0 " aqui voce apaga o led interrupção
for i = 0 to 40 " aqui voce inicia o laço for
LCDOut $fe,1,#i
pause 300
next i
goto Inicio
Disable ' Desabilita interrupções

Depois de ocorrer a interrupção voce não manda apagar mais o led somente quando termina o laço então o goto inicio reinicia o programa mandando apara o led interrupção correto.
para ocorrer o que voce deseja teria que ser assim:

ISR:
if INTCON.1 = 0 then Exit_ISR 'Uma interrupção externa foi acionada pelo pino RB0/INT

INTF:
LED_interrupcao=1 'Aciona LED, indicando que ocorreu uma interrupção
Pause 500
INTCON.1 = 0 ' Flag de interrupção INTF é resetado
LED_interrupcao=0
Exit_ISR:
Resume 'Retorna ao programa principal
Enable 'Habilita interrupções
End

Lembre-se, zona de Fresnel não é nenhuma franquia de puteiro.
Avatar do usuário
otavio luiz
Byte
 
Mensagens: 257
Registrado em: 11 Out 2006 13:56
Localização: Barretos - SP, terra de Peão

Mensagempor casebsantos » 25 Jan 2008 08:11

otavio luiz escreveu:Bem, pelo que vejo o programa esta funcionando do jeito que voce programou olha só:

Inicio:
LED_executa=1 " aqui voce liga o led executa
LED_interrupcao=0 " aqui voce apaga o led interrupção
for i = 0 to 40 " aqui voce inicia o laço for
LCDOut $fe,1,#i
pause 300
next i
goto Inicio
Disable ' Desabilita interrupções

Depois de ocorrer a interrupção voce não manda apagar mais o led somente quando termina o laço então o goto inicio reinicia o programa mandando apara o led interrupção correto.
para ocorrer o que voce deseja teria que ser assim:

ISR:
if INTCON.1 = 0 then Exit_ISR 'Uma interrupção externa foi acionada pelo pino RB0/INT

INTF:
LED_interrupcao=1 'Aciona LED, indicando que ocorreu uma interrupção
Pause 500
INTCON.1 = 0 ' Flag de interrupção INTF é resetado
LED_interrupcao=0
Exit_ISR:
Resume 'Retorna ao programa principal
Enable 'Habilita interrupções
End



Otavio,

Você está correto em sua explicação!!! Uma coisa tão óbvia que eu nem sequer percebi!!! Falta de atenção minha.

Muito obrigado pela ajuda e me desculpe pela falha.
Gosto deste fórum, pois sempre há pessoas para tirar nossas dúvidas.
Mas uma vez obrigado.
casebsantos
Bit
 
Mensagens: 32
Registrado em: 19 Fev 2007 19:41
Localização: Belém-PA

Mensagempor tcpipchip » 25 Jan 2008 09:37

Aproveitando o momento, voce usa o PICBASIC 2.50 ? (MELABS)

Eu tive que abandonar (mesmo com os patches) e voltar par ao 2.47

Algumas das minhas aplicações nao rodam direto com o 2.50...

É pena

TCPIPCHIP
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor otavio luiz » 25 Jan 2008 09:47

Eu tençho o 2.47 e pedi a uma amiga me enviar o 2.50 dos EUA, qual problema por exemplo voce tem tido com o 2.50, por incrivel que pareça nunca me ocorreu problema por bug do compilador, sempre tive problemas com erros meus mesmo. A unica coisa que me lembro é que quando tinha um trecho de programa em asm eu fazia assim:
ASM
xxxxx
xxxxx
xxxx
xxxx
ENDASM

O compilador não compilava esse trecho do programa :?: :?:
tive que fazer
@xxxxx
@xxxxx
@xxxxx
Ai sim funfa BLZ
Lembre-se, zona de Fresnel não é nenhuma franquia de puteiro.
Avatar do usuário
otavio luiz
Byte
 
Mensagens: 257
Registrado em: 11 Out 2006 13:56
Localização: Barretos - SP, terra de Peão

Mensagempor tcpipchip » 25 Jan 2008 17:33

Eu acho que o problema está com o HSERIN...
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor casebsantos » 26 Jan 2008 10:19

tcpipchip escreveu:Eu acho que o problema está com o HSERIN...


Amigo,

Eu utilizo a versão 2.47 e até agora não tive problemas com a mesma. Com relação a versão 2.50 já tive observado em outros fóruns que algumas pessoas detectaram falhas nesta versão durante a compilação.

Qual o proplema que você está tendo com o comando HSERIN? Posso verificar com outros colegas meus.

Aproveitando o momento, você trabalha com o MikroBasic? Se sim´, me tire uma dúvida: É impressão minha, mas o Mikrobasic gera um arquivo HEX maior que o gerado em PicBasic?
casebsantos
Bit
 
Mensagens: 32
Registrado em: 19 Fev 2007 19:41
Localização: Belém-PA

Mensagempor tcpipchip » 26 Jan 2008 12:43

Simplesmente ocorreu sobreposição de bytes na recepção do HSERIN ou HSEROUT nao envia corretamente...
No exemplo abaixo eu tento pegar o sincronismo de uma camera...
Simplesmente nao recebo caracteres certos na 2.50, mas na 2.47 vai e muito bem :)
Os IF retornam TRUE
Disasemblei o código do PICBASIC e achei algumas coisas estranhas...mas...acabei desistindo...

CAMERA_CONNECT:
RESULT = 0
SPBRG = SPEED
FOR RETRIES = 1 TO 60 'FIQUE TENTANDO
b1 = $aa 'ENVIANDO PACOTES DE SYNC
b2 = $0d
b3 = 0
b4 = 0
b5 = 0
b6 = 0
gosub send_camera
HSERIN 45,TIME_OUT_CAMERA,[B1,B2,B3,B4,B5,B6]
if (B1 = $AA) AND (B2 = $0E) AND (B3 = $0D) AND (B5 = $00) AND (B6 = $00) THEN
RESULT = 1
GOTO SAI_CAMERA_CONNECT 'ENTAO SINCRONIZE O PACOTE
ENDIF
'ERRO CRITICO, CAMERA COM PROBLEMAS
IF (B1 = $AA) AND (B2 = $0F) THEN
RESULT = B5
GOTO SAI_CAMERA_CONNECT_II
ENDIF
TIME_OUT_CAMERA:
CLEARWDT
NEXT RETRIES
'NAO CONSEGUIU COMUNICAR COM CAMERA :(
RESULT = $0E
SAI_CAMERA_CONNECT:
HSERIN 45, SAI_CAMERA_CONNECT_II,[B1,B2,B3,B4,B5,B6]
IF (B1 = $AA) AND (B2 = $0D) AND (B3 = $00) AND (B4 = $00) AND (B5 = $00) AND (B6 = $00) THEN
RESULT = 2
b1 = $AA 'CONFIRME SYNC COM PACOTE DE ACK
b2 = $0E
b3 = $0D
b4 = 0
b5 = 0
b6 = 0
gosub SEND_CAMERA
ELSE
RESULT = $0E
ENDIF
SAI_CAMERA_CONNECT_II:
RETURN

Quanto o MIKROBASIC, só usei uma vez para implementar um soft para um leitor de cartao magnetico...
Avatar do usuário
tcpipchip
Dword
 
Mensagens: 6560
Registrado em: 11 Out 2006 22:32
Localização: TCPIPCHIPizinho!

Mensagempor geraldomelo » 31 Jan 2008 01:59

pessoal , só tirando uma duvida com vcs. eu parei de programar em basic (PBP246) na época , simplesmente por causa das interrupções ... se eu usasse um pause de 10 segundos por exemplo , nesse tempo não ocorria a interrupção .... nessas versões novas isso foi "arrumado" ??

abs

Geraldo
geraldomelo
Byte
 
Mensagens: 267
Registrado em: 14 Out 2006 16:53
Localização: Ribeirão preto - SP

Mensagempor otavio luiz » 31 Jan 2008 03:44

Não, continua da mesma forma, se voce for fazer um pause longo tem que fazer um laço for/next e repetir por várias vezes um pause curto.
Durante o tempo de pause todas as interrupções são desabilitadas.
Lembre-se, zona de Fresnel não é nenhuma franquia de puteiro.
Avatar do usuário
otavio luiz
Byte
 
Mensagens: 257
Registrado em: 11 Out 2006 13:56
Localização: Barretos - SP, terra de Peão


Voltar para PIC

Quem está online

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

x