![]() | ![]() | ![]() |
| | |||||||
| Micro Controllers Discuss all aspects of micro controllers - building them, coding them, etc. All controllers are welcome - PIC, BASIC, Z8 Encore!, etc. |
| | LinkBack | Thread Tools | Display Modes |
| | (permalink) |
| Hi everybody, I am working on a project for controlling some devices with a remote controller which use NEC protocol. I have written RX codes in CCS using the timers. I have tried to catch fall and rise points to generate two data column and a checksum. After I setup and execute the timer, I wait for signal go to low with while(IR_PIN). But pic doesn't response until this line. It always stays in eternal loop in spite of it's logic value becomes zero. I confused up. | |
| |
| | (permalink) |
| Have you turned off the comparators CMCON=7;? Is the pin set to input? Is IR_PIN defined as a single bit? A bit more information and some code would be useful. Mike. | |
| |
| | (permalink) |
| Thank you Mike. Yes I turned the comparators off. Here is my code; Code: #include <16f628a.h>
#fuses NOWDT, INTRC_IO, PUT, NOPROTECT, MCLR
#use delay (clock=4000000) //4 MHZ
#byte CMCON=0x07;
#define IR_PIN PIN_B0
unsigned char bitcount;
int32 ir_tempbyte_hi;
int16 ir_tempbyte_lo;
int16 headp,heads,rise,fall;
void ir_read(void);
void ir_get_rise(void);
void ir_get_fall(void);
void ir_build_bytes(void);
#int_ext
void ext_int ()
{
ir_read();
}
void ir_read(void)
{
ir_tempbyte_hi=0;
ir_tempbyte_lo=0;
while(IR_PIN); // //Wait for minimal pre which stays low
ir_get_rise(); // Get headp & heads to see what protocol it is
headp=rise;
ir_get_fall();
heads=fall;
if ((headp>8800)&&(headp<9090)&&(heads>4200)&&(heads<4570)) // We got NEC Start Sequence
{
output_high(PIN_A2);
ir_build_bytes(); // Now trying to read data bits
}
else
{
output_high(PIN_A2);
}
}
void ir_get_rise(void)
{
output_high(PIN_A7);
setup_counters(RTCC_INTERNAL,RTCC_DIV_1); // Get high
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
set_timer1(0);
while(!IR_PIN); // Wait for signal to go high
rise = get_timer1();
delay_ms(1000);
output_low(PIN_A7);
}
void ir_get_fall(void)
{
output_high(PIN_A6);
setup_counters(RTCC_INTERNAL,RTCC_DIV_1); // Get low
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
set_timer1(0);
while(IR_PIN); // Wait for signal to go low
fall = get_timer1();
delay_ms(1000);
output_low(PIN_A6);
}
void ir_build_bytes(void)
{
for (bitcount=0;bitcount!=32;bitcount++)
{
ir_get_rise();
ir_get_fall();
if ((rise>450)&&(rise<650)&&(fall>1400)&&(fall<1655))
{
ir_tempbyte_hi|=1; // bit=1
}
else if ((rise>450)&&(rise<650)&&(fall>390)&&(fall<600)){;} // bit=0
else return; // Byte Check Fault
}
if (bitcount<31){ir_tempbyte_hi<<=1;} // Don't shift last bit
if (bitcount==32){output_high(PIN_A2);} // reception is valid
}
void main ()
{
setup_CCP1(CCP_OFF); // CCP1 unit outbound
ext_int_edge(H_TO_L); // INT_EXT is High to Low
setup_timer_0(t1_disabled);
setup_timer_1(t2_disabled);
enable_interrupts(INT_EXT); // INT_EXT interrupt inbound
enable_interrupts(GLOBAL); // All interrupts inbound
while(1); //Stand by
} | |
| |
| | (permalink) |
| I'm afraid I'm not familiar with the compiler you are using. I assume it is the CCS compiler as it appears to clear the interrupt flags for you. One thing I notice from your code is your ISR calls ir_read which calls ir_get_rise which has a 1 second delay in it! If it helps, here is some code I wrote in C18 which reads a sony code Code: #define IR_in PORTAbits.RA6
#define IR_tris TRISAbits.TRISA6
unsigned char GetPulse(void){
unsigned char count;
count=0;
IR_tris=1;
while(IR_in==1);
while(IR_in==0){
count++;
Delay100TCYx(1); //50uS assumes 8MHz
}
return count;
}
void GetIR(char *cmd,char *dev){
char i;
*cmd=0;
*dev=0;
while(GetPulse()<40); //wait for start pulse
for(i=0;i<7;i++){
*cmd=*cmd>>1;
if(GetPulse()>18)
*cmd|=0x40;
}
for(i=0;i<5;i++){
*dev=*dev>>1;
if(GetPulse()>18)
*dev|=0x10;
}
} | |
| |
| | (permalink) |
| One thing I notice is that you haven't disabled Low Voltage Programming in your config, add NOLVP to your fuses statement. Also as Pommie points out, interrupts should be short and sweet. Perhaps a better method is to set a flag in the isr, then in your main check to see if the flag is set and if so, go to your subroutine from there. | |
| |
| | (permalink) |
| Thank you very much. | |
| |
| Bookmarks |
| Thread Tools | |
| Display Modes | |
| |
| | ||||
| Title | Starter | Forum | Replies | Latest |
| JDM and 16F628 | patroclus | Micro Controllers | 15 | 22nd November 2008 06:03 PM |
| 16f628 | OY2L | Micro Controllers | 16 | 9th July 2008 10:28 AM |
| 16F628 help | W8TZ | Micro Controllers | 4 | 18th September 2007 12:37 PM |
| 16F628 2-2-1 | AZdave | Micro Controllers | 0 | 24th December 2004 10:09 PM |
| 16F628 PWM | Fletcher | Micro Controllers | 7 | 6th September 2004 02:31 PM |