Here's an easier way without hardware PWM. I haven't tested this on a Sony TV, but it
works great for testing our Sony decoders.
Code:
@ DEVICE PIC16F648A, xt_osc, wdt_off, mclr_off, lvp_off, protect_off
DEFINE OSC 4
' Sony TV - IR pulse timing
Synch CON 96 ' 96 x 25uS = 2.4mS (synch pulse with carrier ON)
Interbit CON 500 ' 500uS (delay between data bits with carrier OFF)
InterPacket CON 26000' 26mS (delay between data packets with carrier OFF)
Logic1 CON 48 ' 48 x 25uS = 1.2mS. Logic 1 bit = 1.2mS (carrier ON)
Logic0 CON 23 ' 24 x 25uS = 600uS. Logic 0 bit = 600uS (carrier ON)
' Packet format: 7 bits on left are button number. 5 bits on right select TV.
K1 CON %000000010000 ' BUTTON 1
K2 CON %100000010000 ' BUTTON 2
K3 CON %010000010000 ' BUTTON 3
K4 CON %110000010000 ' BUTTON 4
K5 CON %001000010000 ' BUTTON 5
K6 CON %101000010000 ' BUTTON 6
K7 CON %011000010000 ' BUTTON 7
K8 CON %111000010000 ' BUTTON 8
K9 CON %000100010000 ' BUTTON 9
K0 CON %100100010000 ' BUTTON 0
MENU CON %000000010000 ' MENU BUTTON
MUTE CON %001010010000 ' MUTE BUTTON
CHUP CON %000010010000 ' CHANNEL UP BUTTON
CHDWN CON %100010010000 ' CHANNEL DOWN BUTTON
VOLUP CON %010010010000 ' VOLUME UP BUTTON
VOLDWN CON %110010010000 ' VOLUME DOWN BUTTON
PREVCH CON %110111010000 ' PREVIOUS CHANNEL BUTTON
ENTER CON %110100010000 ' ENTER BUTTON
POWER CON %101010010000 ' ON/OFF POWER BUTTON
X VAR BYTE ' Data bit loop counter & bit index pointer
Duration VAR BYTE ' Duration of button press
Loops VAR BYTE ' Loop count
Cycles VAR BYTE BANK0 SYSTEM' Number of carrier cycles to generate
Key VAR WORD ' Button # to send
PORTB = %00000000 ' All outputs = 0 on boot
TRISB = %00000000 ' RB0 = IRLED out
@ #define IRTX PORTB ; Define port to use for IR out
@ #define PIN 0 ; Define port pin for IR out
GOTO Main ' Jump over pulse routine to Main
Pulse: ' Generate "Cycles" number of 40kHz pulses
ASM ; Keep this routine in code page 1, and jump over to Main
bsf IRTX,PIN ; 1uS, LED=on
goto $+1 ; + 2uS = 3uS
goto $+1 ; + 2uS = 5uS
goto $+1 ; + 2uS = 7uS
goto $+1 ; + 2uS = 9uS
goto $+1 ; + 2uS = 11uS
goto $+1 ; + 2uS = 13uS
bcf IRTX,PIN ; 1uS, LED=off
goto $+1 ; + 2uS = 3uS
goto $+1 ; + 2uS = 5uS
goto $+1 ; + 2uS = 7uS
goto $+1 ; + 2uS = 9uS
decfsz Cycles,f ; + 1uS = 10S
goto _Pulse ; + 2uS = 12uS
ENDASM
return ' Return to caller
Main:
PAUSE 5000
Key = POWER ' Press Power button
Duration = 2 ' Send it twice
FOR Loops = 1 TO Duration ' Loop 1 to duration
Cycles = Synch ' 2.4mS synch (carrier on)
GOSUB Pulse ' Send synch
' Synch done, now do data bits
FOR X = 11 to 0 STEP-1 ' 12-bits total MSB first
PAUSEUS InterBit ' Pause InterBit delay period (carrier off)
IF Key.0[X] = 1 THEN '
Cycles = Logic1 ' Logic 1
ELSE ' or
Cycles = Logic0 ' Logic 0
ENDIF
GOSUB Pulse ' Send data
NEXT X ' Loop for all 12-bits
PAUSEUS InterPacket ' Inter-Packet delay period (carrier off)
NEXT Loops ' Loop for duration
GOTO Main ' Return for more
END
Bookmarks