ERRO AO RECEBER DADOS PELA serial PIC18F4550.

173 views
Skip to first unread message

Joao Mario Vizarim Bononi

unread,
Mar 22, 2015, 3:12:53 PM3/22/15
to sis_emb...@googlegroups.com
Boa tarde a todos do grupo;
a alguns dias eu abri um tópico em relação a uma duvida sobre interrupção por INT_RDA e agradeço a todos que me ajudaram e dizer que a minha duvida foi resolvida.
Pois bem, eu fiz o programa e obtive sucesso na comunicação, mas estou com um pequeno problema e já estou de cabelo branco...RS

é o seguinte estou usando 2 interrupções, 1 para incrementar um registrador (INT_EXT) e outra para receber os dados (INT_RDA);
mas acontece que quando o botão de incremento eh apertado e se coincidir de estar havendo a interrupção por INT_RDA o microcontrolador para, não faz nada a mais ele para no meio da int_rda ....coloquei um LED para acender no começo da interrupção e o mesmo apagará no final especie de um DEBUG ....quando isso acontece o LED fica aceso.

Desde ja Obrigado  a todos.


/////////////////////







Rogério Poças

unread,
Mar 22, 2015, 3:31:38 PM3/22/15
to sis_emb...@googlegroups.com
Configure o #priority para dizer quem realmente manda em casa :-)
Rogério Poças
--
Você recebeu essa mensagem porque está inscrito no grupo "sis_embarcados" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para sis_embarcado...@googlegroups.com.
Para postar nesse grupo, envie um e-mail para sis_emb...@googlegroups.com.
Acesse esse grupo em http://groups.google.com/group/sis_embarcados.
Para mais opções, acesse https://groups.google.com/d/optout.

Rogério Poças

unread,
Mar 22, 2015, 3:34:02 PM3/22/15
to sis_emb...@googlegroups.com
Hã, esqueci de comentar no e-mail anterior, esse é dos problemas em ficar muito tempo preso dentro da INT, deixa na main e use o contexto salvo...

Rogério Poças
On 22/03/2015 16:12, Joao Mario Vizarim Bononi wrote:

Felipe Picada

unread,
Mar 22, 2015, 3:39:58 PM3/22/15
to sis_emb...@googlegroups.com
Fala Joao,
Ate' onde me lembro a interrupcao externa tem prioridade(INT_EXT),
entao o microcontrolador vai mesmo interromper o que ta fazendo.
Como esta o seu codigo dentro da INT_EXT?
Deu uma olhada no assembly gerado para ver se o compilador(acho que e'
o CCS?) ta gerando o retorno da interrupcao pra voce?

Abraco,
Felipe
> --
> Você está recebendo esta mensagem porque se inscreveu no grupo
> "sis_embarcados" dos Grupos do Google.
> Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie
> um e-mail para sis_embarcado...@googlegroups.com.
> Para postar neste grupo, envie um e-mail para
> sis_emb...@googlegroups.com.
> Visite este grupo em http://groups.google.com/group/sis_embarcados.
> Para obter mais opções, acesse https://groups.google.com/d/optout.
>

Joao Mario Vizarim Bononi

unread,
Mar 22, 2015, 9:57:22 PM3/22/15
to sis_emb...@googlegroups.com
Rogerio, configurei o priority
Esta assim;
#Priority int_rda,int_ext
Mesmo assim nao vai...:p

Joao Mario Vizarim Bononi

unread,
Mar 22, 2015, 10:04:22 PM3/22/15
to sis_emb...@googlegroups.com
Felipe, Dentro da int ta assim
Void int_ext(){
Ciclos++;
}

E na rda ta assim
Void int_rda(){
For(i=0;i<26;i++){
Buffer[indice]=getc();
Indice++;
}
Indice=0;
}

Rogerio Pocas

unread,
Mar 23, 2015, 6:53:00 AM3/23/15
to sis_emb...@googlegroups.com
Bom, que continua gastando muito tempo dentro das interrupções, se já enxugou o máximo e não tem nenhuma "gordura" a mais para tirar, defina qual INT é prioritária e desabilite temporariamente as outras interrupções...

