; ****************************************** ; RemoteEx-4.asm ; Infrared remote control repeater ; Pete Griffiths (C) 2004 ; http://picprojects.org.uk/projects/ ; ; Bug correction for 12F629 operation 07/11/2008 ; ..thanks to Pete Putnam for this fix. ; ; Modified to run with 12F683 ; ; This code can be used with either the 12F629, 12F675 or 12F683 ; ; In the code below there are two sections named _hi and _lo. ; Within these sections is a 'nop' instruction. By including or excluding this one 'nop' ; the two frequencies selectable on GP5 can be configured as 40Khz, 38.4Khz or 37Khz ; ; The code by default is set to 40Khz and 37Khz. ; ; This software generates a 40Khzk, 38.4Khz or 37Khz carrier that is modulated on or off ; depending on the logic level on GP2 ; ; By connecting a device such as a TSOP2238 IR Receiver module to GPIO2 and driving an IR ; LED emitter from GPIO0 (GPIO1) a very low component count IR Remote Control Repeater ; can be realised. ; ; When GP2 goes low, the PIC wakes from sleep and executes a software ; loop that toggles pins GP0 and GP1 with a 15% duty cycle square wave ; at either ~40Khz, ~38.4 or 37Khz depending on the logic level on GP5 after ; reset. GP5 isn't sampled again during operation. ; ___ ___ ; GP0 Q __| |______________| |______________| ; __ ______________ ______________ ; GP1 ^Q |___| |___| | ; ; The software will always leave GP0 clear and GP1 set when GP2 goes high, ; Once GP2 goes high, the PIC enters a low power sleep state. A high to low ; transition on GP2 will wake the PIC and exectute the carrier loop ; ;************************************************************************* ; 12F629 / 675 / 683 * ; +---------+ * ; 1 | | 8 * ; 5.0 V ----+ +---- GND * ; 2 | | 7 * ; Frequency Sel GP5 ----+ +---- GP0 Q Output to IR LED * ; 3 | | 6 * ; GP4 ----+ +---- GP1 ^Q Output to IR LED * ; 4 | | 5 * ; GP3 ----+ +---- GP2 Input from IR Detector * ; +---------+ * ; * ;************************************************************************* ; ; ; This code will assembled and run on a 12F629, 12F675 or 12F683 ; Select the correct PIC in MPLAB under 'Configure - Select Device' ; before assembling this code. ; IFDEF __12F683 #include "p12f683.inc" #define ADCpresent ENDIF IFDEF __12F675 #include "p12f675.inc" #define ADCpresent ENDIF IFDEF __12F629 #include "p12f629.inc" ENDIF IFDEF __12F683 __CONFIG _CP_OFF & _WDT_OFF & _BOD_OFF &_PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CPD_OFF ELSE __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CPD_OFF ENDIF cblock 0x20 output frequency endc org 0x000 ; ****************************************** ; Startup initialisation _reset ;Initialise registers in Bank 1 bsf STATUS,RP0 ; Select Bank 1 IFDEF OSCCAL call 0x3ff ; Get OSCAL value movwf OSCCAL ; write to OSCCAL register ENDIF IFDEF ADCpresent clrf ANSEL ; Set ports for digital mode (12F675 / 12F683 only) ENDIF movlw b'11111100' ; set up W to movwf TRISIO ; enable GPIO 0,1 for output movlw b'00010000' ; set up W to movwf INTCON ; enable edge interupts bcf OPTION_REG,NOT_GPPU ; enable global pull up bsf WPU,5 ; enable pull up on GPIO5 bsf WPU,2 ; enable pull up on GPIO2 bcf STATUS,RP0 ; Select Bank 0 movlw 0x07 ; load W=7 IFDEF __12F683 movwf CMCON0 ; disable Comparator on 12F683 ELSE movwf CMCON ; disable Comparator on 12F675/627 ENDIF movlw 0x02 ; Set up W to movwf output ; Set initial state of output movwf GPIO ; and update physical output Q=0, ^Q=1 clrf ADCON0 ; turn off A/D convertor movf GPIO,W andlw b'00100000' ; mask in bit 5 bsf STATUS,RP0 ; select bank 1 bcf OPTION_REG,INTEDG ; Interupt on negative edge on GPIO 2 bcf STATUS,RP0 ; Select bank 0 clrf frequency ; Clear frequency flag FR btfsc GPIO,5 ; Test GPIO5 bsf frequency,0 ; If GPIO5 ==1 then set frequency flag FR _sleep movlw 0x02 movwf output movwf GPIO movfw GPIO bcf INTCON,INTF sleep btfsc frequency,0 ; Check Frequency flag goto _lo ; If 1 do Lo ; else do Hi _hi movlw 0x01 ;1 movwf GPIO ;1 Hi nop ;1 ; 40KHz without 'nop' ; 38.4KHz with ;nop movlw 0x02 ;1 movwf GPIO ;1 Lo call _dummy ;4 call _dummy ;4 call _dummy ;4 nop ;1 nop ;1 nop ;1 movfw GPIO ;1 andlw 0x04 ;1 bz _hi ;3 ; 1/(25 x 1E-06) = 40Khz ; 1/(26 x 1E-06) = 38.46Khz goto _sleep _lo movlw 0x01 ;1 movwf GPIO ;1 nop ;1 ; 38.4KHz without 'nop' ; 37KHz with nop movlw 0x02 ;1 movwf GPIO ;1 call _dummy ;4 call _dummy ;4 call _dummy ;4 call _dummy ;4 movfw GPIO ;1 andlw 0x04 ;1 bz _lo ;3 ; 1/(26 x 1E-06) = 38.46Khz ; 1/(27 x 1E-06) = 37Khz goto _sleep _dummy return dt "IR Remote Repeater. Pete Griffiths 2004 -" dt "RemoteEx-4.asm" end