sarmad_101
Joined: 17 Jun 2010 Posts: 12
|
Need help about RC5 ? |
Posted: Mon Aug 30, 2010 1:16 am |
|
|
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
}
}
}
|
|
|