Rogério Poças


--
Você está recebendo esta mensagem porque se inscreveu no grupo "sis_embarcados" dos Grupos do Google.

Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para sis_embarcado...@googlegroups.com.
Para postar neste grupo, envie um e-mail para sis_emb...@googlegroups.com.
Visite este grupo em http://groups.google.com/group/sis_embarcados.
Para obter mais opções, acesse https://groups.google.com/d/optout.

Rogerio Pocas

unread,
Mar 23, 2015, 6:55:42 AM3/23/15
to sis_emb...@googlegroups.com
João, você tem certeza que dentro da primeira interrupção RDA você já tem os 26 caracteres disponíveis no buffer da serial? você setou algum tamanho de buffer dentro da sua string de conexão, estou achando muita coisa receber (e ter) 26 caracteres numa tacada só...

Rogério Poças

Rafael Dias

unread,
Mar 23, 2015, 6:58:14 AM3/23/15
to sis_emb...@googlegroups.com

Ah!
Não sei qual compilador está usando, mas verifique o que o seu compilador está salvando na pilha. Isso pode tomar um tempo de processamento.

No C18 tem alguns #pragmas que fazem isso por você.

Att,
Rafael Dias

--
Você recebeu essa mensagem porque está inscrito no grupo "sis_embarcados" dos Grupos do Google.

Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para sis_embarcado...@googlegroups.com.
Para postar nesse grupo, envie um e-mail para sis_emb...@googlegroups.com.
Acesse esse grupo em http://groups.google.com/group/sis_embarcados.
Para mais opções, acesse https://groups.google.com/d/optout.

Andres Villalobos

unread,
Mar 23, 2015, 7:16:21 AM3/23/15
to sis_emb...@googlegroups.com
Verificou se o compilador está entendendo que essa função na verdade é uma interrupção?
Olha no assembly gerado se o compilador está colocando o comando de retorno de interrupção e não o de função.
Abraços,
 
-----
Andrés


De: Rogerio Pocas <rogeri...@gmail.com>
Para: "sis_emb...@googlegroups.com" <sis_emb...@googlegroups.com>
Enviadas: Segunda-feira, 23 de Março de 2015 7:52
Assunto: Re: [sis_embarcados] ERRO AO RECEBER DADOS PELA serial PIC18F4550.

--
Você recebeu essa mensagem porque está inscrito no grupo "sis_embarcados" dos Grupos do Google.

Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para sis_embarcado...@googlegroups.com.
Para postar nesse grupo, envie um e-mail para sis_emb...@googlegroups.com.
Acesse esse grupo em http://groups.google.com/group/sis_embarcados.
Para mais opções, acesse https://groups.google.com/d/optout.





Felipe Picada

unread,
Mar 23, 2015, 8:24:31 AM3/23/15
to sis_emb...@googlegroups.com
Joao,

Seguem meus dois centavos:
A)Retirar este "for" ai neste codigo, nao estas pensando em
interrupcao. este codigo ira ser chamado varias vezes.
Ao meu ver seria, apenas verificar o indice se nao esta out of bounds
e incrementar a cada interrupcao, alocando espaco no buffer.
B) A cada interrupcao estas incrementando? direto, sem debounce? como
esta a interrupcao por borda de subida, descida? nao tem ruido algum
ai? uma chave mecanica(produz ruido) poderia estourar este contador
bem facil.

Att,
Felipe

Joao Mario Vizarim Bononi

unread,
Mar 23, 2015, 9:50:04 AM3/23/15
to sis_emb...@googlegroups.com
Bom dia felipe,
Bom sobre o for eu entendi... Vou fazer, agora rm relaçao ao incremento o mesmo esta com filtro para ruidos, e esta incrementando 1 a cada toque no botao...

Joao Mario Vizarim Bononi

unread,
Mar 23, 2015, 4:22:13 PM3/23/15
to sis_emb...@googlegroups.com
Ola,boa tarde Rogerio,

