Ir ao conteúdo

Posts recomendados

Postado

    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);              
        }
    }
}
      
  


  

 

  • Membro VIP
Postado

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.

 

Postado
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:

 

 

  • Membro VIP
Postado

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.

 

 

Postado

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.

  • Membro VIP
Postado

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
Postado

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

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

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!