Comunicação Serial UART com PIC
Para enviar dados de qualquer microcontrolador PIC para qualquer dispositivo (seja outro uC, computador e etc) utilizando a interface UART, basta ativar o suporte à comunicação serial do compilador ( #use rs232 ) ou fazer uma inclusão de biblioteca ao seu código ( #include < uart.c >). A única diferença estaria nos comandos para controle da comunicação e inicialização:
-------------------------------
#use rs232 (baud = (velocidade), xmit = (pino tx), rcv = (pino rx) ) // inclui e configura a comunicação
putc (); // envia dado pela porta serial
getc (); // recebe dado pela porta serial
------------------------------
#include < uart.c > // inclui a comunicação (configuração dos pinos é automática)
uart_unicializa ( (UxBRG), 1); // configura velocidade da comunicação (prefira velocidades tabeladas
// como: 9600, 19200, etc
uart_transmite (); // envia dado pela porta serial
uart_recebe (); // recebe dado pela porta serial
------------------------------
Atenção: O UxBRG é a velocidade da comunicação, obtido através do calculo:
UxBRG = Fosc/2
____________ -1
16 * Baud Rate
____________ -1
16 * Baud Rate
Exemplo simples para melhor entendimento:
___________________________________________________
Código do Chip 1 :
#include < 16f628a.h > // define o microcontrolador utilizado
#use delay(clock=4000000) // define o cristal utilizado#fuses intrc_io, nowdt, nolvp, nomclr, put // configura os fusíveis
#use rs232(baud=9600 , xmit = pin_b2, rcv = pin_b1) // configura a velocidade da comunicação,
// pino transmissor e pino receptormain() // inicio do programa
{
while(true) // loop infinito
{
putc ('g'); // envia o caractere "g"
delay_ms(500); // espera 500 milisegundos
putc('r'); // envia o caractere "r"
delay_ms(500); // espera 500 milisegundos
} // volta para o loop
}
Código do Chip 2 :
#include < 16f628a.h > // define o microcontrolador utilizado
#use delay(clock=4000000) // define o cristal utilizado#fuses intrc_io, nowdt, nolvp, nomclr, put // configura os fusiveis
#use rs232(baud=9600 , xmit = pin_b2, rcv = pin_b1) // configura a velocidade da comunicação,
// pino transmissor e pino receptor
char dado = 0; // variável global de nome "dado"
main() // início do programa
{
while(true) // loop infinito
{
dado = getc(); // "dado" é igual ao que for recebido pela comunicação
if (dado == 'g') output_high(pin_a3), output_low(pin_a1); // se "dado" for "g" seta pino a3 e desliga a1
}
_____________________________________________
obrigado,estava tentando uma comunicação serial a muito tempo(1 ano),baixei varios tutoriais,mas não estava entendendo,somente esta explicação simples resolveu meu problema,vlw mesmo e continue ajudando quem precisa!!!
ResponderExcluirMuito bacana gostei da explicação! Bom meu caro se eu substituir o primeiro pic por um transmissor rf, que envia um pacote de dados com 8 bits de endereço + 4 bits de dados, como que poderia ser feito para o pic reconhecer esse monte de dados e acender um led, e quando eu enviasse novamente a sequencia desligasse o led?
ResponderExcluirBom... é so você pegar o primeiro dado e armazenar em uma variavel x e os outros 4 bits em uma variavel y.
ExcluirSe o endereço de quem transmitiu bater com o seu endereço, faça determinada ação.
Para o exemplo do Led ficaria assim.
int endereco = 0;
int dado = 0;
int1 led = 0;
main (void){
while(true){
endereco = getc(); //fica travado esperando 1º dado (8 bits)
dado = getc(); //fica travado esperando 2º dado (4 bits)
if(endereco == 0x34) led == !led, endereco = 0;
if(led) output_high(pin_x);
else output_low(pin_x);
}
}
Lembrando que este método só funciona se o 2º dado for composto por 8 bits na transmissão, do contrario o programa ficará esperando pelos outros 4 bits restantes e resultará em erro, no caso você teria que criar uma biblioteca própria.
PS.: getc(); faz com que seu programa fique travado esperando a recepção de dado. Para isso nao ocorrer você precisa fazer com que a recepção gere uma interrupçãono caso a #int_RDA.
Depois eu faço um post sobre essa interrupção.
abraço =).
Então quer dizer que se o transmissor enviar somente os 8 bits, utilizando esse código de para o exemplo do led, eu posso eliminar a linha:
Excluirint dado = 0;
dado = getc(); //fica travado esperando 2º dado (4 bits)
Estou certo, sim ou não.
e quando voce define "if(endereco == 0x34) led == !led, endereco = 0;" esse 0x34 representa a sequencia recebida do transmissor e eu posso determinar qualquer valor? No caso se o valor for igual ao valor determinado ele acende o led, ser o valor recebido for diferente apaga o led, seria assim o funcionamento? E nesta linha "if(led) output_high(pin_x)" no lugar de (pin_x) eu coloco por exemplo (pin_a0), seria isto mesmo!
Gostei muito dos exemplos, agora eu gostaria de saber se tem como substituir o microcontrolador que transmite os dados por um módulo transmissor de rf e como fazer para o microcontrolador que recebe a informação por um módulo receptor de rf reconhecer esta informação executar uma tarefa "acender um led" e depois desligar o mesmo led.
ResponderExcluirDa para fazer isso tranquilamente amigo =). Se o seu módulo tiver o pinos de comunicação (TXD e RXD) é só você pegar o catalogo do módulo e configura-lo (velocidade da comunicação, endereçamento, etc.).
ExcluirDai pra frente é só estabelecer uma comunicação com o módulo normalmente, como se a comunicação fosse com fios.
Eu vou postar aqui, mais tarde, um tutorial sobre como fazer comunicação com um módulo GSM e como enviar e receber mensagens :).
Obrigado pela informação!
ExcluirMuito bom!!!
ResponderExcluirObrigado.
Obrigado por comentar ! =)
Excluir