Recepção Serial no PIC (>70 caracteres)

Software e Hardware para uC PIC

Moderadores: andre_luis, 51, guest2003, Renie

Recepção Serial no PIC (>70 caracteres)

Mensagempor wandersonrainer » 22 Nov 2009 19:01

Olá a todos,

estou implementando um sistema no qual o PIC recebe de um determinado equipamento strings de tamanhos de 7, 17 ou 75.
As de tamanho 7 e 17 o programa consegue recebê-las normalmente e voltar à sua operação normal. Porém, ao receber 75 caracteres, o programa trava.
Alguém sabe se existe um buffer com determinado tamanho para recepção pela USART?

Obrigado a todos.

PS: A recepção está sendo feita vai interrupção.
wandersonrainer
Bit
 
Mensagens: 31
Registrado em: 09 Abr 2007 17:00

Mensagempor Jozias del Rios » 22 Nov 2009 19:20

Pode postar o código?
Os vencedores são aqueles que sabem o que fazer se perderem.
Os perdedores são aqueles que não sabem o que fazer se ganharem.
Avatar do usuário
Jozias del Rios
Byte
 
Mensagens: 279
Registrado em: 31 Out 2009 03:36
Localização: SJCampos-SP

postando o codigo

Mensagempor wandersonrainer » 22 Nov 2009 19:24

Código: Selecionar todos
#include <string.h>

#locate  rc_reg=0x1A


char  msg[80];
char  conteudo[3];
char  chegou;
int   flag=0;
int   cont=0;
int   end=0x80;
char  fim;
int   x=0;
int   c;
int   tam;

#byte porta=0x05
#byte portb=0x06
#byte portc=0x07
#byte portd=0x08
#byte porte=0x09
#byte txsta=0x98
#byte rcsta=0x18


#bit  rs = porte.2
#bit  enable = porte.1
#bit  led=portb.7
#bit  bt1=portb.0
#bit  bt2=portb.1
#bit  bt3=portb.2
#bit  bt4=portb.3

void comando_lcd(int caractere)
{
   rs=0;
   enable=1;
   portd=caractere;
   delay_ms(3);
   enable=0;
}

void escreve_lcd(int caractere)
{
   rs=1;
   enable=1;
   portd=caractere;
   delay_ms(3);
   enable=0;
}

void inicializa_lcd()
{
   comando_lcd(0b00111100);
   comando_lcd(0b00001100);
}

void limpa_lcd()
{
   comando_lcd(0b00000001);
}

void limpa_msg(void)
{
   tam=strlen(msg);
   for(x=0;x<tam;x=x+1)
   {
      msg[x]=0;
      printf("%c",msg[x]);
      delay_ms(100);
   }
   x=0;
}

#int_rda
void  recebido(void)
{
   
   chegou=rc_reg;
     
   msg[cont]=chegou;
   
   cont=cont+1;
   
   if(chegou==0x0A)
   {
   flag=flag+1;
   }
   
   if(flag>=2)
      {
         if(cont>4 && cont<10)//Testa se 2 vezes 0x0A é refetente a AT OK
         {
         limpa_lcd();
         comando_lcd(0x80);
         printf(escreve_lcd, "FOI ATOK");
         comando_lcd(0xC0);
         printf(escreve_lcd, "%u", cont);
         comando_lcd(0xC4);
         tam=strlen(msg);
         printf(escreve_lcd,"%u",tam);
       
         cont=0;
         flag=0;
         limpa_msg();
         }
         if(cont>10 && cont<20)//Teste se 2 vezes 0x0A é refetente a +CMTI
         {
         limpa_lcd();
         comando_lcd(0x80);
         printf(escreve_lcd, "FOI +CMTI");
         comando_lcd(0xC0);
         printf(escreve_lcd, "%u", cont);
         cont=0;
         flag=0;
         limpa_msg();
         }
         [b]if(cont>50 && flag>4)
         {
         limpa_lcd();
         comando_lcd(0x80);
         printf(escreve_lcd, "FOI +CMGR");
         comando_lcd(0xC0);
         printf(escreve_lcd, "%u", cont);
         cont=0;
         flag=0;
         led=~led;
         delay_ms(200);
         led=~led;
         delay_ms(200);
         led=~led;
         delay_ms(200);
         //limpa_msg();
         //tam=strlen(msg);
         }[/b]

      }
   
 
}



