ir remote with pic16f877a

how to receive ir remote signal with pic16f877a using hi tech c compiler with example code?

  • adding library

    Votes: 0 0.0%
  • chage compiler

    Votes: 0 0.0%

  • Total voters
    0

Thread Starter

nanotronnss

Joined Apr 16, 2018
5
hi ,
I need some clarification based on ir remote with pic16f877a topic. i am working on a project called remote control using pic16f877a microcontroller. I have three doubts and let me know.
1. how to receive ir remote signal with pic and i use hi tech c universal tool suite compiler with MPLAB IDE v8.63. if you gave an example code with this compiler that will be very helpful for my further move.
2.if there is any library for ir remote using pic if it so, can you send that library and how to install and work on it.
3.if i receive the ir signal with another controller like arduino uno and how i get that data from arduino uno board to pic16f877a.
which protocols are used between pic and arduino that also i want to know.
finally from the above three which is best or suitable at the end of the product.
 

LesJones

Joined Jan 8, 2017
4,511
There is no problem receiving IR remote control signals using a PIC16F877A I use one as a camera switcher (8 channels.) which is controlled using a TV remote. The remote I used uses the Philips RC-5 IR protocol. I used code I found on this website to read the IR codes but this information is no longer on the website. You may be able to contact the site owner to get the information. The code on the website and my camera switcher are written in assembler so if you want to write them in "C" you would have to re write the code. (I find "C" very difficult to use compared with assembler.) Let me know if you would like a copy of the code and schematic of my camera switcher.

Les.
 

LesJones

Joined Jan 8, 2017
4,511
I don't know what you don't understand. Here is the code for the camera switcher.

Code:
;*****************************************************************************   
;
;  IR Controlled video camera switcing unit
;   
;  Version:  1.0 23/11/08    Basic version
;
;  Version   2.0 28/11/08  Add manual step forward and step beck function.   
;
;  Version   3.0 28/11/08  Being modified to stop auto scan after about 10 minutes to sve waring out multiplexer relays
;
;  Version    4.0 05/12/08  Being modified to save setup values to EEPROM
;
;  Version  5.0 05/10/12  Delay in toggle IR light routine increased to cope with a remote control that sends code multiple times.
;
;*****************************************************************************   

  list p=16f877, st=OFF, x=OFF, n=0
  errorlevel -302
  errorlevel -306

  #include <p16f877A.inc>

;   Use 4 Mhz xtal

   __CONFIG   _XT_OSC & _WDT_OFF & _PWRTE_ON & _BODEN_ON & _LVP_OFF & _CPD_OFF & _CP_OFF

;  **************************  Definitions *******************************
;
;   
;
Camera_Select    EQU   PORTB
IR_Ilumination   EQU   PORTD       ;(Needs to be saved to EEPROM)

#DEFINE     IR_In     PORTA,4

#DEFINE     Auto_on     Flags,0     ;Set for auto scan
;  #DEFINE     New_command   Flags,1     ;Set by received IR character, Cleared when action taken

;  ************************ Constants  *********************************

TIMER_UPDATE  EQU  -d'50'+d'3'  ;Timer update value (2 dead cycles) (-47 decimal) (D1 Hex)

HALF_TIME  EQU  d'900'/d'50'  ;(900/50)Number of timer counts per half bit  (18 decimal)
             ; 18 * 50 uS = 900 uS



;TMR1_Preload   EQU   0x0BCD       ;Value required for 500 mS  (62500 decimal = 0xF424) ( -0xF424 = 0x0BDC)
TMR1_Preload   EQU   0x085EE       ;Value required for 250 mS  ( 31250 decimal = 0x7A12) ( -0x7A12 = 0x085EE)
Timeout_minutes   EQU   d'10'       ;Autoscan timeout value in minutes.

;  ******** RAM Locations ***********
;Bank 0
   CBLOCK   0x20   ;GPR' starts at 0x20
Temp01       ;Temporary storage
Acive_Scan     ;Bit set for channels selected for auto scan  (Needs to be saved to EEPROM)
Scan_delay     ;Stores a number that controls the scan speed (Time in 500 mS seconds value for 2 to 20seconds)
;                   (Needs to be saved to EEPROM)
Flags       ;Flags for various purposes
Camera_No     ;Counter for camera number
Count       ;Used to test if 8 bits ave been tested in "Active_Scan"

Bits       ;Number of bits required to be set to alow increment

Scan_state  ;Scan state pointer

Counter_L     ;Used fior timer to ignore a command until about 200 mS after previous one
Counter_H

Timeout_L     ;Used to stop autoscan after a preset time
Timeout_H     ;Used to stop autoscan after a preset time

TMR1_500mS_counter  ;Scan delay counter (Decremented every 500 mS)   


IR_STATE  ;IR receiver state machine
BIT_TIMER  ;Bit timer
IR_SHIFT:4       ;Only 2 used IR shift register
Data_L       ;Low byte of received data
Data_H       ;High byte of received data

;Locations for EEPROM routines
DATA_EE_DATA
DATA_EE_ADDR

   ENDC       ;Must end at 07F


;   ******* Flag bit definitions ********

;Flags

;   Bit 0     Set for Auto scan
;   Bit 1     Set when new command received  (Cleared when command has been acted upon.)
;   Bit 2   
;   Bit 3     Used as flag to indicate less than 200 mS since last command
;   Bit 4
;   Bit 5
;   Bit 6
;   Bit 7

