'PIC'에 해당되는 글 1건

  1. 2009.09.26 INTERRUPT를 이용한 NEC 리모콘 수신제어
2009. 9. 26. 15:27

/************************************************************************/

/*        Project  :

/*        CPU     : PIC16F676

/*        Crystal  : 20MHz

/*        Compiler: HI-TECH

/*        2008. 10. xx

/*

/*        written by nooriry

/*                                                                                                      

/*************************************************************************/

 

#include          <pic.h>

 

__CONFIG       ( MCLRDIS & PWRTDIS & WDTDIS & HS );

 

unsigned char Custom_code_upper, Custom_code_lower;

unsigned char Data_code_upper, Data_code_lower;

unsigned char Code;

unsigned char Power_flag;

unsigned char signal_in;

unsigned char ratio;

 

#define IR_in               RA2      // remocon input

#define Pw_bt             RA3      // 프론트의 버튼입력

#define LED                RC2     // for test

#define Debug             RC3     // for test

#define Pw_1000CT      RC5     // main B/D 전원 제어

#define ON                 1

#define OFF                0

#define Nec_code        1

#define NG_code         0

 

void delay_time( unsigned int del )

{

           unsigned int i;

           for( i=0; i < del; i++);

}

 

unsigned char Check_header( void )

{

           while( ( IR_in == 0 ) && ( ratio < 107 ) );         

           // HIGH가 되거나 11ms 이하만 대기, high 까지의 TMR0를 가지고 아래로 이동

                    

           if( ( ratio > 78 ) && ( ratio        < 98 ) )          

           // 9ms LOW NEC Signal start를 확인 (8ms~10ms)

           {

                     ratio = 0;

                               

                     while( ( IR_in == 1 ) && ( ratio < 59 ) );

                     // LOW가 되거나 6ms 이하만 대기

                                                               

                     if( ( ratio > 0 ) && ( ratio < 54 ) )        

                     // 4.5ms HIGH NEC Signal을 확인 (3.5ms~5.5ms)

                     {

                                ratio = 0;

                                return Nec_code;        

                                // 9ms LOW NEC format임을 확인

                     }

                     else

                     {

                                ratio = 0;

                                return NG_code;

                     }

           }

 

           else

           {

                     ratio = 0;

                     return NG_code;

           }

}

 

void Code_record( void )

{

           unsigned char code_bit, code_position;

          

           while( ( IR_in == 0 ) && ( ratio < 29 ) );

           // HIGH가 시작 되거나 3ms 이하만 대기

          

           ratio = 0;         // timer reset

          

           for( code_position=0; code_position<4; code_position++ )

           // 여기부터 high 구간만 계산한다.

           {        

                     for( code_bit=0; code_bit<8; code_bit++ )        // 8bit LSB

                     {

                                while( ( IR_in == 1 ) && ( ratio < 29 ) );

                                // low가 시작 될 때 까지 대기

                                                                                    

                                if( ( ratio >= 4 ) && ( ratio <= 6 ) )      

                                // target is 0.565ms (0.45 ~ 0.65ms)

                                {

                                          Code <<= 1;

                                          Code &= 0b11111110;

                                }

                                else if( ( ratio >= 15 ) && ( ratio <= 17 ) )       

                                // target is 1.68ms (1.55 ~1.75ms)

                                {

                                          Code <<= 1;

                                          Code |= 0b00000001;

                                }

 

                                while( ( IR_in == 0 ) && ( ratio < 29 ) );

                                // HIGH가 시작 되거나 3ms 이하만 대기

          

                                ratio = 0;         // timer reset

                     }

 

                     switch( code_position )

                     {

                                case 0: Custom_code_upper = Code;

                                          break;

                                case 1: Custom_code_lower = Code;

                                          break;

                                case 2: Data_code_upper = Code;

                                          break;

                                case 3: Data_code_lower = Code;

                                          break;

                     }        

           }

          

           delay_time(10);

 

}

 

void Pwr_ctrl ( void )

{        

           if( ( Custom_code_upper== 0x10 ) && ( Custom_code_lower== 0xEF ) &&

                     ( Data_code_upper== 0x08 ) && (Data_code_lower== 0xF7 ) )

           {

                     if( Power_flag == 0 )

                     {

                                Pw_1000CT= ON;

                                Power_flag = 1;

                     }

                     else if( Power_flag == 1)

                     {

                                Pw_1000CT= OFF;

                                Power_flag = 0;

                     }

           }

}

 

void System_initialize( void )

{

           ANSEL = 0b00000000;  // analog pin -> digital pin

          

 

           //OPTION = 0b00000111;

           // Global PORTA pull up enable, falling edge int, prescaler(1:256)

           OPTION = 0b00000000;

           //Global PORTA pull up enable, falling edge int, prescaler(1:8)

           // prescaler : Fosc/4 * 2 = 0.4us

           //               : 0.4us * 256 = 0.1024ms (1 ratio)

 

 

           INTCON = 0b00000000;

           // Disable global int, RA2/INT and clear TMR0 flag, RA2/INT flag

 

           // Port A

           TRISA2 = 1;     // RA2 is input

           //TRISA3 = 1;   // RA3 is input

           WPUA = 0b11111111;   // enable pull up

 

           // Port C

           TRISC2 = 0;     // RC2 is output

           TRISC3 = 0;     // RC3 is output

           TRISC5 = 0;     // RC5 is output

}

 

void main(void)

{

           System_initialize();

 

           Power_flag = 0;

 

           signal_in = 0;

 

           Pw_1000CT = OFF;      // B/D initial status

 

           INTE = 1;                    // enable RA2/INT int

           GIE = 1;                                // enable global int

          

           T0IE = 1;                    // enable TMR0 overflow interrupt

          

           while(1)

           {

                     if(signal_in)

                     {

                                ratio = 0;

                                                    

                                if( Check_header() == Nec_code )

                                {

                                          Code_record();

                               

                                          Pwr_ctrl();

                               

                                          delay_time( 5000 );

 

                                          Code = 0x00;

                               

                                          Custom_code_upper = 0x00;

                               

                                          Custom_code_lower = 0x00;

                               

                                          Data_code_upper = 0x00;

                               

                                          Data_code_lower = 0x00;

                                }

                                signal_in = 0;

                     }

           }

}

 

void interrupt isr_event(void)

{

           if(T0IF)

           {

                     ratio++;

                     T0IF = 0;

           }

 

          

           if(INTF)

           {

                     signal_in = 1;

                     INTF = 0;         // must be cleared before re-enabling

           }

}

 

 

Posted by nooriry