Que tal amigos foreros. Me disculpo por la tardanza para esta segunda parte de este proyecto. Sin más preámbulos continuemos.
Tal como se habrán ya dado cuenta, el protocolo de comunicación es como sigue:
16 bytes de preámbulo (0xF0) + 3 Byte Header (0xF8, 0xF8, 0xFA) + 2 bytes codificado en manchester de la longitud de los datos + datos codificados en manchester.
Pues bien para la recepción también vamos a usar un PIC12F629 y vamos a necesitar 2 puertos seriales, uno para la recepción RF y otro para mostrar los datos recibidos (RS232). El puerto serial para la recepción RF configurado a 2400 bps, 8 bits, no paridad e invertido.
El puerto RS232 a 9600 bps, 8 bits, no paridad e invertido (para evitar convertidor de TTL a RS232).
El segmento del código quedaría así:
#use rs232(baud=2400,parity=N,rcv=PIN_A1,bits=8,STREAM=RFPORT,invert)
#use rs232(baud=9600,parity=N,xmit=PIN_A0,bits=8,STREAM=RS232,invert)
Para la recepción debemos ignorar los bytes de preámbulo, lo importante es esperar los bytes de header. Nuestro código para esperar y evaluar el header sería así:
do
{
do
{
do
{
rx_data
= fgetc(RFPORT
); //Recibe el primer dato via RF } while (rx_data!=0xF8); //Si el dato recibido no es 0XF8, continua recibiendo datos
rx_data
= fgetc(RFPORT
); //Recibe el segundo dato } while (rx_data!=0xF8); //Si el dato recibido no es 0XF8, regresa al inicio y espera nuevo dato
rx_data
= fgetc(RFPORT
); //Recibe el tercer dato } while (rx_data!= 0xFA); //Si el dato recibido no es 0XFA, regresa al inicio y espera nuevo dato
Una vez que se ha recibido el header, tendremos que recibir la longitud de los datos, pero recordemos que esta está codificada en manchester, por lo tanto necesitamos la subrutina para decodificar el manchester. Esta subrutina sería así:
BYTE DECODE_DATA(int8 encoded) //decode function for manchester encoded data.
{
int8 enc, dec, pattern, i;
enc = encoded;
dec = 0;
for (i=0; i<4; i++) {
dec >>=1;
pattern = enc & 0b11;
if (pattern == 0b01) // 1
bit_set(dec,3);
else if (pattern == 0b10)
bit_clear(dec,3); // 0
else
return 0xff; // illegal code
enc >>=2;
}
return (dec);
}
Ahora bien la longitud de los datos está codificada en manchester y viene en 2 bytes, para recibirla y decodificarla, nuestro código sería así:
nib
[0] = fgetc(RFPORT
); //Recibe la primera parte baja de la longitud del frame a recibir dec1 = DECODE_DATA(nib[0]); //Decodifica la parte baja de la longitud
nib
[1] = fgetc(RFPORT
); //Recibe la parte alta de la longitud lenght = DECODE_DATA(nib[1]); //Decodifica la parte alta de la longitud del frame
lenght<<=4; //Posiciona la parte alta de la longitud
lenght |= dec1; //Ensambla la longitud del frame
Una vez que tenemos la longitud de los datos, entonces pasamos a recibir dichos datos:
for (i=0; i<lenght; i++) //Prepara para recibir los datos via RF
{
nib
[0]=fgetc(RFPORT
); //Recibe la parte baja del dato dec1=DECODE_DATA(nib[0]); //Decodifica la parte baja del dato
nib
[1]=fgetc(RFPORT
); //Recibe la parte alta del dato data_rx[i]=DECODE_DATA(nib[1]); //Decodifica la parte alta del dato
data_rx[i]<<=4; //Coloca el nible alto en su posicion correcta
data_rx[i]|=dec1; //Ensambla el dato recibido
}
Una vez recibidos los datos, pasamos a mostrarlos en la PC, enviándolos via RS232:
for (i=0;i<lenght;i++) //Prepara para enviar los datos recibidos
{
fputc(data_rx
[i
],RS232
); //Envia el dato via RS232 }
Poniendo todo junto, nuestro código final quedaría de la siguiente manera:
#include <12F629.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOCPD //No EE protection
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES PUT //Power Up Timer
#FUSES BROWNOUT //Reset when brownout detected
#FUSES RESERVED //Used to set the reserved FUSE bits
#use delay(clock=4000000)
#use rs232(baud=2400,parity=N,rcv=PIN_A1,bits=8,STREAM=RFPORT,invert)
#use rs232(baud=9600,parity=N,xmit=PIN_A0,bits=8,STREAM=RS232,invert)
int8 nib[2], i, dec1, rx_data, lenght, data_rx[32];
BYTE DECODE_DATA(int8 encoded) //decode function for manchester encoded data. This code is working fine. I checked it.
{
int8 enc, dec, pattern, i;
enc = encoded;
dec = 0;
for (i=0; i<4; i++) {
dec >>=1;
pattern = enc & 0b11;
if (pattern == 0b01) // 1
bit_set(dec,3);
else if (pattern == 0b10)
bit_clear(dec,3); // 0
else
return 0xff; // illegal code
enc >>=2;
}
return (dec);
}
void main()
{
setup_comparator(NC_NC);
setup_vref(FALSE);
fprintf(RS232
,"RF Link\n\r"); //Envia el mensaje "RF Link" while (1)
{
do
{
do
{
do
{
rx_data
= fgetc(RFPORT
); //Recibe el primer dato via RF } while (rx_data!=0xF8); //Si el dato recibido no es 0XF8, continua recibiendo datos
rx_data
= fgetc(RFPORT
); //Recibe el segundo dato } while (rx_data!=0xF8); //Si el dato recibido no es 0XF8, regresa al inicio y espera nuevo dato
rx_data
= fgetc(RFPORT
); //Recibe el tercer dato } while (rx_data!= 0xFA); //Si el dato recibido no es 0XFA, regresa al inicio y espera nuevo dato
nib
[0] = fgetc(RFPORT
); //Recibe la primera parte baja de la longitud del frame a recibir dec1 = DECODE_DATA(nib[0]); //Decodifica la parte baja de la longitud
nib
[1] = fgetc(RFPORT
); //Recibe la parte alta de la longitud lenght = DECODE_DATA(nib[1]); //Decodifica la parte alta de la longitud del frame
lenght<<=4; //Posiciona la parte alta de la longitud
lenght |= dec1; //Ensambla la longitud del frame
for (i=0; i<lenght; i++) //Prepara para recibir los datos via RF
{
nib
[0]=fgetc(RFPORT
); //Recibe la parte baja del dato dec1=DECODE_DATA(nib[0]); //Decodifica la parte baja del dato
nib
[1]=fgetc(RFPORT
); //Recibe la parte alta del dato data_rx[i]=DECODE_DATA(nib[1]); //Decodifica la parte alta del dato
data_rx[i]<<=4; //Coloca el nible alto en su posicion correcta
data_rx[i]|=dec1; //Ensambla el dato recibido
}
for (i=0;i<lenght;i++) //Prepara para enviar los datos recibidos
{
fputc(data_rx
[i
],RS232
); //Envia el dato via RS232 }
}
}
La siguiente es una imagen de un dato transmitido ("a"):
La siguiente imagen es el frame transmitido via RF:
Y finalmente la imagen en donde se recibe el caracter "a"

a_RX.JPG(17.41 kB, 454x258 - visto 1177 veces)Espero esto les pueda servir y cualquier duda o pregunta por favor no duden en hacerla.
Elreypic.