;   ******* EEPROM LOCATION use *******
EEPROM0     EQU   0x00   ;Holds flag for valid EEPROM data
EEPROM1     EQU   0x01   ;Saves copy of Acive_Scan
EEPROM2     EQU   0x02   ;Saves copy of Scan_delay
EEPROM3     EQU   0x03   ;Saves copy of IR_Ilumination

;*****************************************************************************   
;
;  Function :  Reset vector
;  Hardware entry point to the code
;  This vector is also used for soft resets in the event of
;  abnormal events
;
;  Input:  None.
;
;  Output:  N/A
;
;*****************************************************************************   
   
  ORG  0

RESET   
   CALL initHardware
   CALL   Restore_Params   ;Read saved values from EEPROM (If valid data flag set in EEPROM)
   GOTO  Main


;*****************************************************************************   
;
;  Function :  Interrupt vector
;  Hardware entry point for interrupts
;  This vector handles all external and internal interrupts
;
;  Input:  None.
;
;  Output:  N/A
;
;*****************************************************************************   
   
  ORG  4       ;Should never get here.

   GOTO   Main     ;Interrupts not used.

;*****************************************************************************   


;*****************************************************************************   
;
;  Function :  initHardware  Subroutine
;  reconfigures the peripherals of the chip.
;  This ensure that, if ESD or bugs have caused the configuration
;  change, it is restored. This is called every hour.
;
;  Input:  None
;
;  Output:  None
;
;*****************************************************************************   
initHardware

     MOVLW  0x21  ;Clear memory
     MOVWF  FSR
     MOVLW  35  ; Clear a total of 36 RAM addresses
     MOVWF  0x20
_CLRMEM  CLRF  INDF  ;Clear this address
  INCF  FSR,F  ;Increment pointer
  DECFSZ  0x20,F  ; Decrement counter
  GOTO  _CLRMEM  ; Repeat until done

       clrf  STATUS  ; Select bank 0
       clrf  INTCON  ; No interrupts
       clrf  PCLATH  ; Code is in first bank

;   Configure I/O ports
     BSF  STATUS,RP0  ;Select bank 1 of register file
     MOVLW   0x06
     MOVLW  b'00010000'  ; Only PA4 is an input
  MOVWF  TRISA
     MOVWF   ADCON1       ; ALL DIGITAL
     MOVLW   0x00
     MOVWF   TRISB     ;All bits as outputs
     MOVWF   TRISC     ;All bits as outputs
     MOVWF   TRISD     ;All bits as outputs

;   Configure TIMER 0
     MOVLW  b'11011111'  ; Timer mode without pre-scaler, Internal clock (1 Mhz with 4 Mhz xtal)
     MOVWF  OPTION_REG   ;Prescaler assigned to WDT divide by 128

     BCF  STATUS,RP0  ;Select bank 0 of register file
;   Configure TIMER 1
     MOVLW   b'00110000'   ;Internal clock, 1:8 prescale, TMR1 off
     MOVWF   T1CON
     MOVLW   LOW TMR1_Preload
     MOVWF   TMR1L
     MOVLW   HIGH TMR1_Preload
     MOVWF   TMR1H
     BSF   T1CON,TMR1ON   ;Start timer

     MOVLW  IR_STATE_0  ;Init IR receiver state machine
     MOVWF  IR_STATE

     MOVLW  LOW Scan_state_0   ;Set initial Scan_state
     MOVWF   Scan_state

     CLRF   Camera_No
     CLRF   Camera_Select
     BSF   Camera_Select,0     ;Select camara 1   

     CLRF   IR_Ilumination
     CLRF   PORTC

     MOVLW   0x06       ;Gives 3 second scan time
     MOVWF   Scan_delay
     MOVWF   TMR1_500mS_counter

     MOVLW   0xFF       ;Set all inputs active
     MOVWF   Acive_Scan
     BSF   Auto_on       ;Set auto scan to on

     CLRF   Counter_L
     MOVLW   0x10     ;16 decimal 12.8 * 16 = 204.8 ms
     MOVWF   Counter_H     ;Reload counter

     CLRF   Timeout_L     ;Set Timeout low and high to length of Autoscan timeout
     MOVLW   Timeout_minutes
     MOVWF   Timeout_H

     RETURN

;*****************************************************************************   
;
;  Function :  Main
;  Main application loop
;
;  Input:  None.
;
;  Output:  N/A
;
;  The program should go round this main program loop every 50 uS
;
;*****************************************************************************   

   

Main  ;The program should go round this main program loop every 50 uS

;-----------------------------------------CALL THE IR RECEIVER STATE MACHINE--

  CALL  IR_MACHINE  ;Call the IR receiver state machine

;-----------------------------------------------------SCAN --


     BTFSC   Flags,3
     GOTO   Main_2
     DECFSZ   Counter_L,F     ;50uS * 2656 = 12.8 mS
     GOTO   Main_2
     DECFSZ   Counter_H,F
     GOTO   Main_2
;     MOVLW   0x10     ;16 decimal 12.8 * 16 = 204.8 ms
     MOVLW   0x30     ;48 decimal 12.8 * 48  = 614.4 ms  (Increased from 16 in version 04 - 05/10/12)

     MOVWF   Counter_H     ;Reload counter
     BSF   Flags,3

Main_2
     MOVLW   b'00000100'   ;For testing loop time
     XORWF   PORTC,F


     CALL   Scan_cam  ;Call the camera scan state machine
     CLRF   PCLATH


;-------------------------------------------------------SYNC MAIN WITH TIMER--

