venthan
Junior Member level 3
Hello,
I am trying to interface IR remote control(NEC Protocol) using 16f887 pic microcontroller. Coding objective is to read the IR signal and has to be display the equalant HEX value of command and address. While testing in hardware IR signal is not detecting but got random output. Tried a lot to solve the issue but failed. Here I have attached the coding kindly help me out. Thanks in advance.
I am trying to interface IR remote control(NEC Protocol) using 16f887 pic microcontroller. Coding objective is to read the IR signal and has to be display the equalant HEX value of command and address. While testing in hardware IR signal is not detecting but got random output. Tried a lot to solve the issue but failed. Here I have attached the coding kindly help me out. Thanks in advance.
Code C - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 sbit LCD_RS at Rd1_bit; sbit LCD_EN at Rd2_bit; sbit LCD_D4 at Rd4_bit; sbit LCD_D5 at Rd5_bit; sbit LCD_D6 at Rd6_bit; sbit LCD_D7 at Rd7_bit; sbit LCD_RS_Direction at TRISd1_bit; sbit LCD_EN_Direction at TRISd2_bit; sbit LCD_D4_Direction at TRISd4_bit; sbit LCD_D5_Direction at TRISd5_bit; sbit LCD_D6_Direction at TRISd6_bit; sbit LCD_D7_Direction at TRISd7_bit; // End LCD module connections bit nec_ok; char text[5]; unsigned short nec_state, command, inv_command, i; unsigned int address, timer_value; unsigned long nec_code; void Interrupt() { if (RBIF_bit && RBIE_bit){ // PORTB change ISR RBIF_bit = 0; if(nec_state != 0){ timer_value = (TMR1H << 8) + TMR1L; // Store Timer1 value TMR1H = 0; // Reset Timer1 TMR1L = 0; } switch(nec_state){ case 0 : // Start receiving IR data (we're at the beginning of 9ms pulse) TMR1H = 0; // Reset Timer1 TMR1L = 0; TMR1ON_bit = 1; // Enable Timer1 nec_state = 1; // Next state: end of 9ms pulse (start of 4.5ms space) i = 0; break; case 1 : // End of 9ms pulse if((timer_value > 9500) || (timer_value < 8500)){ // Invalid interval ==> stop decoding and reset nec_state = 0; // Reset decoding process TMR1ON_bit = 0; // Disable Timer1 } else nec_state = 2; // Next state: end of 4.5ms space (start of 562µs pulse) break; case 2 : // End of 4.5ms space if((timer_value > 5000) || (timer_value < 4000)){ nec_state = 0; // Reset decoding process TMR1ON_bit = 0; // Disable Timer1 } else nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space) return; case 3 : // End of 562µs pulse if((timer_value > 700) || (timer_value < 400)){ // Invalid interval ==> stop decoding and reset TMR1ON_bit = 0; // Disable Timer1 nec_state = 0; // Reset decoding process } else nec_state = 4; // Next state: end of 562µs or 1687µs space return; case 4 : // End of 562µs or 1687µs space if((timer_value > 1800) || (timer_value < 400)){ // Time interval invalid ==> stop decoding TMR1ON_bit = 0; // Disable Timer1 nec_state = 0; // Reset decoding process return; } if( timer_value > 1000) // If space width > 1ms (short space) nec_code = 1 << (31 - i); // Write 1 to bit (31 - i) else // If space width < 1ms (long space) nec_code = 0 << (31 - i); // Write 0 to bit (31 - i) i++; if(i > 31){ // If all bits are received nec_ok = 1; // Decoding process OK RBIE_bit = 0; // Disable PORTB change interrupt return; } nec_state = 3; // Next state: end of 562µs pulse (start of 562µs or 1687µs space) } } if (TMR1IF_bit){ // Timer1 ISR TMR1IF_bit = 0; // Clear Timer1 overflow flag bit nec_state = 0; // Reset decoding process TMR1ON_bit = 0; // Disable Timer1 } } void main() { OSCCON = 0X70; trisd = 0x00; trisb0_bit = 1; ansel = 0x00; nec_ok = 0; nec_state = 0; ANSELH = 0; // Configure all PORTB pins as digital Lcd_Init(); // Initialize LCD module Lcd_Cmd(_LCD_CURSOR_OFF); // cursor off Lcd_Cmd(_LCD_CLEAR); // clear LCD TMR1IF_bit = 0; // Clear Timer1 overflow interrupt flag bit TMR1IE_bit = 1; // Enable Timer1 overflow interrupt T1CON = 0x10; // Set Timer1 clock source to internal with 1:2 prescaler (Timer1 clock = 1MHz) INTCON = 0x90; INTF_bit = 0; INTE_bit = 1; IOCB0_bit = 1; OPTION_REG = 0XC0; Lcd_out(1,5,"welcome"); Lcd_out(2,2, "dear"); delay_ms(1000); Lcd_cmd(_lcd_clear); Lcd_Out(1, 1, "Address:0x0000"); Lcd_Out(2, 1, "Com:0x00 In:0x00"); delay_ms(1000); while(1) { while(nec_ok) // Wait until NEC code receiver nec_ok = 0; // Reset decoding process nec_state = 0; TMR1ON_bit = 0; // Disable Timer1 address = nec_code >> 16; command = nec_code >> 8; inv_command = ~command ; IntToHex(address, text); // Save address in string text with hex format Lcd_Out(1, 11, text); // Display address ByteToHex(command, text); // Save command in string text with hex format Lcd_Out(2, 7, text); // Display command ByteToHex(inv_command, text); // Save inverted command in string text with hex format Lcd_Out(2, 15, text); // Display inverted command RBIE_bit = 1; // Enable PORTB change interrupt } }