Sim o buffer esta completo pq funciona normalmente....  so quando eu aperto o botao menu, ou acontece a int_ext que o problema acontece... acredito que ele fica parado dentro da interrupção por rda pois o led de debug acende e nao apaga.

Rogerio Pocas

unread,
Mar 23, 2015, 4:24:20 PM3/23/15
to sis_emb...@googlegroups.com
Que velocidade está sua UART? o CORE está em 48MHz com PLL?

Rogério Poças

--
Você recebeu essa mensagem porque está inscrito no grupo "sis_embarcados" dos Grupos do Google.

Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para sis_embarcado...@googlegroups.com.
Para postar nesse grupo, envie um e-mail para sis_emb...@googlegroups.com.
Acesse esse grupo em http://groups.google.com/group/sis_embarcados.
Para mais opções, acesse https://groups.google.com/d/optout.

Joao Mario Vizarim Bononi

unread,
Mar 23, 2015, 4:24:59 PM3/23/15
to sis_emb...@googlegroups.com
Boa tarde!!!!!
Vou tirar o for e no loop principal fazer assim;

while(true){

if(indice==26){
indice=0;
disable_interrupts(int_rda);
tratar dados...
enable_interrupts(int_rda);

  }
}

posto jaja o resultado... abração

Joao Mario Vizarim Bononi

unread,
Mar 23, 2015, 5:30:31 PM3/23/15
to sis_emb...@googlegroups.com
9600 bps
Core 20mhz
NOPLL

Joao Mario Vizarim Bononi

unread,
Mar 23, 2015, 6:55:45 PM3/23/15
to sis_emb...@googlegroups.com
Pelo que eu vi aqui, o problema nao acontece só quando a interrupção externa é chamada durante a int_RDA, e sim a qualquer aperto de botao........
desabilitei todas as interrupçoes;
deixei um botao para incrementar um registrador no loop principal, e se eu ficar apertando o botao e receber dados pela rda trava a uart e nao retorna mais nada para o master.

ta dificil...

Felipe Picada

unread,
Mar 23, 2015, 7:04:00 PM3/23/15
to sis_emb...@googlegroups.com
Opa,

Algumas perguntas:

Estas setando o TRIS manualmente?

O SPI esta desabilitado? este PIC e' cheio de perifericos... eu
normalmente desligo tudo que nao uso.

Esta usando fast_io?

Ja deu uma olhada no kbhit()?

Deu uma olhada no EX_SISR.C (provided by CCS) - se pegar este exemplo
como base e colocar a sua interrupcao externa como fica?

Nao tem como postar o codigo, init routine, defines etc..? Remove tudo
que precisaria um NDA.... :)

Att,
Felipe

Joao Mario Vizarim Bononi

unread,
Mar 23, 2015, 9:09:02 PM3/23/15
to sis_emb...@googlegroups.com
Felipe, fiz um teste, troquei o uC para o 16F877a e funcionou!
eu desabilitei todos os perifericos, mesmo assim nao foi com o 18f4550...
coisa de loko    :O

Joao Mario Vizarim Bononi

unread,
Mar 24, 2015, 12:52:54 AM3/24/15
to sis_emb...@googlegroups.com
Bom dia a todos,
o problema foi resolvido era só habilitar opção errors nas configurações de uart  !    UFFAAA!!  rsrs

obrigado a todos;


Em domingo, 22 de março de 2015 16:12:53 UTC-3, Joao Mario Vizarim Bononi escreveu:

Rogerio Pocas

unread,
Mar 24, 2015, 6:34:45 AM3/24/15
to sis_emb...@googlegroups.com
...mas ainda tem problemas, aquele get de 26 bytes@9600bps está fazendo seu uC ficar muito tempo preso dentro da INT...

Rogério Poças

--
Você recebeu essa mensagem porque está inscrito no grupo "sis_embarcados" dos Grupos do Google.

Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para sis_embarcado...@googlegroups.com.
Para postar nesse grupo, envie um e-mail para sis_emb...@googlegroups.com.
Acesse esse grupo em http://groups.google.com/group/sis_embarcados.
Para mais opções, acesse https://groups.google.com/d/optout.