_SYNC  BTFSC  TMR0,7  ;Wait until bit 7 of TMR = 0
  GOTO  _SYNC  ; Not 0 yet!
  MOVLW  TIMER_UPDATE  ;Reload timer again  ( 0xD1 ) (Will time for 50 uS)
  ADDWF  TMR0,F



  GOTO  Main

;-----------------------------------------------------------------------------
;-----------------------------------------------------------------------------
;
; IR receiver state machine
;
;-----------------------------------------------------------------------------

IR_MACHINE   
     CLRF   PCLATH  
     MOVF  IR_STATE,W  ;Jump to present state
  MOVWF  PCL

;---------------------------------------STATE 0, WAIT FOR BEGIN OF START BIT--

IR_STATE_0  BTFSC  PORTA,4  ;Input still high?
  RETURN  ; Yes! Nothing to do

  MOVLW  HALF_TIME/2-1  ;Wait until we're in the center of the     (HALF_TIME 18 decimal, 12 Hex )
  MOVWF  BIT_TIMER  ; start pulse           (So 18/2 = 9 -1 = 8  )
  MOVLW  IR_STATE_1  ;Next stop is state 1
  MOVWF  IR_STATE
  RETURN

;---------------------------STATE 1, START BIT DETECTED, CHECK IF IT IS REAL--

IR_STATE_1  DECFSZ  BIT_TIMER,F  ; Wait until center of start pulse
  RETURN  ;Time's not up yet!

  BTFSC  PORTA,4  ;Is the input still low?
  GOTO  IR_ERROR_1  ; Nope! Exit with error

  MOVLW  HALF_TIME  ; Set interval to the center of the
  MOVWF  BIT_TIMER  ; first half of the next bit
  MOVLW  b'00001000'  ;Prepare the shift register
  MOVWF  IR_SHIFT
  CLRF  IR_SHIFT+1
  MOVLW  IR_STATE_2  ; Prepare for next stop
  MOVWF  IR_STATE
  RETURN

;-----------------------------------IR STATE 2, WAIT FOR FIRST HALF OF A BIT--
;
IR_STATE_2  DECFSZ  BIT_TIMER,F  ; Wait until center of first half of bit
  RETURN  ; Keep waiting!

  MOVLW  IR_STATE_3  ;Next state is 3 if input is high
  BTFSS  PORTA,4
  MOVLW  IR_STATE_4  ;Input is low, next state is 4
  MOVWF  IR_STATE
  MOVLW  HALF_TIME  ;Restart bit timer
  MOVWF  BIT_TIMER
  RETURN

;---------------IR STATE 3, FIRST HALF WAS HIGH NOW IT MUST BE LOW FOR A "1"--

IR_STATE_3  DECFSZ  BIT_TIMER,F  ;Wait until center of 2nd half of bit
  RETURN  ;Keep waiting!

  BTFSC  PORTA,4  ;Is input high now?
  GOTO  _ERROR  ; Nope! It's an error!

  BSF  STATUS,C  ;A 1 was received, shift it in result
  RLF  IR_SHIFT,F
  RLF  IR_SHIFT+1,F
  MOVLW  HALF_TIME  ; Restart bit timer
  MOVWF  BIT_TIMER
  MOVLW  IR_STATE_2  ;In case we need some more bits
  BTFSC  STATUS,C  ; We're done when Carry is 1
  MOVLW  IR_STATE_5  ;Carry is 1, received entire message
  MOVWF  IR_STATE
  RETURN

_ERROR  MOVLW  IR_ERROR_0  ;Wait until input gets high before
  MOVWF  IR_STATE  ;returning to state 0
  RETURN

;---------------IR STATE 4, FIRST HALF WAS LOW NOW IT MUST BE HIGH FOR A "0"--

IR_STATE_4  DECFSZ  BIT_TIMER,F  ;Wait until center of 2nd half of bit
  RETURN  ;Keep waiting!

  BTFSS  PORTA,4  ;Is input high now?
  GOTO  IR_ERROR_1  ; Nope! It's an error!

  BCF  STATUS,C  ;A 0 was received, shift it in result
  RLF  IR_SHIFT,F
  RLF  IR_SHIFT+1,F
  MOVLW  HALF_TIME  ; Restart bit timer
  MOVWF  BIT_TIMER
  MOVLW  IR_STATE_2  ; In case we need some more bits
  BTFSC  STATUS,C  ;We're done when Carry is 1
  MOVLW  IR_STATE_5  ;Carry is 1, received entire message
  MOVWF  IR_STATE
  RETURN

;--------------------------IR STATE 5, MESSAGE RECEIVED, START PROCESSING IT--

IR_STATE_5   

  MOVF  IR_SHIFT,W  ; Get IR command
  ANDLW  b'00111111'  ;The command is only 6 bits wide
  BTFSS  IR_SHIFT+1,4  ;Copy inverted extended bit to b6 of
  IORLW  b'01000000'  ; command

  RLF  IR_SHIFT,F  ;Shift the entire IR address in
  RLF  IR_SHIFT+1,F  ; 2nd byte of shift register
  RLF  IR_SHIFT,F
  RLF  IR_SHIFT+1,F
  MOVWF  IR_SHIFT  ;Save cleaned up hex IR command number
     MOVWF   Data_L

  MOVLW  IR_STATE_6  ;We've done enough in this state
  MOVWF  IR_STATE  ;Let's do the rest in state 6

;       Rceived code now in IR_SHIFT (Low byte) & IR_SHIFT+1 (High byte)
  RETURN

