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

Need help about RC5 ?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
sarmad_101



Joined: 17 Jun 2010
Posts: 12

View user's profile Send private message

Need help about RC5 ?
PostPosted: Mon Aug 30, 2010 1:16 am     Reply with quote

I got this program and I am checking it for RC5 remote but getting garbage on the Hyper Terminal...

Anybody just tell me what should be the problem in it?
Code:

#include <18F452.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOOSCSEN                 //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES BORV20                   //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES STVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOCPD                    //No EE protection
#FUSES NOCPB                    //No Boot Block code protection
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads

#use delay(clock=8000000)
#use rs232(baud=9600,xmit=PIN_C6,rcv=PIN_C7)

#use FAST_IO(A)                           //don't keep setting TRIS registers
#use FAST_IO(C)

/*
 * USEFUL CONSTANTS
 */
#define FUZZY 2            //Nothing is perfect, allows for some signal slop
//NEC
#define NEC_TMR1_HIGH   41   //Sets for 110ms rollover timeout
#define NEC_TMR1_LOW   39
#define NEC_LEADIN   210      //TMR0 timings, this is 13.5ms
#define NEC_ONE      34      //'1' bit
#define NEC_ZERO   17      //'0' bit - These timings are high and low times together
#define NEC_REPEAT   175      //If a button is held down.
//SONY
#define SONY_TMR1_HIGH   168   //Sets for a 45ms timeout
#define SONY_TMR1_LOW   27
#define SONY_LEADIN   46      //This is 3ms
#define SONY_ONE   28      //'1' bit
#define SONY_ZERO   18      //'0' bit
#define SONY_REPEAT   0      //Doesn't have one
//PAN
#define WONKY_LEADIN   80      //This is 5.5 ms
#define WONKY_ONE   27      //'1' bit
#define WONKY_ZERO   13      //'0' bit
#define WONKY_REPEAT   0      //Doesn't have one

/*
 * GLOBAL VARIABLES
 */
enum {                  //I do this to use symbolic names, no magic numbers!
   SONY = 0,
   NEC,
   PAN,
   RC5
};
#define MAXBIT 50            //Anywhere from 12 to 32 bits
unsigned char bits[MAXBIT];      //Bit storage for ISR
unsigned char rBits=0;         //read pointer in circular buffer
unsigned char startOne=0;      //flag denoting the start of a command string
unsigned char nCmd[4]={0,0,0,0};//currently building command
unsigned char nBit=0;         //command bit pointer
unsigned char whichOne = PAN;   //Flag to show which timeout to use
unsigned char wonk[6];         //48 bits in this one
unsigned char TEST = 0;         //If set to one, just spits out timings

/*
 * save_w and save_status are at 7f through 7a which are available in ALL banks
 * all of these variables can be called "volatile" in that they are modified
 * outside of the normal program's scope.
 */
unsigned char save_w;         //These next 3 bytes are save on interrupt
#locate save_w=0x7f
unsigned char save_status;
#locate save_status=0x7e
unsigned char save_FSR;
#locate save_FSR=0x7d
unsigned char wBits=0;         //To make access to these variables fast
#locate wBits = 0x7c         //Keep them in common memory for ISR use
unsigned char t1h;
#locate t1h = 0x7b
unsigned char t1l;
#locate t1l = 0x7a

/*
 * Give me direct access to several SFR's that CCS doesn't handle the way I want to.
 */
#byte TXREG = 0xFAD
#byte T1CON = 0xFCD
#byte INTCON = 0xFF2
#byte FSR = 0xFE1
#byte status= 0xFD8
#byte TMR1L = 0xFCE
#byte TMR1H = 0xFCF
#byte PIR1 = 0xF9E
#byte TMR0 = 0xFCC

void init(void)
//Initialize just about everything.
{
   /*
      RA7-RA4: N/C    = output
      RA3: /MCLR      = input
      RA2: IR in      = input (interrupt pin INT)
      RA1: PGC       = output
      RA0: PGD       = output
   */
   set_tris_a(0b00001100);
   /*
      RC7-RC6: N/C   = output
      RC5: RxD      = input
      RC4: TxD      = output
      RC3-RC1: N/C   = output
      RC0: LED      = output
   */
   set_tris_c(0b00100000);
   
   //Turn off comparator
  setup_comparator(NC_NC_NC_NC);
   
   //We will be doing interrupts
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_128);      //16ms timer
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);         //Gives 131ms max timeout
   ext_int_edge(H_TO_L);                        //IR IRQ on falling edge
   PIR1 = 0;
   bit_clear(INTCON,1);
   bit_clear(INTCON,2);
   
   if (whichOne == NEC)                        //Set our timeout by remote
   {
      t1h = NEC_TMR1_HIGH;
      t1l = NEC_TMR1_LOW;
   }
   else if (whichOne == SONY)
   {
      t1h = SONY_TMR1_HIGH;
      t1l = SONY_TMR1_LOW;
   }
   else
   {
      t1h = NEC_TMR1_HIGH;
      t1l = NEC_TMR1_LOW;
   }     
   enable_interrupts(INT_TIMER1);                  //Select these interrupts
   enable_interrupts(INT_EXT);
   //enable_interrupts(GLOBAL);                  //Start this later
}