Ronaldo Lins

unread,
Mar 24, 2015, 7:24:14 AM3/24/15
to sis_emb...@googlegroups.com
Bom dia, João!

Por acaso esse seu código não está gerando uma mensagem de reentrancy? Se tiver, acredito que seja por conta da função getc(). O que o compilador faz no momento da chamada dessa função é desabilitar todas as interrupções. Faça um teste com o seu próprio led, substituindo o getc() por um toggle no led por exemplo. Outra coisa é tentar forçar um clear nas flag de interrupção antes de sair da INT_RDA.

Abraços,
Ronaldo Lins



Em domingo, 22 de março de 2015 16:12:53 UTC-3, Joao Mario Vizarim Bononi escreveu:

Joao Mario Vizarim Bononi

unread,
Mar 24, 2015, 7:40:59 AM3/24/15
to sis_emb...@googlegroups.com
Bom dia rogerio,
O codigo nao esta maos com 26bytes capturados de uma vez, eu fiz um
buffer[indice]
Indice++

E ja sai da int, e la no loop principai eu fiz
If(indice==26){
Indice=0;
Tratar dados...
}

Magnus

unread,
Mar 24, 2015, 7:46:39 AM3/24/15
to sis_emb...@googlegroups.com
Detalhes:
Na interrupção, evite a escrita no buffer quando o índice for igual a 26.
No loop principal, trate primeiro os dados, zere o índice depois.
Dessa maneira você evita que um pacote chegando durante o tratamento corrompa o atual.


--
Você está recebendo esta mensagem porque se inscreveu no grupo "sis_embarcados" dos Grupos do Google.
Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para sis_embarcados+unsubscribe@googlegroups.com.
Para postar neste grupo, envie um e-mail para sis_embarcados@googlegroups.com.
Visite este grupo em http://groups.google.com/group/sis_embarcados.
Para obter mais opções, acesse https://groups.google.com/d/optout.

Rogerio Pocas

unread,
Mar 24, 2015, 7:47:33 AM3/24/15
to sis_emb...@googlegroups.com
Você testa o buffer antes de dar o get? lembre-se que comandos do tipo get ficam esperando a chegada do novo byte...

Rogério Poças


--
Você está recebendo esta mensagem porque se inscreveu no grupo "sis_embarcados" dos Grupos do Google.

Para cancelar inscrição nesse grupo e parar de receber e-mails dele, envie um e-mail para sis_embarcado...@googlegroups.com.
Para postar neste grupo, envie um e-mail para sis_emb...@googlegroups.com.
Visite este grupo em http://groups.google.com/group/sis_embarcados.
Para obter mais opções, acesse https://groups.google.com/d/optout.

Joao Mario Vizarim Bononi

unread,
Mar 24, 2015, 8:04:11 AM3/24/15
to sis_emb...@googlegroups.com
Legal, bem pensado!!!
Obrigado

Ronaldo Lins

unread,
Mar 24, 2015, 8:36:43 AM3/24/15
to sis_emb...@googlegroups.com
João,

Eu falei besteiras quando disse que a função getc() gera um reentrancy, isso só acontece quando temos delay_ms(...) e chamadas de funções com passagens de parâmetro (ao menos que eu tenha presenciado, foram essas situações programando PIC com CCS).

O que vc acha de controlar seu buffer da forma que está abaixo? sobre o getc() eu concordo com o Rogerio, que ela fica aguardando a chegada de um byte. Mas, como vc já houve uma interrupção por INT_RDA, isso siginifica que o dado já está pronto para ser lido.

int8 Buffer[26];
Void int_rda(){ 
static int8 i =0;
char c;
   c = getc();
   if(!flagBufferFull)
   {
     Buffer[i++] = c;
     /*eu ainda colocaria um timeout aqui, para ter um tempo máximo entre bytes e caso o mesmo estoure, ele seria responsável por limpar o buffer, zerar o índice e flag de buffer cheio*/
     if(i>26)
     {
       i=0;
       flagBufferFull = TRUE;
    }
  }
}