void main()
{
   set_tris_a(0b00000000);
   set_tris_b(0b00001111);
   //set_tris_c(0b00000000);
   set_tris_d(0b00000000);
   set_tris_e(0b00000000);
 
   porta=0;
   portb=0;
   portc=0;
   portd=0;
   porte=0;
   
   fim=26;
   
   //txsta=0b10100100;
   //rcsta=0b10010000;
   
   inicializa_lcd();
   limpa_lcd();
   
   comando_lcd(0x80);
   printf(escreve_lcd,"TESTE GERAL");
   
   //printf("ATE0\n\r");
   
   //printf("AT+CMGD=1\n\r");
   delay_ms(200);
   
   enable_interrupts(global);
   enable_interrupts(int_rda);
   
//!   printf("AT+CMGF=1\n\r");
//!   delay_ms(500);
//!   
//!   printf("AT+CMGD=1\n\r");
//!   delay_ms(500);
      limpa_msg();
   while(1)
   {
   
      if(bt1==0)
      {
         while(bt1==0)
         {
         }
      printf("AT\n\r");
      }
      if(bt2==0)
      {
         while(bt2==0)
         {
         }
      printf("AT+CMGF=1\n\r");
      }
      if(bt3==0)
      {
      printf("AT+CMGR=1\n\r");
         while(bt3==0)
         {
         }
      }
      if(bt4==0)
      {
      printf("AT+CMGD=1\n\r");
         while(bt4==0)
         {
         }
      }
   }
}



A parte em negrito é a que trava.
O PIC utilizando é o PIC16F877A.
Editado pela última vez por wandersonrainer em 22 Nov 2009 19:32, em um total de 2 vezes.
wandersonrainer
Bit
 
Mensagens: 31
Registrado em: 09 Abr 2007 17:00

Mensagempor Jozias del Rios » 22 Nov 2009 19:30

Por favor edite a sua mensagem e use "[code]' ao início e "[/code]" ao fim do código postado, conforme as regras do forum. Os leitores agradecem ;-)
Os vencedores são aqueles que sabem o que fazer se perderem.
Os perdedores são aqueles que não sabem o que fazer se ganharem.
Avatar do usuário
Jozias del Rios
Byte
 
Mensagens: 279
Registrado em: 31 Out 2009 03:36
Localização: SJCampos-SP

Mensagempor Alesandro F Zagui » 23 Nov 2009 11:00

A RAM do 16F877 é muito pequena, tente migrar pro 18F452, é compatível pino a pino e em alguns lugares é até mais barato.
Alesandro Freire Zagui
Alesandro F Zagui
Byte
 
Mensagens: 154
Registrado em: 12 Mai 2009 11:03
Localização: Campo Mourao, Pr

Mensagempor leoabubauru » 23 Nov 2009 12:30

wanderson

Trate o LCD fora da interrupção. Suas rotinas de LCD têm delays de 3ms o que pode realmente travar o micro dependendo da taxa de comunicação e da quantidade de bytes. Ou seja, sua rotina mal terminou (se é que terminou!) de trar um byte e já tem outro chegando. Quando a mensagem é grande (>70 no seu caso) isso vira uma loucura para o uC.

Não acho necessário trocar por um 18F452. O 777 dá conta do recado. Preencha um buffer e trate-o no MAIN. É bem mais seguro!
Tento, tento e tento...
Me arrebento!
Também bato!
Ô negocim bunitim essa tal eletrônica de barco!
leoabubauru
Byte
 
Mensagens: 227
Registrado em: 21 Nov 2006 19:08
Localização: São Paulo

Mensagempor wandersonrainer » 24 Nov 2009 18:50

leoabubauru escreveu:wanderson

