ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • INTERRUPT를 이용한 NEC 리모콘 수신제어
    _[HARDWARE]/기타 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

               }

    }

     

     

Designed by Tistory.