void main()
{
    while(true)
    {
        if(flagBufferFull == TRUE)
        {
              flagBufferFull = FALSE;
              /*trata os dados aqui*/

        }

}

Em terça-feira, 24 de março de 2015 09:04:11 UTC-3, Joao Mario Vizarim Bononi escreveu:
Legal, bem pensado!!!
Obrigado

Ronaldo Lins

unread,
Mar 24, 2015, 8:50:37 AM3/24/15
to sis_emb...@googlegroups.com
*faltou fechar uma chave para fechar o while(true){}

Joao Mario Vizarim Bononi

unread,
Mar 24, 2015, 2:27:17 PM3/24/15
to sis_emb...@googlegroups.com
Boa tarde Ronaldo,

vou experimentar seu codigo e ver o que acontece, achei muito funcional,

em relação ao timeout eu fiz de uma maneira muito para iniciante no assunto (pois sou mesmo...rsrs)

criei uma int interna pelo estouto do timer 0; a cada 10ms ele estoura e zera o buffer e o indice...ate q fico bom..

abraços

Ronaldo Lins

unread,
Mar 24, 2015, 2:49:51 PM3/24/15
to sis_emb...@googlegroups.com
Olá, João!

Também, estou no inicio nessa jornada que não tem fim... estou na área há pouco mais de 3 anos, então ainda tenho muito que aprender com vocês daqui do sis_embarcados. 

Segue uma sugestão de timeout, não testei pra saber se está 100%, acredito que vai funcionar.

void isr_RTCC() //overflow = 1ms
{
   static int8 count = 0;
   if(flagInterBytes == TRUE)
   {
        if(++count == 100)
        {
             flagInterBytes = FALSE;
             count = 0;
             index = 0;
       }
   }
   else
       count = 0;
}

int8 Buffer[26];
int8 index =0;
Void int_rda(){ 
char c;
   c = getc();
   if(!flagBufferFull)
   {
     Buffer[index++] = c;
     if(index>26)
     {
       index=0;
       flagBufferFull = TRUE;
       flagInterBytes = false;
    }
    else
       flagInterBytes = TRUE; /*inicia timeout*/

Ronaldo Lins

unread,
Mar 24, 2015, 3:35:45 PM3/24/15
to sis_emb...@googlegroups.com
Tenho uma ressalva no controle do buffer, que foi feita pelo nosso amigo Felipe Picada:
    substitua o trecho de código
     if(index>26) //dessa forma teremos problema com invasão de memória
     {
       index=0;
       flagBufferFull = TRUE;
       flagInterBytes = false;
    }

   por
     if(index>=26) //poderia ser somente comparando com '=='26, mas, prefiro proteger o Buffer com '>=', assim por default se o index ultrapassar o tamanho de buffer em qualquer hipótese ele estará protegido
     {
       index=0;
       flagBufferFull = TRUE;
       flagInterBytes = false;
    }
    existem formas também de controlar o buffer... você pode incrementar o index somente enquanto ele for menor que o tamanho do buffer...

   Ainda de carona, nesse detalhe você também pode melhorar o seu timeout, substituindo 
        if(++count == 100)
        {
             flagInterBytes = FALSE;
             count = 0;
             index = 0;
       }

      Por

        if(++count >= 100)

Joao Mario Vizarim Bononi

unread,
Mar 26, 2015, 8:35:46 PM3/26/15
to sis_emb...@googlegroups.com
Ronaldo, tudo bem?

agradeço a ajuda e anotei todas as suas ideias e vou colocar elas em pratica logo logo,
depois te dou um retorno, pois fiz a programação como eu havia falado e a placa programada esta com o meu parceiro para fazer um "robozinho"
para ficar pegando os dados os dados das IHM e jogar no banco de dados....

obrigado pela força e um grande abraço.

Ronaldo Lins

unread,
Mar 27, 2015, 7:10:32 AM3/27/15
to sis_emb...@googlegroups.com
Bom dia, João!

Fico contente por ajudar e espero que tenha sucesso no seu projeto.

Abraços.
Reply all
Reply to author
Forward
0 new messages