#int_global
void isr(void)
/*
 * Lets handle all ISR save/recovery functions, the default isn't lean enough for an
 * ISR that is highly time critical.
 */
{
   #asm
      //store current state of processor
      MOVWF save_w
      SWAPF status,W
      MOVWF save_status
      SWAPF FSR,W
      MOVWF save_FSR
      BCF   status,5                              //Set to page 0 for SFR's
      BCF   status,6
   #endasm
   //We only have two interrupts, so if it isn't this one, it's the other.
   if (bit_test(PIR1,0))                        //Timer1 overflow IRQ
   {
      bits[wBits++] = 255;                     //timed out
      bit_clear(PIR1,0);                        //Clear TMR1 interrupt flag
      bit_clear(T1CON,0);                        //Turn TMR1 off until...
   }
   if (bit_test(INTCON,1))                        //CCP1 capture IRQ
   {
         bits[wBits++] = TMR0;                     //save the pulse time
         bit_clear(INTCON,1);                     //clear external interrupt flag
         TMR1H = t1h;                           //reset the timeout
         TMR1L = t1l;
         bit_set(T1CON,0);                        //turn TMR1 back on so we can time out
         TMR0 = 0;                              //clear out the timer
   }
      if (wBits == MAXBIT)                        //rollover the bit buffer
         wBits=0;

      #asm
      // restore processor and return from interrupt
      SWAPF save_FSR,W
      MOVWF FSR
      SWAPF save_status,W
      MOVWF status
      SWAPF save_w,F
      SWAPF save_w,W
      #endasm 
}                               

unsigned char DecodeBit(unsigned char time)
/*
 * This will determine if the bit is a 0 or a 1, by whichever standard is in being used.
 * Returns a 1 if a logic 1 bit, 0 otherwise.
 */
{
   unsigned char ret = 0;
   unsigned char val = 0;
   
   val = time;                     //Can be used to "fuzzy" the time for rounding
   
   if (whichOne == NEC)
   {
      if ((val <= NEC_ONE+FUZZY) && (val >= NEC_ONE-FUZZY))
         ret = 1;
      else if ((val <= NEC_ZERO+FUZZY) && (val >= NEC_ZERO-FUZZY))
         ret = 0;
   }
   else if (whichOne == SONY)
   {
      if ((val <= SONY_ONE+FUZZY) && (val >= SONY_ONE-FUZZY))
         ret = 1;
      else if ((val <= SONY_ZERO+FUZZY) && (val >= SONY_ZERO-FUZZY))
         ret = 0;
   }
   else if (whichOne == PAN)
   {
      if ((val <= WONKY_ONE+FUZZY) && (val >= WONKY_ONE-FUZZY))
         ret = 1;
      else if ((val <= WONKY_ZERO+FUZZY) && (val >= WONKY_ZERO-FUZZY))
         ret = 0;
   }
   return ret;
}

