Ir ao conteúdo

PIC receber String pela Serial RS232


CeDahmer

Posts recomendados

Postado

Boa tarde amigos. Mais uma vez venho pedir ajuda:

Estou precissando obter uma string de 10 letras no meu microcontrolador enviado pela porta serial do PC. Estou usando o PIC 16F877a na linguagem C com o compilador CCS.

Usei vários métodos sugeridos em outros tópicos aqui mesmo no fórum, mas não consegui eficiencia na obtenção de mais de 2 caracteres. Agora estou testando outro método o problema é que trava e só volta a funcionar quando recebe, ou quando o watchdog reinicia, mas aí volta a travar. Abaixo descreverei o código que estou usando

#use rs232(baud=9600, xmit = PIN_C6, rcv = PIN_C7, parity = N, bits = 8, errors)

char BytesRecebidos[10]; // variável de escopo geral

//A função abaixo é chamada de dentro do loop infinito

Void Receber_RS232() {

gets(BytesRecebidos);

}

Desta forma recebe a string completa e na ordem certa que envio do PC, mas não faz as chamadas das outras funções que estão escritas abaixo dela no loop.

Se alguém puder me ajudar, Obrigado.

Postado

Seu vetor está sendo mal usado.

veja:



#use rs232(baud=9600, xmit = PIN_C6, rcv = PIN_C7, parity = N, bits = 8, errors)

char byterecebido[10];
int i;

void recebe()
{
for (i=0;i>=9;i++)
{
gets(byterecebido[i]);
}
}

com isso a rotina so vai fazer um loop de 10 vezes.

abs.

Postado

Serial é algo nada confiavel. Nao sei porque mas nao gosto desse tipo de comunicacao?

você sempre enviara 10bytes? em sequencia?

Eu faria algo mais na "mao grande" hehe.

Esperaria acontecer a interrupcao da recepcao do primeiro byte, e ficaria aguardando os outros 9 bytes dentro da propria rotina de interrupcao (só saindo dela depois de ter recebido os 10bytes) e com um timeout, para o caso de menos de 10bytes serem recebidos em sequencia, ai você poderia considerar que ocorreu erro. E usaria um baudrate alto, de preferência, para o PIC nao ficar muito tempo preso na rotina de interupcao esperando receber os 10bytes. Mas esta é só uma ideia, dependeria de outras necessidades do porjeto fazer desta forma.

Postado

Obrigado a todos pelas respostas e dedicação em me auxiliar.

Em alguns dias eu li mais de 500 páginas em uns 200 sites sobre o assunto, e acabei descobrindo que não existe nenhuma forma mágica de fazer o PIC receber uma palavra enviada pelo computador ou outro microcontrolador, e esta dúvida é muito frequênte entre os programadores. Mas existe sim solução. Mas ela não é mágica, e necessita ser criada pelo programador seguindo sua necessidade.

É necessário criar um protocolo próprio, por mais ***** que pareça, o importânte é que funcione e que não utilize muito recurso do microcontrolador. Então segundo esse princípio perdi um dia tentando e depois de umas 100 gravações no PIC consegui um protocolo rudimentar, que ainda precissa ser melhorado, mas que cumpre sua função.

Abaixo passarei o código:

int8 i;

char RS232;

if (kbhit())

{

rs232=getch();

if (rs232!=0){

se++; // variável global

BR[(int)se/2]=rs232;

}

if (se>=20) {

se=0;

for (i=0;i>=10;i++) {BR=0;}

}

}

printf("F%c%c%c%c%c%c%c%c%c",BR[0],BR[1],BR[2],BR[3],BR[4],BR[5],BR[6],BR[7],BR[8],BR[9]);

O princípio do funcionamento também está baseado na forma como fiz para enviar os dados a partir do computador, pois utilizei o Visual Basic na verão 6 utilizando o componente MSCOMM.

Como o buffer do USART do microcomputador receber ou armazena 3 bytes por vez, eu envio do computador esses 3 bytes por vez, sendo que o último seja o retorno de carro ou o Enter como preferir 'Chr(13)', o primeiro é a letra desejada, e o segundo pode ser o comando responsável pela nova linha ou 'Chr(10)', ou poderia ser ainda outro Enter, ou qualquer outra letra, ela será apagada mesmo. Conforme o microcontrolador ir recebendo, ele irá acrescentando a variável 'se' de 2 em 2, por isso é dividido por 2 e jogado só o primeiro byte na matriz 'BR' com o índice correspondente ao valor da variável 'se'. Ao chegar no valor máximo que é 20 a variável é zerada e o processo recomeça criando uma nova palavra. Assim para ter certeza que está funcionando o 'printf' devolve ao PC a palavra montada.

Assim posso alterar a data do RTC Ds1307 que está acoplado com o código:

if (BR[0]=='D' && BR[9]=='D'){

gravar_ds1307(4,get_bcd(BR[1] & BR[2])); delay_ms(10);

gravar_ds1307(5,get_bcd(BR[4] & BR[5])); delay_ms(10);

gravar_ds1307(6,get_bcd(BR[7] & BR[8])); delay_ms(10);

}

No VB o código foi:

Private Sub cmdEnviar_Click()

If MSComm1.PortOpen = True Then

MSComm1.Output = txtEnviar.Text & Chr(10) & Chr(13)

End If

End Sub

Este foi o método que achei, sei que ainda está ineficiente. se alguém quiser contribuir, muito me ajudará. Ainda vou testar as outras soluções postadas aqui neste tópico.

Postado

Não entendí a dificuldade?

Não programo em C para µcontroladores,mas sempre faço praticamente o que o Maskador citou,com a diferença que ja vou comparando byte a byte para saber se é a palavra que estou' esperando'.

  • mês depois...
Postado

Amigo,

Eu usei uma simples interrupção da serial, onde todos os caracteres são recebidos e armazenados num array de quantos bytes (char) você desejar, a qualquer momento desde que a interrupção esteja habilitada. Conforme sua aplicação você escolhe o momento de habilitar e desabilitar ou até mesmo está sempre habilitada realizando qualquer coisa, e no momento que aparece um caracter no buffer esta é acionada para recebê-lo.

no cabeçalho é importante observar a velocidade de transmissão(no seu caso: baud=9600), pois, qualquer diferença você irá receber lixo ou perder informação, o buffer do 16f887a recebe um byte e armazena no buffer que será lido enquanto continua recebendo bits para formar um novo byte, este só recebe portanto, no máximo dois bytes dentro da velocidade de transmissão estipulada, se a velocidade de envio for maior ele perderá informação.

#use rs232(baud=9600, xmit = PIN_C6, rcv = PIN_C7, parity = N, bits = 8, errors)

Int pacote[10];

void main()

{

enable_interrupts(global);

enable_interrupts(int_rda);

While(1)

{

Escreve seu código…….....

Escreve seu código…….....

}

}

#INT_RDA

void Void Receber_RS232()

{

pacote[i++]=getc();

printf (lcd_escreve,"%c",pacote); //escreve no lcd o que recebeu

//– depende da sua configuração de lcd

}

  • 3 meses depois...

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

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!