Ir ao conteúdo
  • Cadastre-se

PIC Interrupção serial (RX C7) trava após enviar (TX C6) char pro PC, CCS


Posts recomendados

    Pessoal, estou tendo um problema aqui e não estou conseguindo resolver, ainda estou em fase de aprendizado e não sei o que ocorre, se é algum bit de algum registrador de transmissão que devo limpar, se é a interrupção serial que preciso limpar clear_interrupts(INT_RDA);. Já fiz de tudo e nada da certo.

 

    Aqui está apenas um pedaço do código, já estou utilizando 66% de um 16F876a.

    Hoje já consigo pegar a string que chega no RX(hardware) faço o que tenho que fazer com ela e envio para o pc via TX(hardware) e isso funciona perfeitamente.

    A variável resposta, se ela for 1(TRUE) quando o PIC lê sensores/pinos de entrada, ela deve enviar um determinado caracter para o PC, só que ao fazer isso a interrupção serial #INT_RDA para de funcionar.

    Se a variável resposta, for 0(FALSE), ou seja, nunca envie caracter para o PC, a interrupção serial funciona perfeitamente. Observação¹: ela sempre para quando chega um determinado numero de caracteres, e em seguida logo após uma determinada função que demora uns 5 segundos pra ocorrer, a interrupção serial é reativada e isso funciona PERFEITAMENTE. 

    Não estou conseguindo saber porque trava/para após enviar um caracter ao PC. Observação¹: Sempre que envio um caracter ao computador a interrupção serial está ativada (ao menos era pra estar) pois até então o PIC não leu nada dela e então não foi desativada.

 

#include <16F876a.h> 
#case                     
#use delay(clock=10000000)  
  
#fuses HS,NOWDT, PUT, BROWNOUT, NOLVP
#use rs232(baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, stop=1, ERRORS)
  
int1 resposta=1;
char X='X';
char Y='Y';

#INT_RDA
void serial_isr()
{
    restartRS232();  // Está aqui desnecessariamente
    int t;  
    
    buffer[next_in]=getc(); 
    t=next_in; 
    next_in=(next_in+1)%BUFFER_SIZE;  
    if(next_in==next_out) next_in=t;    
}
  
BYTE bgetc()
{
    BYTE c; 
    while(!bkbhit); 
    c=buffer[next_out];
    next_out=(next_out+1)%BUFFER_SIZE;
    return(c);
}

void main()
{
    enable_interrupts(GLOBAL);
    enable_interrupts(INT_RDA);
  	
  	while(TRUE)
    {
            if(bkbhit)
        	{
            c=bgetc();
            if(c=='0') 
            {
                key_card=TRUE;
                limpa_teclado();
                output_high(BEEP);
                delay_ms(40);
                output_low(BEEP);
                barcode_buffer[0]=c;       
                barcode_buffer[1]=bgetc();  
                barcode_buffer[2]=bgetc();  
                barcode_buffer[3]=bgetc();  
                barcode_buffer[2]=0;        
                printf("%c%c%c%c%c%cC\n\r",barcode_buffer[0],barcode_buffer[1],barcode_buffer[2],barcode_buffer[3]);
                d_int_rda=FALSE;
                disable_interrupts(INT_RDA);
                codigo_lido();
            }
             /*******************************************************************************************/ 
             if((resposta)&&(!input(SENSOR_S))) printf("%c\r\n",X);
             if((resposta)&&(!input(SENSOR_E))) printf("%c\r\n",Y);              
        }
    }
}
      
  


  

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Não entendei muito bem... só foquei no

13 horas atrás, erpgc82 disse:

enviar um determinado caracter para o PC, só que ao fazer isso a interrupção serial #INT_RDA para de funcionar.

Assim sendo sugiro que trabalhe diretamente nos bytes e bits dos registradores. P.ex. avalie o flag, ative o habilitador das interrupts diretamente em seu seu bit e não fique dependendo do sw mastigado do seu compilador e suas libs.

 

Também 1/2 que percebo que parece que você desabilita a interrupt ...

13 horas atrás, erpgc82 disse:

printf("%c%c%c%c%c%cC\n\r",barcode_buffer[0],barcode_buffer[1],barcode_buffer[2],barcode_buffer[3]); d_int_rda=FALSE; disable_interrupts(INT_RDA);

... e não habilita mais. O que está coerente com...

13 horas atrás, erpgc82 disse:

enviar um determinado caracter para o PC, só que ao fazer isso a interrupção serial #INT_RDA para de funcionar.

 

Link para o comentário
Compartilhar em outros sites