unsigned char DecodeCode(void)
/*
 * Works with the timing values to create a device/command pair from the data.
 */
{
   unsigned char tmp;
   unsigned char bVal;
   unsigned char res = 0;
   
   if (rBits != wBits)                        //We have a new bit in
   {
      tmp = bits[rBits++];                  //Get the bit to look at
      if (rBits == MAXBIT)
         rBits = 0;
     
      //This is a cute item, if you press and hold a NEC remote button it will issue
      //lots of "Repeat Code" pulses.  We can then detect that we have an NEC.
//      if (tmp <= NEC_REPEAT+FUZZY && tmp >= NEC_REPEAT-FUZZY)
//      {
//         whichOne = NEC;                     //We can detect the repeat code
//         t1h = NEC_TMR1_HIGH;
//         t1l = NEC_TMR1_LOW;
//      }
      //NEC IR codes
      if (whichOne == NEC)
      {
         if (tmp > NEC_LEADIN+10)            //timeout
         {
            startOne = 0;
            res = 0;
         }
         else if (nBit == 31 && startOne == 1)   //all bits are in
         {
            startOne = 0;
            res = 1;
         }
         else if ((tmp <= NEC_LEADIN+FUZZY) && (tmp >= NEC_LEADIN-FUZZY))   
         //We have a new command coming in.
         {
            nBit = 0;                     //first bit in first byte
            startOne = 1;                  //we've started one
            nCmd[0]=0;nCmd[1]=0;nCmd[2]=0;nCmd[3]=0;
            res = 0;                     //we're done here
         }
         else
         {
            bVal = DecodeBit(tmp);
            if (bVal == 1)
               bit_set(nCmd[nBit/8],(nBit & 0x07));      //Set the bit needed
            else
               bit_clear(nCmd[nBit/8],(nBit & 0x07));
            nBit++;
         }
      }
      //SONY IR codes.  This works with 12 and 16 bit SONY IR, not 20 bit
      else if (whichOne == SONY)
      {
         if (tmp > SONY_LEADIN+10)            //all bits are in, up to 16 bits
         {
            if (startOne == 1)
            {
               startOne = 0;
               res = 1;
            }
            else
            {
               startOne = 0;
               res = 0;
            }
         }
         else if ((tmp <= SONY_LEADIN+FUZZY) && (tmp >= SONY_LEADIN-FUZZY))
         {
            nBit = 0;
            startOne = 1;
            nCmd[0]=0;nCmd[1]=0;nCmd[2]=0;nCmd[3]=0;
            res = 0;                     // ready to start another one
         }
         else
         {
            bVal = DecodeBit(tmp);
            if (nBit < 7)                     //This is the command code
            {
               if (bVal == 1)
                  bit_set(nCmd[2],nBit++);
               else
                  bit_clear(nCmd[2],nBit++);
            }
            else                           
            {
               if (bVal == 1)
                  bit_set(nCmd[0],(nBit-7));      //This is the device code
               else
                  bit_clear(nCmd[0],(nBit-7));
               nBit++;
            }
         }
      }
      //PAN IR codes
      if (whichOne == PAN)
      {
         if (tmp > WONKY_LEADIN+10)            //timeout
         {
            startOne = 0;
            res = 0;
         }
         else if (nBit == 47 && startOne == 1)   //all bits are in
         {
            startOne = 0;
            res = 1;
         }
         else if ((tmp <= WONKY_LEADIN+FUZZY) && (tmp >= WONKY_LEADIN-FUZZY))   
         //We have a new command coming in.
         {
            nBit = 0;                     //first bit in first byte
            startOne = 1;                  //we've started one
            wonk[0]=0;wonk[1]=0;wonk[2]=0;wonk[3]=0;
            wonk[4]=0;wonk[5]=0;
            res = 0;                     //we're done here
         }
         else
         {
            bVal = DecodeBit(tmp);
            if (bVal == 1)
               bit_set(wonk[nBit/8],(nBit & 0x07));      //Set the bit needed
            else
               bit_clear(wonk[nBit/8],(nBit & 0x07));
            nBit++;
         }
      }
   }
   return res;
}

void main(void)
{
   char key;
   //setup_oscillator(OSC_8MHZ);
   init();
   printf("DLC IR Decoder\n\r");

   enable_interrupts(GLOBAL);               //Start listening to IR signals.

   while(1)
   {
      if (kbhit())
      {
         key = getch();
         switch (key)
         {
            case 'T':
            case 't':
               TEST = 1;
               printf("Test Mode On\n\r");
               break;
            case 'D':
            case 'd':
               TEST = 0;
               printf("Test Mode Off\n\r");
               break;
            case 'P':
            case 'p':
               whichOne = PAN;
               printf("Panasonic mode\n\r");
               break;
            case 'S':
            case 's':
               whichOne = SONY;
               printf("SONY mode\n\r");
               break;
            case 'N':
            case'n':
               whichOne = NEC;
               printf("NEC mode\n\r");
               break;
         }
      }
      if (TEST != 1)
      {
         if (DecodeCode() == 1)
         {
            if (whichOne == SONY)
            {
               printf("SONY Device = %u Command = %u\n\r",(int)nCmd[0],(int)nCmd[2]);
            }
            else if (whichOne == PAN)
            {
               printf("PANASONIC %X %X %X %X %X %X\n\r",wonk[0],wonk[1],wonk[2],wonk[3],wonk[4],wonk[5]);
            }
            else
            {
               printf("NEC Device = %u Command = %u\n\r",(int)nCmd[0],(int)nCmd[2]);
            }
         }
      }
      if (rBits != wBits)
      {
         if (TEST == 1)
         {
            printf("%u\n\r",bits[rBits++]);
            if (rBits == MAXBIT)
               rBits = 0;
         }
         output_toggle(PIN_C0);            // This flashes when we see IR signals
      }
   }
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion 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