Trate o LCD fora da interrupção. Suas rotinas de LCD têm delays de 3ms o que pode realmente travar o micro dependendo da taxa de comunicação e da quantidade de bytes. Ou seja, sua rotina mal terminou (se é que terminou!) de trar um byte e já tem outro chegando. Quando a mensagem é grande (>70 no seu caso) isso vira uma loucura para o uC.

Não acho necessário trocar por um 18F452. O 777 dá conta do recado. Preencha um buffer e trate-o no MAIN. É bem mais seguro!


Ok, valeu pela dica. :wink:
wandersonrainer
Bit
 
Mensagens: 31
Registrado em: 09 Abr 2007 17:00

Mensagempor Jozias del Rios » 24 Nov 2009 20:04

Não foi justamente isso que eu falei em outro tópico faz 1 semana?
para o cara tirar "lcd_pos_xy" e "printf" da porcaria da interrupção de recepção da uart....

eu acho que todo microcontrolador deve ser aprendido primeiro a se mexer em ASM, para depois se ir para o C....

tem gente que perde a noção do que acontece por trás completamente!

just my 50 cents
abs!
Os vencedores são aqueles que sabem o que fazer se perderem.
Os perdedores são aqueles que não sabem o que fazer se ganharem.
Avatar do usuário
Jozias del Rios
Byte
 
Mensagens: 279
Registrado em: 31 Out 2009 03:36
Localização: SJCampos-SP

Mensagempor wandersonrainer » 24 Nov 2009 20:40

Jozias del Rios escreveu:Não foi justamente isso que eu falei em outro tópico faz 1 semana?
para o cara tirar "lcd_pos_xy" e "printf" da porcaria da interrupção de recepção da uart....

eu acho que todo microcontrolador deve ser aprendido primeiro a se mexer em ASM, para depois se ir para o C....

tem gente que perde a noção do que acontece por trás completamente!

just my 50 cents
abs!


Ok meu caro, mas o problema foi resolvido sem essa alteração.
Foi constatado que, de acordo com as mensagem recebidas pelo equipamento (modem GSM), o programa SEMPRE entrava no segundo IF.
O problema foi resolvido sem retirar as chamadas de escritas no LCD de dentro da interrupção da USART, pois os tempos de recepção dos caracteres, de acordo com a velocidade de transmissão, foram devidamente calculados.

Abs (take it easy).
wandersonrainer
Bit
 
Mensagens: 31
Registrado em: 09 Abr 2007 17:00

Mensagempor msamsoniuk » 24 Nov 2009 23:01

olhae jozias! ponto para o C! hehehe mal ae, eu nao resisti! :)

wandersonrainer escreveu:
Jozias del Rios escreveu:Não foi justamente isso que eu falei em outro tópico faz 1 semana?
para o cara tirar "lcd_pos_xy" e "printf" da porcaria da interrupção de recepção da uart....

eu acho que todo microcontrolador deve ser aprendido primeiro a se mexer em ASM, para depois se ir para o C....

tem gente que perde a noção do que acontece por trás completamente!

just my 50 cents
abs!


Ok meu caro, mas o problema foi resolvido sem essa alteração.
Foi constatado que, de acordo com as mensagem recebidas pelo equipamento (modem GSM), o programa SEMPRE entrava no segundo IF.
O problema foi resolvido sem retirar as chamadas de escritas no LCD de dentro da interrupção da USART, pois os tempos de recepção dos caracteres, de acordo com a velocidade de transmissão, foram devidamente calculados.

Abs (take it easy).
Avatar do usuário
msamsoniuk
Dword
 
Mensagens: 2935
Registrado em: 13 Out 2006 18:04

Mensagempor Djalma Toledo Rodrigues » 24 Nov 2009 23:27

wandersonrainer escreveu: ... mas o problema foi resolvido sem essa alteração....

Compartilha.
Avatar do usuário
Djalma Toledo Rodrigues
Dword
 
Mensagens: 2334
Registrado em: 03 Ago 2008 13:22


Voltar para PIC

Quem está online

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

x