5 horas atrás, .if disse:

Não entendei muito bem... só foquei no

Assim sendo sugiro que trabalhe diretamente nos bytes e bits dos registradores. P.ex. avalie o flag, ative o habilitador das interrupts diretamente em seu seu bit e não fique dependendo do sw mastigado do seu compilador e suas libs.

 

Também 1/2 que percebo que parece que você desabilita a interrupt ...

... e não habilita mais. O que está coerente com...

Olá If, é isso mesmo, desabilito a interrupção e ao reabilitar ela nao volta funcionar.

 

mas...

Se eu não enviar nenhum comando ao computador/software através do pino TX, exemplo, não houver nenhum printf, a interrupção serial reabilita normalmente.

 

Mas se enquanto a interrupção estiver desabilitada, eu enviar algum caracter ao computador, pelo TX, para o software/pc, a interrupção nao reativa mais...

 

vou fazer um teste aqui de não desativar a interrupção mais... E apenas usar uma flag, e se chegarem caracteres no momento que não era para chegarem, eles serão apagados... irei fazer isso, depois posto aqui se este problema estará resolvido.

5 horas atrás, .if disse:

 

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

Minha vaga lembrança... como este mc tem buffer limitado, ele usa tanto o tx como rx o mesmo byte/registro... EDIT: ERREI..😳.. TXREG e RCREG são registros distintos...Portanto enquanto você estive printandof penso que não pode contar com a recepção e vice versa. Aguarde chegar o pacote de dados e só depois mande imprimir - com int. desab. Depois de print, hab. de novo.

Outra coisa...

Meio que me lembrei que este chip só tem 1 vetor de interrupt. Você deve avaliar se o bit da  serial é que foi ativado.  Não sei se tem que desativar ele manualmente assim que cai na interrupt ou se ele zera sozinho. Por isso que sempre digo que é bom trabalhar com acesso aos registros e analisar bit a bit. Se achar que deve, consulte o datasheet  do mc. Também pode varrer a net e achar exemplo pronto pra seu compilador.

 

 

Link para o comentário
Compartilhar em outros sites

Acabei de testar aqui, e o problema não é nem a interrupção, configurei agora para NUNCA  a interrupção serial ser desabilitada, e mesmo assim, ao enviar um caracter qualquer ex: printf("x") para o pc/software a interrupção para de funcionar, realmente não sei o que está havendo, vou deixar isso de lado e depois volto, pois preciso enviar caracteres para o pc/software.

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

A printf é muuuuuuito gulosa, além de comer recursos e memória pode estar zoando o barraco. Envie 1 caracter por vez algo como putc(). Minha (minha) preferência é criar minhas próprias rotinas de envio serial algo como:
 

minha_putc(d)
{
TXREG=d; 
while(!TMRT);
}

minha_printf(const char * dado)
{
while(*dado) minha_putc(*dado++);
}
...

minha_printf(“The quick brown fox jumps over the lazy dog”);
//todas as letras do alfabeto

Pra esta façanha, hás de sujar as mãos e dar uma olhadela no datasheet do seu mc e ver a função e operação dos registros e bits.

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

eu estava utilizando a diretiva #use fast_io(c)

no main()
{
    set_tris_c(0b00000100);

    output_c(0b00000011);

     while(TRUE)

    {

    }


}
Os pinos do TX e RX estavam como portas de saída em nivel baixo, mas funcionavam...
porém quando removi a diretiva #use e o set_tris, o problema resolveu no mesmo minuto, depois de 1 semana de sofrimento, só pode ter sido isso.

agora estou vendo aqui como configurar apenas certos pinos do port C

12 horas atrás, .if disse:

A printf é muuuuuuito gulosa, além de comer recursos e memória pode estar zoando o barraco. Envie 1 caracter por vez algo como putc(). Minha (minha) preferência é criar minhas próprias rotinas de envio serial algo como:
 


minha_putc(d)
{
TXREG=d; 
while(!TMRT);
}

minha_printf(const char * dado)
{
while(*dado) minha_putc(*dado++);
}
...

minha_printf(“The quick brown fox jumps over the lazy dog”);
//todas as letras do alfabeto

Pra esta façanha, hás de sujar as mãos e dar uma olhadela no datasheet do seu mc e ver a função e operação dos registros e bits.

 

👆 Veja aí o que era! 🙂

no forum do ccs os "senior" lá me disseram agora, que não se utiliza FAST_IO mas eu aprendi a usar sempre nos livros do Brasil, definir pinos de entrada e de saída... enfim.. era isso, falta de atenção com o TX e RX

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

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

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!