;------------------------------IR STATE 6, CONVERT HEX MESSAGE TO 7 SEGMENTS--

IR_STATE_6   


;   Test high byte for device code 0x05

     MOVF   IR_SHIFT+1,W
     ANDLW   0x1F     ;Mask for bits 0 4, Address is only 5 bits wide
     SUBLW   0x05
     BTFSS   STATUS,Z
     GOTO   IR_STATE_6a   ;Not device code 0x05
     CALL GT_Table     ;Take action on command
IR_STATE_6a
     CLRF   PCLATH
  MOVLW  IR_STATE_7  ; Done enough for now. Let's finish it
  MOVWF  IR_STATE  ;in the last state

     RETURN


;----------------------------------IR STATE 7, WAIT FOR INPUT TO RETURN HIGH--

IR_STATE_7
IR_ERROR_0  MOVLW  IR_STATE_0  ;Reset state machine only if input is
  BTFSC  PORTA,4  ; high
  MOVWF  IR_STATE
  RETURN

;-----------------------------------------------------------IR ERROR STATE 1--

IR_ERROR_1  MOVLW  IR_STATE_0  ;Return to IR state 0
  MOVWF  IR_STATE

  RETURN

;-----------------------  END OF IR STATE MACHINE ------------------------
;



;   ---------------------Scan state machine -------------------------

   ORG   0x100

Scan_cam
     MOVLW   0x01
     MOVWF   PCLATH

  MOVF  Scan_state,W  ;Jump to next state
  MOVWF  PCL


Scan_state_0

     BTFSS   PIR1,TMR1IF   ;Test TMR1 interrupt flag (This should set about every 250 mS)
     RETURN       ;No action required

     MOVLW   b'00001000'   ;For testing loop time
     XORWF   PORTC,F

     BCF   PIR1,TMR1IF   ;Clear TMR1 interrupt flag
     BCF   T1CON,TMR1ON   ;Stop timer
     MOVLW   LOW TMR1_Preload
     MOVWF   TMR1L
     MOVLW   HIGH TMR1_Preload
     MOVWF   TMR1H
     BSF   T1CON,TMR1ON   ;Start timer


     DECFSZ   Timeout_L,F     ;Timeout auto scan after about 10 minutes to save multipexer relays
     GOTO   Scan_state_0a
     MOVLW   d'240'       ;Value to give one minute
     MOVWF   Timeout_L     ;Reload counter

     DECFSZ   Timeout_H,F
     GOTO   Scan_state_0a
     BCF   Auto_on       ;Clear auto scan flag (It does not matter that timer still counts
             ;after Auto on is cleared.
Scan_state_0a

     DECFSZ   TMR1_500mS_counter,F
     RETURN        ;No action required
     MOVF   Scan_delay,W
     MOVWF   TMR1_500mS_counter    ;Reload counter value








     MOVLW   LOW Scan_state_1
     MOVWF   Scan_state

Scan_state_1
     BTFSS   Auto_on     ;Test if auto scan is on
     RETURN       ;No auto scan
     MOVLW   LOW Scan_state_2
     MOVWF   Scan_state
     RETURN

Scan_state_2
;Test if more than 1 camera is selected in auto scan

     MOVF   Acive_Scan,W
     MOVWF   Temp01

     MOVLW   0xFE     ; -2
     MOVWF   Bits

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   STATUS,C
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     BTFSC Bits,7     ;If set then "Bits" has not overflowed. IE less than 2 bits set
     GOTO   State_2b
     MOVLW   LOW Scan_state_3
     MOVWF   Scan_state
     RETURN

State_2b
     MOVLW   LOW Scan_state_0   
     MOVWF   Scan_state
     RETURN

Scan_state_3

     INCF   Camera_No,F     ;Only bits 0, 1, and 2 used  (Value of 7 will overflow into bit 3 on increment.)       
     MOVF   Camera_No,W
;     MOVWF   PORTD
     ANDLW   0x07       ;Mask for bits   0, 1, and 2
     ADDWF   PCL,F

     GOTO   Cam_1
     GOTO   Cam_2
     GOTO   Cam_3
     GOTO   Cam_4
     GOTO   Cam_5
     GOTO   Cam_6
     GOTO   Cam_7
     GOTO   Cam_8

Cam_1
     BTFSS   Acive_Scan,0   ;Is camera 1 to be displayed ?
     GOTO    Scan_state_3   ;Increment again
     MOVLW   b'00000001'   ;Select camera 1
     GOTO   Set_Cam



Cam_2
     BTFSS   Acive_Scan,1   ;Is camera 2 to be displayed ?
     GOTO    Scan_state_3   ;Increment again
     MOVLW   b'00000010'   ;Select camera 2
     GOTO   Set_Cam

Cam_3
     BTFSS   Acive_Scan,2   ;Is camera 3 to be displayed ?
     GOTO    Scan_state_3   ;Increment again
     MOVLW   b'00000100'   ;Select camera 3
     GOTO   Set_Cam

Cam_4
     BTFSS   Acive_Scan,3   ;Is camera 4 to be displayed ?
     GOTO    Scan_state_3   ;Increment again
     MOVLW   b'00001000'   ;Select camera 4
     GOTO   Set_Cam

Cam_5
     BTFSS   Acive_Scan,4   ;Is camera 5 to be displayed ?
     GOTO    Scan_state_3   ;Increment again
     MOVLW   b'00010000'   ;Select camera 5
     GOTO   Set_Cam

Cam_6
     BTFSS   Acive_Scan,5   ;Is camera 6 to be displayed ?
     GOTO    Scan_state_3   ;Increment again
     MOVLW   b'00100000'   ;Select camera 6
     GOTO   Set_Cam

Cam_7
     BTFSS   Acive_Scan,6   ;Is camera 7 to be displayed ?
     GOTO    Scan_state_3   ;Increment again
     MOVLW   b'01000000'   ;Select camera 7
     GOTO   Set_Cam

Cam_8
     BTFSS   Acive_Scan,7   ;Is camera 8 to be displayed ?
     GOTO    Scan_state_3   ;Increment again
     MOVLW   b'10000000'   ;Select camera 8

Set_Cam
     MOVWF   Camera_Select   

     MOVLW  LOW Scan_state_0
     MOVWF   Scan_state
     RETURN   


Scan_state_4
;Test if more than 1 camera is selected in auto scan

     MOVF   Acive_Scan,W
     MOVWF   Temp01

     MOVLW   0xFE     ; -2
     MOVWF   Bits

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   STATUS,C
     BTFSC   STATUS,C
     INCF   Bits,F

     RRF   Temp01,F
     BTFSC   STATUS,C
     INCF   Bits,F

     BTFSC Bits,7     ;If set then "Bits" has not overflowed. IE less than 2 bits set
     GOTO   State_4b
     MOVLW   LOW Scan_state_5
     MOVWF   Scan_state
     RETURN

State_4b
     MOVLW   LOW Scan_state_0   
     MOVWF   Scan_state
     RETURN



Scan_state_5

     DECF   Camera_No,F     ;Only bits 0, 1, and 2 used  (Value of 7 will overflow into bit 3 on increment.)       
     MOVF   Camera_No,W
;     MOVWF   PORTD
     ANDLW   0x07       ;Mask for bits   0, 1, and 2
     ADDWF   PCL,F

     GOTO   Cam_1_R
     GOTO   Cam_2_R
     GOTO   Cam_3_R
     GOTO   Cam_4_R
     GOTO   Cam_5_R
     GOTO   Cam_6_R
     GOTO   Cam_7_R
     GOTO   Cam_8_R

Cam_1_R
     BTFSS   Acive_Scan,0   ;Is camera 1 to be displayed ?
     GOTO    Scan_state_5   ;Increment again
     MOVLW   b'00000001'   ;Select camera 1
     GOTO   Set_Cam_R

Cam_2_R
     BTFSS   Acive_Scan,1   ;Is camera 2 to be displayed ?
     GOTO    Scan_state_5   ;Increment again
     MOVLW   b'00000010'   ;Select camera 2
     GOTO   Set_Cam_R

Cam_3_R
     BTFSS   Acive_Scan,2   ;Is camera 3 to be displayed ?
     GOTO    Scan_state_5   ;Increment again
     MOVLW   b'00000100'   ;Select camera 3
     GOTO   Set_Cam_R

Cam_4_R
     BTFSS   Acive_Scan,3   ;Is camera 4 to be displayed ?
     GOTO    Scan_state_5   ;Increment again
     MOVLW   b'00001000'   ;Select camera 4
     GOTO   Set_Cam_R

Cam_5_R
     BTFSS   Acive_Scan,4   ;Is camera 5 to be displayed ?
     GOTO    Scan_state_5   ;Increment again
     MOVLW   b'00010000'   ;Select camera 5
     GOTO   Set_Cam_R

Cam_6_R
     BTFSS   Acive_Scan,5   ;Is camera 6 to be displayed ?
     GOTO    Scan_state_5   ;Increment again
     MOVLW   b'00100000'   ;Select camera 6
     GOTO   Set_Cam_R

Cam_7_R
     BTFSS   Acive_Scan,6   ;Is camera 7 to be displayed ?
     GOTO    Scan_state_5   ;Increment again
     MOVLW   b'01000000'   ;Select camera 7
     GOTO   Set_Cam_R

Cam_8_R
     BTFSS   Acive_Scan,7   ;Is camera 8 to be displayed ?
     GOTO    Scan_state_5   ;Increment again
     MOVLW   b'10000000'   ;Select camera 8

Set_Cam_R
     MOVWF   Camera_Select   

     MOVLW  LOW Scan_state_0
     MOVWF   Scan_state
     RETURN   




;         ----------------------------------

   ORG   0x200

;GOTO table for IR commands

GT_Table

     NOP

     MOVLW   0x02
     MOVWF   PCLATH

   MOVF   Data_L,W
   ANDLW   0x3F         ;Mask for bits 0 - 5
   ADDWF   PCL,F
   
   GOTO   Not_used         ;IR code 0x00
   GOTO   Set_1         ;IR code 0x01     "1"
   GOTO   Set_2         ;IR code 0x02     "2"
   GOTO   Set_3         ;IR code 0x03     "3"
   GOTO   Set_4         ;IR code 0x04     "4"
   GOTO   Set_5         ;IR code 0x05     "5"
   GOTO   Set_6         ;IR code 0x06     "6"
   GOTO   Set_7         ;IR code 0x07     "7"
   GOTO   Set_8         ;IR code 0x08     "8"
   GOTO   Not_used         ;IR code 0x09
   GOTO   Not_used         ;IR code 0x0A
   GOTO   Not_used         ;IR code 0x0B
   GOTO   Toggle_light         ;IR code 0x0C   Power standby button
   GOTO   Not_used         ;IR code 0x0D
   GOTO   Not_used         ;IR code 0x0E
   GOTO   Not_used         ;IR code 0x0F

   GOTO   Speed_plus         ;IR code 0x10  Vol +
   GOTO   Speed_minus         ;IR code 0x11  Vol -
   GOTO   Not_used         ;IR code 0x12
   GOTO   Not_used         ;IR code 0x13
   GOTO   Not_used         ;IR code 0x14
   GOTO   Not_used         ;IR code 0x15
   GOTO   Not_used         ;IR code 0x16
   GOTO   Not_used         ;IR code 0x17
   GOTO   Not_used         ;IR code 0x18
   GOTO   Not_used         ;IR code 0x19
   GOTO   Not_used         ;IR code 0x1A
   GOTO   Not_used         ;IR code 0x1B
   GOTO   Not_used         ;IR code 0x1C
   GOTO   Not_used         ;IR code 0x1D
   GOTO   Not_used         ;IR code 0x1E
   GOTO   Not_used         ;IR code 0x1F

   GOTO   Set_active         ;IR code 0x20     "+"
   GOTO   Clear_active         ;IR code 0x21     "-"
   GOTO   Not_used         ;IR code 0x22
   GOTO   Not_used         ;IR code 0x23
   GOTO   Not_used         ;IR code 0x24
   GOTO   Not_used         ;IR code 0x25
   GOTO   Not_used         ;IR code 0x26
   GOTO   Save_Params         ;IR code 0x27     (A & OTR)
   GOTO   Not_used         ;IR code 0x28
   GOTO   Not_used         ;IR code 0x29
   GOTO   Not_used         ;IR code 0x2A
   GOTO   Not_used         ;IR code 0x2B
   GOTO   Step_reverse         ;IR code 0x2C   Fast reverse
   GOTO   Not_used         ;IR code 0x2D
   GOTO   Manual_step         ;IR code 0x2E   Fast forward
   GOTO   Not_used         ;IR code 0x2F

   GOTO   Not_used         ;IR code 0x30
   GOTO   Not_used         ;IR code 0x31
   GOTO   Step_reverse         ;IR code 0x32     (Left arrow on multi remote)
   GOTO   Not_used         ;IR code 0x33
   GOTO   Manual_step         ;IR code 0x34     (Right arrow on multi remote)
   GOTO   Scan_start         ;IR code 0x35     Play
   GOTO   Scan_stop         ;IR code 0x36     Stop
   GOTO   Not_used         ;IR code 0x37  (could change this to "GOTO   Save_Params" for £ Shop remote)
   GOTO   Not_used         ;IR code 0x38
   GOTO   Not_used         ;IR code 0x39
   GOTO   Not_used         ;IR code 0x3A
   GOTO   Not_used         ;IR code 0x3B
   GOTO   Not_used         ;IR code 0x3C
   GOTO   Not_used         ;IR code 0x3D
   GOTO   Not_used         ;IR code 0x3E
   GOTO   Not_used         ;IR code 0x3F


Not_used

;   MOVLW   b'10101010'     ;Test only
;   XORWF   PORTB,F     ;Test only
;   MOVF   Data_L,W
;   MOVWF   PORTB     ;Test only

   RETURN

Set_1           ;IR code 0x01     "1"
   CLRF   Camera_No
   MOVLW   b'00000001'
   MOVWF   Camera_Select
   BCF   Auto_on       ;Turn auto scan off
   RETURN

Set_2           ;IR code 0x02     "2"
   MOVLW   0x01   
   MOVWF   Camera_No
   MOVLW   b'00000010'
   MOVWF   Camera_Select
   BCF   Auto_on       ;Turn auto scan off
   RETURN


Set_3           ;IR code 0x03     "3"
   MOVLW   0x02   
   MOVWF   Camera_No
   MOVLW   b'00000100'
   MOVWF   Camera_Select
   BCF   Auto_on       ;Turn auto scan off
   RETURN

Set_4           ;IR code 0x04     "4"
   MOVLW   0x03   
   MOVWF   Camera_No   
   MOVLW   b'00001000'
   MOVWF   Camera_Select
   BCF   Auto_on       ;Turn auto scan off
   RETURN

Set_5           ;IR code 0x05     "5"
   MOVLW   0x04   
   MOVWF   Camera_No
   MOVLW   b'00010000'
   MOVWF   Camera_Select
   BCF   Auto_on       ;Turn auto scan off
   RETURN

Set_6           ;IR code 0x06     "6"
   MOVLW   0x05   
   MOVWF   Camera_No
   MOVLW   b'00100000'
   MOVWF   Camera_Select
   BCF   Auto_on       ;Turn auto scan off
   RETURN

Set_7           ;IR code 0x07     "7"
   MOVLW   0x06   
   MOVWF   Camera_No
   MOVLW   b'01000000'
   MOVWF   Camera_Select
   BCF   Auto_on       ;Turn auto scan off
   RETURN

Set_8           ;IR code 0x08     "8"
   MOVLW   0x07   
   MOVWF   Camera_No
   MOVLW   b'10000000'
   MOVWF   Camera_Select
   BCF   Auto_on       ;Turn auto scan off
   RETURN


Speed_plus         ;IR code 0x10  Vol +  (Min value 0x04, Max value 0x28)
   MOVF   Scan_delay,W
   SUBLW   0x27
   BTFSC   STATUS,C     ;Skip increment - Already at max value
   INCF   Scan_delay,F

;   MOVF   Scan_delay,w     ;Test
;   MOVWF PORTB     ;Test

   RETURN         


Speed_minus         ;IR code 0x11  Vol -
   MOVF   Scan_delay,W
   SUBLW   0x03
   BTFSS   STATUS,C     ;Skip increment - Already at max value
   DECF   Scan_delay,F


;   MOVF   Scan_delay,w     ;Test
;   MOVWF PORTB     ;Test

   RETURN   

Toggle_light
   BTFSC   Auto_on
   RETURN         ;Only switch if auto scan is off
   
   BTFSS   Flags,3
   RETURN         ;If flag is clear then not enough time has elapsed since last toggle command

   BCF   Flags,3
   MOVF   Camera_Select,W
   XORWF   IR_Ilumination,F     
   RETURN


Set_active           ;IR code 0x20     "+"
   BTFSC   Auto_on
   RETURN         ;Only switch if auto scan is off
   MOVF   Camera_Select,W
   IORWF   Acive_Scan,F
   RETURN

Clear_active           ;IR code 0x21     "-"
   BTFSC   Auto_on
   RETURN         ;Only switch if auto scan is off
   MOVF   Camera_Select,W
   XORLW   0xFF       ;Invert all bits in "W"
   ANDWF   Acive_Scan,F
   RETURN


Save_     NOP           ;IR code 0x27     (A & OTR)
   RETURN

Scan_start         ;IR code 0x35     Play

   CLRF   Timeout_L     ;Set Timeout low and high to length of Autoscan timeout
   MOVLW   Timeout_minutes
   MOVWF   Timeout_H
   BSF   Auto_on
   Return


Scan_stop         ;IR code 0x36     Stop
   BCF   Auto_on
   RETURN

Manual_step
     BTFSC   Auto_on
     RETURN         ;Only step  if auto scan is off

     BTFSS   Flags,3
     RETURN         ;If flag is clear then not enough time has elapsed since last toggle command
     BCF   Flags,3
     MOVLW   LOW Scan_state_2
     MOVWF   Scan_state
     RETURN

Step_reverse
     BTFSC   Auto_on
     RETURN         ;Only step if auto scan is off

     BTFSS   Flags,3
     RETURN         ;If flag is clear then not enough time has elapsed since last toggle command
     BCF   Flags,3
     MOVLW   LOW Scan_state_4
     MOVWF   Scan_state
     RETURN

;       -------------------------

Restore_Params
     MOVLW   EEPROM0
     CALL   EEREAD
     SUBLW   0x33     ;Value used to indicate valid data
     BTFSS   STATUS,Z   ;If result is zero then data is valid
     RETURN
     MOVLW   EEPROM1
     CALL   EEREAD
     MOVWF   Acive_Scan

     MOVLW   EEPROM2
     CALL   EEREAD
     MOVWF   Scan_delay

     MOVLW   EEPROM3
     CALL   EEREAD
     MOVWF   IR_Ilumination
     RETURN

Save_Params       ;Write values to eeprom
     
   MOVLW   EEPROM0     ;Write EEPROM valid flag ( 0x33)
   MOVWF   DATA_EE_ADDR
   MOVLW   0x33
   MOVWF   DATA_EE_DATA
   CALL   EWRITE

   MOVLW   EEPROM1     ;EEPROM address Active_scan
   MOVWF   DATA_EE_ADDR
   MOVFW   Acive_Scan
   MOVWF   DATA_EE_DATA
   CALL   EWRITE

   MOVLW   EEPROM2     ;EEPROM address to Scan_delay
   MOVWF   DATA_EE_ADDR
   MOVFW   Scan_delay
   MOVWF   DATA_EE_DATA
   CALL   EWRITE

   MOVLW   EEPROM3     ;EEPROM address to IR_Ilumination
   MOVWF   DATA_EE_ADDR
   MOVFW   IR_Ilumination
   MOVWF   DATA_EE_DATA
   CALL   EWRITE
     RETURN




;*****************************************************************************   
;
; subroutine to read from EEPROM

;
;  Function : EEREAD         
;     
;  Input:  EEPROM address to read from  (In "W" register)
;
;  Output:  Date read from EEPROM  (In "W" register)
;
;*****************************************************************************  
; subroutine to read EEPROM memory  (For PIC16F876)
EEREAD
   bcf    STATUS,RP0
   bsf    STATUS,RP1   ; select memory bank 2
   movwf    EEADR     ; write EEADR
   BSF STATUS,RP0      ; Bank 3
   BCF   EECON1, EEPGD   ;Select data memory
   bsf   EECON1,RD   ; read EEPROM   
   bcf   STATUS,RP0   ; select bank 2
   movfw   EEDATA     ; EEPROM value in w
   BCF   STATUS,RP1   ;Select bank 0

   return
   
;*****************************************************************************
;
; subroutine to write to EEPROM
;
;  Function : EWRITE
;       Writes data in "W" register to internal EEPROM
;     Address of EEPROM to be written must first be put in EEADR register   
;     
;  Input:  Value to write to internal EEPROM
;
;*****************************************************************************   

; subroutine to write to EEPROM  (For PIC16F876)

EWRITE
;   BCF INTCON,GIE      ;Disable INTs.
   BSF STATUS,RP1      ;
   BSF STATUS,RP0     ;Select bank 3
   BTFSC EECON1,WR    ;Wait for write
   GOTO $-1      ;to complete
   BCF STATUS, RP0    ;select Bank 2
   BCF   STATUS,RP1   ;Select bank 0
   MOVF DATA_EE_ADDR,W    ;Data Memory
   BSF STATUS,RP1      ;Select bank 2
   MOVWF EEADR      ;Address to write
   BCF   STATUS,RP1   ;Select bank 0
   MOVF DATA_EE_DATA,W    ;Data Memory Value
   BSF STATUS,RP1      ;Select bank 2
   MOVWF EEDATA      ;to write
   BSF STATUS,RP0      ;Select Bank 3
   BCF EECON1,EEPGD    ;Point to DATA memory
   BSF EECON1,WREN    ;Enable writes
   MOVLW 0x55      ;
   MOVWF EECON2      ;Write 55h
   MOVLW 0xAA      ;
   MOVWF EECON2      ;Write AAh
   BSF EECON1,WR      ;Set WR bit to  begin write
   BCF EECON1,WREN    ;Disable writes
   BCF   STATUS,RP1   ;Select bank 2
   BCF   STATUS,RP0   ;Select bank 0
;   BSF INTCON,GIE      ;Enable INTs.
   RETURN


;*****************************************************************************

;Write starting values to EEPROM memory

  ORG 0x2100
   DE   0x33       ;Valid data byte
   DE   0xFF       ;Active_scan     (FF - all inputs active.)
   DE   0x06       ;Scan_delay     (1.5 seconds)
   DE   0x00       ;IR_Ilumination     (All off)

   end
The code for reading the RC-5 IR protocol is almost a direct copy of the code that I got from the link in post #2 The information that WAS on that site had code for some other IR protocols. This may give you enough information to write a program in the version of "C" that you want to use.

Les.
 

Thread Starter

nanotronnss

Joined Apr 16, 2018
5
i have familiar in only 'c' i dont know assembly language can you send some other example or how to decode the ir signal with pic16f877a with hi tech c universal tool compiler.i dont know ccs or micro c coding. that's why its hard to me.i have searched many links and forums the only thing is they post the code in pic16f877a with ccs or the code is in hi tech c but controller is different like pic18f2550. please send the code in c
 

AlbertHall

Joined Jun 4, 2014
12,625
Here is code for a PIC18, so it is going to need some fettling to use it with PIC16f877 but most of the work is done for you.
This code will receive and decode multiple IR protocols and decide for itself which protocol the IR is using.
 

Thread Starter

nanotronnss

Joined Apr 16, 2018
5
actually we develope an universal remote so,that i use many protocols.for testing i use NEC protocol.if it great to have multiple ir protocol library or code.
 

be80be

Joined Jul 5, 2008
2,395
You can just the arduino IR code and roll your own it's not that hard I have done IR in C asm pasicl jal and sworfish basic.
And if you find IR code for XC8 it wouldn't take much changes.

Code:
#include <xc.h>

#define _XTAL_FREQ 40000000

char infrared_code[6];
unsigned char UART1Config = 0, baud;
char MensajeTx[] = "Probando ";
int counter = 0;


void main(void) {

//Infrared entry.
TRISBbits.RB0 = 1;

TRISBbits.RB1 = 1;
TRISBbits.RB2 = 1;
TRISBbits.RB3 = 1;
TRISBbits.RB4 = 1;
TRISBbits.RB5 = 1;
TRISBbits.RB6 = 1;
TRISBbits.RB7 = 1;


//State LED
TRISCbits.RC2 = 0;

UART1Config = USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE &              USART_EIGHT_BIT & USART_BRGH_HIGH;
baud = 28;
OpenUSART(UART1Config,baud);

ADCON1 |= 0b1111;
EnablePullups();

RCIF = 0; //reset RX pin flag
RCIE = 1; //Enable RX interrupt
IPEN = 0;

INTCONbits.RBIE = 1; //Enable Interrupt per change on PORTB
INTCONbits.PEIE = 1; // Enable Peripherial Interrupt
INTCONbits.GIE = 1; // Enable Global Interrupt

INTEDG0 = 1;

ei();       //remember the master switch for interrupt?

while(1){
    for(int i=0; i<10; i++)
        __delay_ms(100);

    putsUSART("While: /n");
}
}

void interrupt low_priority myIsr(void){

//If is interrupted by change on portB
if (INTCONbits.RBIF){

    __delay_ms(14);
    __delay_us(224);

    for(int i=0;i<6;i++)
    {
        if(PORTBbits.RB0)
        {
            infrared_code[i] = 1;
        }
        else{
            infrared_code[i] = 0;
        }
        __delay_ms(1);
        __delay_us(778);
    }

    while(BusyUSART());
    putsUSART("Interrupcion: ");

    //for(int i=0;i<6;i++)
    //{
        //WriteUSART(infrared_code[i]);
     //   putsUSART(infrared_code[i]);
   // }
    putsUSART(infrared_code);
    putsUSART("/n");

    if(counter == 0)
    {
        PORTCbits.RC2 = 1;
        counter = 1;
    }
    else if(counter == 1)
    {
        PORTCbits.RC2 = 0;
        counter = 0;
    }
    INTCONbits.GIE = 1;
    INTCONbits.RBIF = 0;

    if (PORTB) {
        asm("nop");
    }

    for(int i=0;i<20;i++)
       __delay_ms(100);

}

}
 

Thread Starter

nanotronnss

Joined Apr 16, 2018
5
hi,
i am tried this project with pic18f44k22. this controller has dual uart so,that we shifted to this controller.my doubt is i am using MPLABX v4.15 with xc8 compiler.i want to know how to configure this particular controller in MPLABX IDE.
 
Top