CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Another RF link over UART (one-way)

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
PICoHolic



Joined: 04 Jan 2005
Posts: 224

View user's profile Send private message

Another RF link over UART (one-way)
PostPosted: Tue Jun 30, 2015 7:25 am     Reply with quote

Hello,

Inspired by: http://www.ccsinfo.com/forum/viewtopic.php?t=22525
(Optimized and Rx timeout added [optional])

File: manchester.h

Code:

#ifndef  _MANCHESTER_H
#define  _MANCHESTER_H
///////////////////////////////////////////////////////////////////////////////
#define  MAN_PREAMB  0x55  //preamble
#define  MAN_SOP     0xFF  //Start of payload
///////////////////////////////////////////////////////////////////////////////
#endif


File manchester.c

Code:

#include "manchester.h"
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
char manchester[16]={
   0b01010101, //0
   0b01010110, //1
   0b01011001, //2
   0b01011010, //3
   0b01100101, //4
   0b01100110, //5
   0b01101001, //6
   0b01101010, //7
   0b10010101, //8
   0b10010110, //9
   0b10011001, //A 10
   0b10011010, //B 11
   0b10100101, //C 12
   0b10100110, //D 13
   0b10101001, //E 14
   0b10101010}; //F 15
///////////////////////////////////////////////////////////////////////////////
void TxManchester(int8 Dt)
{
   putc(manchester[Dt>>4], PORT1);        //MSB
   putc(manchester[Dt & 0x0F], PORT1);    //LSB
}
///////////////////////////////////////////////////////////////////////////////
signed int8 _RxManchester(int8 Dt)
{
   int8 i=0;

   while ((Dt!=manchester[i]) && (i<16))
      i++;

   return i<16?i:-1;
   
}
///////////////////////////////////////////////////////////////////////////////
int1 ManchesterToBinary(int8 msb, int8 lsb, int8 *bin)
{
   signed int8 ret1, ret2;

   ret1 = _RxManchester(msb);

   if (ret1 != -1)
   {
      ret2 = _RxManchester(lsb);
      if (ret2 != -1)
      {
         *bin = (ret1 << 4) | ret2;
         return 1;
      }
      else
         return 0;
   }
   else
      return 0;
}
///////////////////////////////////////////////////////////////////////////////


File: Tx.c

Code:

#include "manchester.c"
///////////////////////////////////////////////////////////////////////////////
void TxData(int8 *DtBuff)  //data is being sent inverted
{
   int8 i;
   int8 len = DtBuff[0];   //1st byte is length

   putc(MAN_PREAMB, PORT1);
   putc(MAN_PREAMB, PORT1);
   putc(MAN_SOP, PORT1);
   for (i=0; i<len; i++)         //send payload
   {
      TxManchester(DtBuff[i]);   //last byte in DtBuff should be checksum
   }
}
///////////////////////////////////////////////////////////////////////////////


File Rx.h
Code:

#ifndef  RX_H
#define  RX_H
///////////////////////////////////////////////////////////////////////////////
#define  MAXRXDATA      16
#define  MAXRXDATAMSK   MAXRXDATA-1
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
#endif


File: Rx.c

Code:

#include "Rx.h"
///////////////////////////////////////////////////////////////////////////////
#include "manchester.c"
///////////////////////////////////////////////////////////////////////////////
int8 RxDataBuff[MAXRXDATA];
int8 RxPrt = 0;
int1 RxDtReady = 0;
int16 MaxBytesTimeout;
///////////////////////////////////////////////////////////////////////////////
#define  RxByteTimeout        525   //in cycles = 8.4ms = time for 1 byte to get Rx @ 1200
#define  SetUARTTimeOut(n)    {MaxBytesTimeout=(RxByteTimeout*n); set_timer0(0xFFFF - MaxBytesTimeout); clear_interrupt(INT_TIMER0); enable_interrupts(INT_TIMER0);}
#define  ResetUARTTimeOut()   disable_interrupts(INT_TIMER0)
///////////////////////////////////////////////////////////////////////////////
#INT_TIMER0
void TIMER0_isr(void)
{
   //Reset all:
   RxDtReady = FALSE;
   RxPrt = 0;
   ResetUARTTimeOut();
}
///////////////////////////////////////////////////////////////////////////////
#INT_RDA2
void RDA2_isr(void)
{
   int8 d;
   static int8 RxDtPayPrt = 0;
   static int8 ExpectedLen;
   static int1 msb = 1;
   static int8 msb_data;

   d = getc(PORT2);

   switch (RxPrt)
   {
   case 0:
   case 1:
      if (d==MAN_PREAMB)
         RxPrt++;
      else
         RxPrt = 0;     //reset
      break;

   case 2:
      if (d==MAN_SOP)
         RxPrt++;
      else
         RxPrt = 0;     //reset
      break;

   case 3:
         if (!msb)
         {
            if (ManchesterToBinary(msb_data, d, &ExpectedLen)) //get binary value
            {
                  RxDataBuff[0] = ExpectedLen;
                  SetUARTTimeOut((ExpectedLen-1) * 2);
                  RxDtPayPrt = 1;   //move 2nd position
                  RxPrt++;
            }
            else
               RxPrt = 0;     //reset
         }
         else
         {
            msb_data = d;
         }
         msb = !msb;
      break;

   default:
         if (!msb)
         {
            if (ManchesterToBinary(msb_data, d, &d))  //get binary value
            {
               RxDataBuff[RxDtPayPrt++ & MAXRXDATAMSK] = d; //copy & move to next position
               if (RxDtPayPrt == ExpectedLen)
               {
                  RxPrt = 0;     //reset
                  RxDtReady = 1; //flag
               }
            }
            else
               RxPrt = 0;     //reset
         }
         else
         {
            msb_data = d;
         }
         msb = !msb;
         break;

   }

}
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////


Transmit test code:
Code:

#include "Tx.c"
//...//
Data[0] = 5;
Data[1] = 0;
Data[2] = 1;
Data[3] = 2;
Data[4] = Data[0] ^ Data[1] ^ Data[2] ^ Data[3];
TxData(Data);


Receive test code (RDAx interrupt must be enabled)
Code:

#include "Rx.c"
//...//
setup_timer_0(T0_INTERNAL | T0_DIV_32);   //for Rx timeout (525 per Rx byte) XT = 8Mhz
//..//
if (RxDtReady)
{
   RxDtReady = 0;

   if ((RxDataBuff[0] == 5) && (RxDataBuff[4] == (RxDataBuff[0] ^ RxDataBuff[1] ^ RxDataBuff[2] ^ RxDataBuff[3])))
   {
      // TO DO:...
   }
}


Important notes:
1- Baud rate should be selected carefully (should be less than the maximum bit rate supported by the RF transmitter/receiver)
2- Both UART Tx & Rx must be inverted by hardware (1 way is to use transistors or a simple inverter)

Cheers!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group