Code:
'==================================================================================================
'==================================== CONFIGURE PIC ===========================================
'==================================================================================================
' # 18F46K22 #
DEFINE OSC 4
'
DEFINE PULSIN_MAX 10000
'
@ CONFIG PBADEN = OFF ' PORTB<5:0> pins are configured as digital I/O on Reset
@ CONFIG LVP = OFF ' Single-Supply ICSP disabled
@ CONFIG XINST = OFF ' Instruction set extension and Indexed Addressing mode disabled (Legacy mode)
'
'@ CONFIG STVREN = ON ' Stack full/underflow will cause Reset
'
'@ CONFIG WDTEN = ON ' WDT is always enabled. SWDTEN bit has no effect
'@ CONFIG WDTPS = 512 ' Watchdog Timer Postscale Select bits
'
'@ CONFIG PWRTEN = ON ' Power up timer enabled
'@ CONFIG BOREN = SBORDIS ' Brown-out Reset enabled in hardware only (SBOREN is disabled)
'@ CONFIG BORV = 285 ' VBOR set to 2.85 V nominal
'
@ CONFIG FOSC = INTIO67 'Internal oscillator block
OSCCON.6 = 1 '#################### 111 = 16, 110 = 8
OSCCON.5 = 0 '###### 16 MHz ###### 101 = 4, 100 = 2
OSCCON.4 = 1 '####################
OSCTUNE.6 = 0 '##### PLL X 4 ######
'@ CONFIG PLLCFG = ON 'Oscillator multiplied by 4
'#########################################
'####### Make Ports Digital ##########
'#########################################
'
ANSELA = $00 'SET PORT A ALL DIGITAL
ANSELB = $00 'SET PORT B ALL DIGITAL
ANSELC = $00 'SET PORT C ALL DIGITAL
ANSELD = $00 'SET PORT D ALL DIGITAL
ANSELE = $00 'SET PORT E ALL DIGITAL
'
'==================================================================================================
'=================================== INCLUDE FILES ==========================================
'==================================================================================================
'
'==================================================================================================
'=================================== SET PIC PORTS ==========================================
'==================================================================================================
'
HCDATA var PORTC.5 ' Pin 14 74HC595
HCCLK var PORTD.4 ' Pin 11 74HC595
HCLAT var PORTC.7 ' Pin 12 74HC595
CIVP VAR PORTA.5 ' TO ICOM REMOTE PORT CI-V
LCDP VAR PORTB.0 ' SERIAL LCD PORT (OPTIONAL)
INFRA VAR PORTD.7 ' Infrared LED DATA
'LED VAR PORTC.0 ' STATUS LED
'
'==================================================================================================
'==================================== SET VARIABLES =========================================
'==================================================================================================
'
Leader VAR WORD ' will be up to 900 for a 9mS leader pulse
BtnVal VAR BYTE[32] ' holds 32 pulse results
DByte1 VAR BYTE ' address byte
DByte2 VAR BYTE ' inverse of address byte
DByte3 VAR BYTE ' command byte
DByte4 VAR BYTE ' inverse of command byte
X VAR BYTE ' loop count
Y VAR BYTE ' = DByte3 (command) for subroutines selection
Z VAR BYTE ' Generic counter FOR-NEXT Loops (digits counter)
RBdata VAR BYTE[6] ' Bytes array to store digits for frequency or memory
f1 VAR BYTE ' Vol, SQL, MSB byte
f2 VAR BYTE ' Vol, SQL, LSB Byte
f3 VAR BYTE ' BCD to BIN byte store for DEC calculations
f4 VAR BYTE ' BCD to BIN byte store for DEC calculations
pattern VAR Byte ' 74HC595 output pattern
'
'==================================================================================================
'===================================== SET CONSTANTS =======================================
'==================================================================================================
'
DL1 CON 800 ' > 8.5 ms pulse for NEC Protocol (Start) - 850 @ 4 MHz
DL2 CON 110 ' > 1.5 ms pulse for NEC Protocol (read bit 0 or 1) @ 4 MHX
LCDS CON 16468 ' SERIAL LCD SPEED 16468 -> 9600
LINE1 CON 128 ' LCD Line 1
LINE2 CON 192 ' LCD Line 2
I CON 254 ' LCD general command
CIVS CON 84 ' "188"->4800, "84"->9600, "32"->19200 "813"->1200
CIVA CON $70 ' TRX address
'
'####################################################################################################################################################
'
'
'##################################################################################################
'################################# PROGRAM STARTS HERE #####################################
'##################################################################################################
'
START:
'
CLEAR '
pattern = %00000000 ' LED OFF
gosub OUT_595
PAUSE 200
GOSUB LCDCLS
PAUSE 10
SEROUT2 LCDP,LCDS,["HELLO MALAKA"]
pattern = %11111111 ' LED ON
gosub OUT_595
pause 500
pattern = %00000000 ' LED OFF
gosub OUT_595
gosub LCDCLS ' Clear LCD
'
'==================================================================================================
'============================== MAIN LOOP CHECKS FOR INFRARED COMMAND =========================
'==================================================================================================
'
MAIN:
'
PULSIN INFRA,0,Leader ' Leader pulse is ~9mS low-going
IF Leader < DL1 THEN Main ' Valid start burst check > 8.5 ms
GOSUB READ32 ' Read 32 bytes (0-15 for address and 16-31 for command)
'GOTO MAIN ' ONLY FOR TESTING AND READING VARIOUS NEC REMOTES
GOSUB COMMANDS ' GOTO Check Input Commands
PAUSE 100
GOTO MAIN
'
'==================================================================================================
'=================================== VOLUME UP SUBROUTINE ====================================
'==================================================================================================
'
VOLUP: ' All variables are set as bytes
'
Z = $01 ' For future functions
DO
IF Leader > DL1 THEN
GOSUB VOLUP1 ' Go to increase volume
ELSE
pattern = 0
GOSUB Out_595
GOTO MAIN
ENDIF
PULSIN INFRA,0,Leader ' Check again for start pulse (autorepeat function) WORKS
LOOP
GOTO VOLUP ' Go back to main routine to check for another button press
'
'==================================================================================================
'================================ VOLUME INCREASE AND BYTE CALCULATIONS =======================
'==================================================================================================
'
VOLUP1:
'
GOSUB READVD
f4 = f4 + 10 ' Increase volume by 10 units
IF f3 < 2 AND f4 >= 99 THEN
f4 = 0 ' Make sure result is less than 100
f3 = f3 + 1 ' Increase hundreds by 1
ELSEIF f3 > 1 AND f4 > 54 THEN ' If volume > 254 stay to 254 (max)
f3 = 2
f4 = 54
ENDIF
f1 = ((f3 / 10) << 4) + (f3 // 10) ' Convert bin to BCD
f2 = ((f4 / 10) << 4) + (f4 // 10) ' Convert bin to BCD
SEROUT2 CIVP,CIVS,[$FE,$FE,civa,$E0,$14,$01,f1,f2,$FD] ' NEW VOLUME setting
pause 50
'GOSUB PRINTVAL ' Only for testing and displaying actual volume
RETURN
'
'==================================================================================================
'===================================== RECEIVED COMMANDS ====================================
'==================================================================================================
'
COMMANDS:
'
Y = DByte3
'
IF Y = 7 OR Y = 3 THEN ' VOL - (added new NEC remote)
pattern = 1
GOSUB Out_595
' GOSUB VOLDOWN
ENDIF
IF Y = 21 OR Y = 2 THEN ' VOL + (added new NEC remote)
pattern = 1
GOSUB Out_595
GOSUB VOLUP
ENDIF
RETURN
'
'################################################################################################################################
'######################################################## CLEAR LCD #########################################################
'################################################################################################################################
'
LCDCLS:
'
SEROUT2 LCDP,LCDS,[254,1] ' Clear LCD
return
'
'################################################################################################################################
'################################################################################################################################
'################################################################################################################################
'
' -------------------------------------------------------------------------------------------------------------------------------
Out_595:
'
SHIFTOUT HCDATA,HCCLK,1,[pattern] ' send pattern to 1st 74HC595
PULSOUT HCLAT, 5 ' latch outputs
RETURN
'
'==================================================================================================
'================================ READ 32 Bytes - Address and Command =========================
'==================================================================================================
'
READ32:
'
FOR X = 0 TO 31 ' grab 32 incoming pulses
PULSIN INFRA,1,BtnVal[X] ' now measuring high-going pulse widths
NEXT X
FOR X = 0 TO 7 ' sort 1st 8 pulses
IF BtnVal[X] > DL2 THEN ' > 150 x 10uS = > 1.5mS pulse period
DByte1.0[X]=1
ELSE
DByte1.0[X]=0
ENDIF
NEXT X
FOR X = 8 TO 15 ' sort 2nd 8 pulses, etc....
IF BtnVal[X] > DL2 THEN
DByte2.0[X-8]=1
ELSE
DByte2.0[X-8]=0
ENDIF
NEXT X
FOR X = 16 TO 23
IF BtnVal[X] > DL2 THEN
DByte3.0[X-16]=1
ELSE
DByte3.0[X-16]=0
ENDIF
NEXT X
FOR X = 24 TO 31
IF BtnVal[X] > DL2 THEN
DByte4.0[X-24]=1
ELSE
DByte4.0[X-24]=0
ENDIF
NEXT X
DByte4 = ~ DByte4 ' Reverse all the 8 bits to compare
IF DByte3 <> DByte4 THEN
GOSUB LCDCLS
SEROUT2 LCDP,LCDS, [I,LINE1,"Command ERROR !"]
pause 500
GOSUB LCDCLS
pattern = 0
GOSUB out_595
GOTO MAIN
ENDIF
SEROUT2 LCDP,LCDS, [I,LINE1,"A : ",DEC3 DByte1, "-",BIN8 DByte1] ' PRINT ADDRESS
SEROUT2 LCDP,LCDS, [I,LINE2,"C : ",DEC3 DByte3, "-",BIN8 DByte3] ' PRINT COMMAND
RETURN
'
'==================================================================================================
'================================== Read Volume & SQL Data ====================================
'==================================================================================================
'
READVD:
'
SEROUT2 CIVP,CIVS,[$FE,$FE,CIVA,$E0,$14,Z,$FD] ' Send this to the radio to read current SETTING
SERIN2 CIVP,CIVS,[SKIP 6,f1,f2] ' Skip first 6 useless bytes and read next 2 bytes
PAUSE 5 ' Give sometime to rest
f3 = ((f1 >> 4) * 10) + (f1 & $0f) ' Convert BCD to binary
f4 = ((f2 >> 4) * 10) + (f2 & $0f) ' Convert BCD to binary
RETURN ' Go back to set new Volume or Squelch
'
Well, that's all folks...
Bookmarks