Advertisement
Electgpl

PIC - Receptor NEC

Sep 6th, 2017
150
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.45 KB | None | 0 0
  1. /* This RF receiver is based on NEC protocol
  2.    Internal oscillator used @ 8MHz
  3. */
  4.  
  5. #include <16F883.h>
  6. #fuses NOMCLR, NOBROWNOUT, NOLVP, INTRC_IO
  7. #use delay(clock = 8MHz)
  8. #use fast_io(C)
  9.  
  10. short code_ok = 0;
  11. unsigned int8 nec_state = 0, i;
  12. unsigned int32 rf_code;
  13. #INT_EXT                                         // External interrupt
  14. void ext_isr(void){
  15.   unsigned int16 time;
  16.   if(nec_state != 0){
  17.     time = get_timer1();                         // Store Timer1 value
  18.     set_timer1(0);                               // Reset Timer1
  19.   }
  20.   switch(nec_state){
  21.     case 0 :                                     // Start receiving IR data (we're at the beginning of 9ms pulse)
  22.       setup_timer_1( T1_INTERNAL | T1_DIV_BY_2 );   // Enable Timer1 module with internal clock source and prescaler = 2
  23.       set_timer1(0);                             // Reset Timer1 value
  24.       nec_state = 1;                             // Next state: end of 9ms pulse (start of 4.5ms space)
  25.       i = 0;
  26.       ext_int_edge( H_TO_L );                    // Toggle external interrupt edge
  27.       return;
  28.     case 1 :                                     // End of 9ms pulse
  29.       if((time > 9500) || (time < 8500)){        // Invalid interval ==> stop decoding and reset
  30.         nec_state = 0;                           // Reset decoding process
  31.         setup_timer_1(T1_DISABLED);              // Stop Timer1 module
  32.       }
  33.       else
  34.         nec_state = 2;                           // Next state: end of 4.5ms space (start of 560µs pulse)
  35.       ext_int_edge( L_TO_H );                    // Toggle external interrupt edge
  36.       return;
  37.     case 2 :                                     // End of 4.5ms space
  38.       if((time > 5000) || (time < 4000)){        // Invalid interval ==> stop decoding and reset
  39.         nec_state = 0;                           // Reset decoding process
  40.         setup_timer_1(T1_DISABLED);              // Stop Timer1 module
  41.         return;
  42.       }
  43.       nec_state = 3;                             // Next state: end of 560µs pulse (start of 560µs or 1680µs space)
  44.       ext_int_edge( H_TO_L );                    // Toggle external interrupt edge
  45.       return;
  46.     case 3 :                                     // End of 560µs pulse
  47.       if((time > 700) || (time < 400)){          // Invalid interval ==> stop decoding and reset
  48.         nec_state = 0;                           // Reset decoding process
  49.         setup_timer_1(T1_DISABLED);              // Disable Timer1 module
  50.       }
  51.       else
  52.         nec_state = 4;                           // Next state: end of 560µs or 1680µs space
  53.       ext_int_edge( L_TO_H );                    // Toggle external interrupt edge
  54.       return;
  55.     case 4 :                                     // End of 560µs or 1680µs space
  56.       if((time > 1800) || (time < 400)){         // Invalid interval ==> stop decoding and reset
  57.         nec_state = 0;                           // Reset decoding process
  58.         setup_timer_1(T1_DISABLED);              // Disable Timer1 module
  59.         return;
  60.       }
  61.       if( time > 1000)                           // If space width > 1ms (short space)
  62.         bit_set(rf_code, (31 - i));              // Write 1 to bit (31 - i)
  63.       else                                       // If space width < 1ms (long space)
  64.         bit_clear(rf_code, (31 - i));            // Write 0 to bit (31 - i)
  65.       i++;
  66.       if(i > 31){                                // If all bits are received
  67.         code_ok = 1;                             // Decoding process OK
  68.         disable_interrupts(INT_EXT);             // Disable the external interrupt
  69.       }
  70.       nec_state = 3;                             // Next state: end of 560µs pulse (start of 560µs or 1680µs space)
  71.       ext_int_edge( H_TO_L );                    // Toggle external interrupt edge
  72.   }
  73. }
  74. #INT_TIMER1                                      // Timer1 interrupt (used for time out)
  75. void timer1_isr(void){
  76.   nec_state = 0;                                 // Reset decoding process
  77.   ext_int_edge( L_TO_H );                        // External interrupt edge from high to low
  78.   setup_timer_1(T1_DISABLED);                    // Disable Timer1 module
  79.   clear_interrupt(INT_TIMER1);                   // Clear Timer1 interrupt flag bit
  80. }
  81. void main() {
  82.   setup_oscillator(OSC_8MHZ);                    // Set internal oscillator to 8MHz
  83.   output_c(0);                                   // PORTD initial state
  84.   set_tris_c(0);                                 // Configure PORTD pins as outputs
  85.   enable_interrupts(GLOBAL);                     // Enable global interrupts
  86.   enable_interrupts(INT_EXT_L2H);                // Enable external interrupt
  87.   clear_interrupt(INT_TIMER1);                   // Clear Timer1 interrupt flag bit
  88.   enable_interrupts(INT_TIMER1);                 // Enable Timer1 interrupt
  89.   while(TRUE){
  90.     if(code_ok){                                 // If the mcu successfully receives NEC protocol message
  91.       code_ok = 0;                               // Reset decoding process
  92.       nec_state = 0;
  93.       setup_timer_1(T1_DISABLED);                // Disable Timer1 module
  94.       if(rf_code == 0x00FF00FF)
  95.         output_toggle(PIN_C0);
  96.       if(rf_code == 0x00FF807F)
  97.         output_toggle(PIN_C1);
  98.       if(rf_code == 0x00FF40BF)
  99.         output_toggle(PIN_C2);
  100.       if(rf_code == 0x00FF20DF)
  101.         output_toggle(PIN_C3);
  102.       enable_interrupts(INT_EXT_L2H);            // Enable external interrupt
  103.     }
  104.   }
  105. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement