;Program ASM_RX.ASM 'Reads signals from a Sony IR remote control, 'and returns the button code in the variable IR_But. 'the device code in the variable IR_DEV, 'The infrared receiver module used is the Sharp IS1U60. 'The infrared receiver module for this experiment should, 'be a type that is set for a 40kHz carrier frequency. 'If another type is used. some reduction in range may be noticed. 'The remote control used, may be either a Sony manufactured unit, 'or one of the universal remotes that can be configured for Sony equipment. 'This is important since we are dealing with a specific signal protocol. 'With Sony’s SIRC specification, a start pulse is initially sent to 'indicate the beginning of a frame of data. This pulse is approx 2.4 ms in length. 'Following this, are 5-bits of data, which represent the DEVICE code, 'which signifies the target device (TV, VCR, etc.). 'Then an additional 7-bit BUTTON code 'Data bits are sent with the most significant bit first (MSB). List P=16F84 ; Set Micro to PIC16F84 #Include ; Load the Variable Definitions __Config _CP_OFF & _WDT_OFF & _PWRTE_OFF & _XT_OSC Radix Decimal ; ** Declare the Variables and RAM usage** Packet Equ 12 ; A 16-bit variable P_Val Equ 14 ; The bit length 55us = 0, 110us = 1 IR_But Equ 15 ; The BUTTON code returned IR_Dev Equ 16 ; The DEVICE code returned Cntr Equ 17 ; Temporary Variable Bitcnt Equ 18 ; Temporary loop variable D_LP1 Equ 19 ; Delay Loop 1 D_LP2 Equ 20 ; Delay Loop 2 Tr_Byte Equ 21 ; The value to transmit serially ORG 00 Goto Start ORG 04 ; ** THE MAIN PROGRAM LOOP STARTS HERE ** Start Clrf PortA ; Clear PortA Bsf Status,5 ; Point to Page1 Movlw 00000100b ; Make PortA,2 an Input Movwf PortA Bcf Status,5 ; Point back to Page0 Again Clrwdt ; Walk the dog Call IRIN ; Get the IR signal from the handset Bcf PortA,0 ; Clear both LEDs Bcf PortA,1 Movlw 255 ; If IR_DEV=255 then look again Subwf IR_Dev,w Btfsc STATUS,z Goto Again ; ** Transmit the DEVICE code then the BUTTON code serially ** ; ** at inverted 9600 baud N-8-1 ** Movf IR_Dev,w Call Sout Movf IR_But,w Call Sout ; ** If IR_DEV <> 1 (TV device code) then look Again ** Movlw 1 Subwf IR_Dev,w Btfss STATUS,z Goto Again ; ** If IR_But=16 (channel up) then illuminate the green LED ** Movlw 16 Subwf IR_But,w Btfss STATUS,z Goto CH_UP Bsf PortA,1 ; **If IR_BUT=17 (channel down) then illuminate the red LED ** CH_UP Movlw 17 Subwf IR_But,w Btfss STATUS,z Goto Exit Bsf PortA,0 Exit Call Delay ; Delay for 10ms Goto Again ; ** THE SUBROUTINES START HERE ** ; ************************************************************************** ; * Receive the data bits and convert them into a 12-bit packet * ; * A one should return approx 110, actual timing is 1200us * ; * A zero should return approx 55, actual timing is 600us * ; * We split the difference and say that < 80 is a 0 and >= 80 is a 1 * ; * These values are for use with a 4mHz crystal * ; * The 7-bit BUTTON code is returned in the variable IR_But, * ; * and the 5-bit DEVICE code is returned in the variable IR_Dev. * ; * IR_DEV will return holding 255, if no header was detected * ; ************************************************************************** IRIN Clrwdt ; Walk the dog Call Pulsin ; Measure the header length ; Verify a good header, if its not valid then exit ; ** If PVAL < 200 then return with IR_DEV=255 ** Movlw 200 Subwf P_VAL,W Btfsc STATUS,C Goto Next1 Movlw 255 Movwf IR_Dev Return ; ** If PVAL > 250 then return with IR_DEV=255 ** Next1 Movlw 250 Subwf P_VAL,W Btfss STATUS,C Goto PK_Strt Movlw 255 Movwf IR_Dev Return ; Build up the 12-bit packet Clrf Packet Clrf Packet+1 PK_Strt Movlw 12 ; Create a loop for 12-bits Movwf Bitcnt S_again Call Pulsin ; Get the bit duration Movlw 80 ; If the pulse is greater then 80 then it's a 1 Subwf P_VAL,w Btfsc STATUS,C Goto One Bcf Packet+1,4 ; Clear the bit Goto Cont One Bsf Packet+1,4 ; Set the bit Cont Rrf Packet+1,F ; Rotate the bit into place Rrf Packet,F Decfsz Bitcnt ; Have we reached 12-bits yet? Goto S_again ; No! then loop again ; *********************************************************** ; * Split the 7-bit BUTTON code, and the 5-bit DEVICE code * ; *********************************************************** Movf Packet,W ; Mask the 7-bit BUTTON code Andlw 01111111b Movwf IR_But ; ** Rotate PACKET and PACKET+1, right, 7 times ** Rrf Packet+1,F Rrf Packet,F Rrf Packet+1,F Rrf Packet,F Rrf Packet+1,F Rrf Packet,F Rrf Packet+1,F Rrf Packet,F Rrf Packet+1,F Rrf Packet,F Rrf Packet+1,F Rrf Packet,F Rrf Packet+1,F Rrf Packet,F Movf Packet,W ; Mask the 5-bit DEVICE code Andlw 00011111b Movwf IR_Dev Return ; ******************************************** ; * Measure a high to low pulse on PortA,2 * ; * and leave the 8-bit result in P_VAL. * ; * An 11 microsecond resolution is achieved * ; * using a 4MHz crystal. * ; ******************************************** Pulsin Clrwdt ; Walk the dog Clrf Cntr ; Clear the variables used, Clrf P_Val ; prior to the subroutine Trans Btfss PortA,2 ; Wait for a 1 to 0 transition Goto Edge ; Edge found! Incfsz P_Val ; Else, increment P-VAL until >255 Goto Trans Incfsz Cntr ; Loop up to 255 Goto Trans Return Edge Clrf P_Val ; A 1 to 0 transition occurred Edge_LP Btfsc PortA,2 ; Count how long it's logic 0 Return Clrwdt ; Walk the dog Nop ; Timing loop Nop Nop Nop Nop Incfsz P_Val ; Increment P_VAL until >255 Goto Edge_LP Return ; **************************************************** ; * Transmit inverted 9600 baud (8-N-1) From PortA,3 * ; **************************************************** Sout Movwf TR_Byte ; The byte to send Movlw 08 Movwf Bitcnt ; Create a loop of 8 Bsf PortA,3 ; Send the start bit Call Bit_Dly ; Wait, one bit time Xmtlp Rrf Tr_Byte ; Rotate Right Moves Data Bits Into Carry, Starting With Bit 0. Btfsc Status,0 ; Is it a Zero-bit? Bcf PortA,3 ; Yes, so send A Zero Btfss Status,0 ; Is it a One-bit? Bsf PortA,3 ; Yes, so send A One Call Bit_Dly ; Wait, one bit time Decfsz Bitcnt Goto Xmtlp ; Loop for 8-bits Bcf PortA,3 ; Send the stop bit Call Bit_Dly ; Wait, one bit time Return ; Exit the subroutine ; ** Delay 1 bit time ** Bit_Dly Movlw 22 ; Set Baud to 9600 Movwf D_Lp1 Slp Clrwdt ; Walk the dog (1us) Decfsz D_Lp1 Goto Slp Return ; ****************** ; * DELAY for 10ms * ; ****************** Delay Movlw 4 Movwf D_Lp2 Clrf D_Lp1 D_Loop Clrwdt ; Walk the dog (1us) Nop Decfsz D_Lp1,f Goto D_Loop Decfsz D_LP2,f Goto D_Loop Return End