PICpocket
- 17th February 2009, 23:46
I was working on a project and ran out of room on my 627A and switched over to a 16F88 spare that I had.
My code is a clock that can be programmed via IR signals. Strangely, the clock portion works fine, however the IR part no longer works. There was no problem changing the device over to the 88, and the program compiled just fine, so I am not sure what is wrong exactly.
Here is a copy of the code:
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
Include "modedefs.bas"
DEFINE LOADER_USED 1 ' Using boot-loader for initial prototype
DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 0
DEFINE DEBUG_BAUD 19200
define DEBUG_MODE 0 ' 1 = inverted, 0 = true
Enter CON 11 'Enter key on remote
Out VAR BYTE(4) '7 seg display
TChange VAR BYTE(4) 'Time change digits
Enable1 VAR BYTE(4) 'Power goes on for memory 1
Disable1 VAR BYTE(4) 'Power goes off for memory 1
Enable2 VAR BYTE(4) 'Power goes on for memory 2
Disable2 VAR BYTE(4) 'Power goes off for memory 2
TimeSet VAR BIT '1 = Enabled 0= Disabled
Second var byte
Minute2 VAR BYTE ' Ones column for minutes
Minute1 VAR BYTE ' Tens column for minutes
Hour2 VAR BYTE ' Ones column for hours
Hour1 VAR BYTE ' Tens column for hours
Counts VAR BYTE ' Counts for timer
Loop VAR BYTE ' Loop counter
Index VAR BYTE ' Index counter
IR_PULSE VAR BYTE(13) ' 13-bytes. 8 data ; 5 address
PULSE_IN VAR WORD ' Raw pulsin value
DBYTE VAR BYTE ' Holds 8-bit data byte
ABYTE VAR BYTE ' Holds 5-bit hardware address
Second = 0
Minute1 = 0
Minute2 = 0
Hour1 = 1
Hour2 = 2
Loop = 0
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, ReloadTMR1, ASM, no ; MUST be first
INT_Handler TMR1_INT, _T1handler, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
;--- Change these to match the desired interrupt frequency -------------------
;--- See http://DarrelTaylor.com/DT_INTS-14/TimerTemplate.html for more Info.
@Freq = 10 ; Frequency of Interrupts in Hz
@Prescaler = 2 ; Timers Prescaler setting
T1CON = $10 ; $30 = Prescaler 1:8, TMR1 OFF
; $00=1:1, $10=1:2, $20=1:4, $30=1:8 -- Must match @Prescaler value
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
GOSUB StartTimer ; Start the Timer
Main:
@ INT_ENABLE TMR1_INT
PULSIN PORTB.7,0,PULSE_IN '// Read-in start pulse
IF (PULSE_IN < 200) OR (PULSE_IN = 0) THEN '// Less than Start pulse, then keep looking
GOTO Main '// so clear outputs & return.
ENDIF
@ INT_DISABLE TMR1_INT
GOTO Verify
'--Main 2 used after values have been entered without Enter press to get around INT
Main2:
PULSIN PORTB.7,0,PULSE_IN '// Read-in start pulse
IF (PULSE_IN < 200) OR (PULSE_IN = 0) THEN '// Less than Start pulse, then keep looking
GOTO Main2 '// so clear outputs & return.
ENDIF
Verify: '// Read, Decode, then verify data
FOR Index = 0 TO 12 '// Setup to read-in 13 pulses
PULSIN PORTB.7,0,IR_PULSE[Index] '// Read 13 low-going pulses on RA.7
NEXT Index '// Loop x times
DBYTE = $FF '// Start with all 1's and find each 0
FOR Index = 0 TO 7 '// Get 8 "data" bits
IF IR_PULSE[Index] < 100 THEN DBYTE.0[Index]=0 '// Less than 1mS = 0
NEXT Index
Result:
Loop = Loop + 1
Out[Loop] = DBYTE + 1
If Out[Loop] = 10 then
Out[Loop] = 0
EndIF
DEBUG "D", Out[1],out[2],out[3],out[4]
PAUSE 500
IF Loop = 5 Then
Loop = 0
EndIF
If TimeSet = 1 then 'Time change
IF OUt[5] = 12 THEN 'If enter pressed, with valid time entry
IF (Out[1] = 2 AND OUt[2]<=4) AND (Out[3]<=5) And (out[4] <=9) Then
Second = 0
HOur1 =Out[1] 'Set new time
Hour2 =Out[2]
Minute1 =Out[3]
Minute2 =Out[4] 'Clear time entry bit.
Out[1] = 20
Out[2] = 20
Out[3] = 20
Out[4] = 20
Out[5] = 20
TimeSet = 0
GOTO Main
ENDIF
IF (Out[1] <= 2 AND OUt[2]<=4) AND (Out[3]<=5) And (out[4] <=9) Then
Second = 0
HOur1 =Out[1] 'Set new time
Hour2 =Out[2]
Minute1 =Out[3]
Minute2 =Out[4] 'Clear time entry bit.
Out[1] = 20
Out[2] = 20
Out[3] = 20
Out[4] = 20
Out[5] = 20
TimeSet = 0
GOTO Main
EndIF
GOTO Main
ENDIF
ENDIF
IF OUT[1]=1 AND Out[2]=7 and OUt[3]=7 and Out[4]=12 THEN 'TimeSet entry correct (177 + enter)?
Out[1] = 20
Out[2] = 20
Out[3] = 20
Out[4] = 20
Out[5] = 20
TimeSet = 1 'If they enter the correct code, then unlock features
GOTO Main
ENDIF
GOTO Main2
T1handler:
Counts = Counts + 1 ; Increase the 1/10th sec count
IF counts = 10 then
Counts = 0
Second = Second + 1 'Calculate time and change values
If Second = 60 then
Minute2 = Minute2 +1
Second = 0
IF Minute2 = 10 THEN
Minute1 = Minute1 + 1
Minute2 = 0
IF Minute1 = 6 then
Hour2 = Hour2 + 1
Minute1 = 0
IF Hour2 = 10 THEN
Hour1 = Hour1 + 1
Hour2 = 0
endif
endif
endif
endif
IF Hour1 = 2 AND HOUR2 = 4 THEN 'Roll clock over from 23 to 0
Hour1 = 0
Hour2 = 0
endif
If Hour1 = 0 then 'If hour 1 is 0 then do not display it
Hour1 = 20 'SLED-C4 will not display anything if the
Endif 'value is above 10
DEBUG "D", Hour1,Hour2,Minute1,Minute2 ' Display time
DEBUG "P",12,"~" ' Display Colon
ELSE
@ INT_RETURN
ENDIF
@ INT_RETURN
;---[TMR1 reload - interrupt handler]-----------------------------------------
ASM ; Calculate Timer Reload Constant
ReloadInst = 8 ; # of Intructions used to reload timer
if ((Prescaler == 1)||(Prescaler == 2)||(Prescaler == 4)||(Prescaler == 8))
MaxCount = 65536 + (ReloadInst / Prescaler)
TimerReload = MaxCount - (OSC*1000000/4/Prescaler/Freq)
if ((TimerReload < 0) || (TimerReload > (65535-ReloadInst)))
error Invalid Timer Values - check "OSC", "Freq" and "Prescaler"
endif
else
error Invalid Prescaler
endif
ENDASM
@Timer1 = TMR1L ; map timer registers to a word variable
Timer1 VAR WORD EXT
TimerReload CON EXT ; Get the External Constant
TMR1ON VAR T1CON.0 ; Alias the Timers ON/OFF bit
;---Reload Timer1------
ASM
ReloadTMR1
MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
MOVLW LOW(TimerReload) ; 1 Add TimerReload to the
ADDWF TMR1L,F ; 1 value in Timer1
BTFSC STATUS,C ; 1/2
INCF TMR1H,F ; 1
MOVLW HIGH(TimerReload) ; 1
ADDWF TMR1H,F ; 1
MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
INT_RETURN
ENDASM
;---Start/Stop controls -----
StartTimer:
Timer1 = TimerReload ; Load Timer
TMR1ON = 1 ; start timer
RETURN
StopTimer:
TMR1ON = 0 ; stop timer
RETURN
Thanks for the help
My code is a clock that can be programmed via IR signals. Strangely, the clock portion works fine, however the IR part no longer works. There was no problem changing the device over to the 88, and the program compiled just fine, so I am not sure what is wrong exactly.
Here is a copy of the code:
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
Include "modedefs.bas"
DEFINE LOADER_USED 1 ' Using boot-loader for initial prototype
DEFINE DEBUG_REG PORTB
DEFINE DEBUG_BIT 0
DEFINE DEBUG_BAUD 19200
define DEBUG_MODE 0 ' 1 = inverted, 0 = true
Enter CON 11 'Enter key on remote
Out VAR BYTE(4) '7 seg display
TChange VAR BYTE(4) 'Time change digits
Enable1 VAR BYTE(4) 'Power goes on for memory 1
Disable1 VAR BYTE(4) 'Power goes off for memory 1
Enable2 VAR BYTE(4) 'Power goes on for memory 2
Disable2 VAR BYTE(4) 'Power goes off for memory 2
TimeSet VAR BIT '1 = Enabled 0= Disabled
Second var byte
Minute2 VAR BYTE ' Ones column for minutes
Minute1 VAR BYTE ' Tens column for minutes
Hour2 VAR BYTE ' Ones column for hours
Hour1 VAR BYTE ' Tens column for hours
Counts VAR BYTE ' Counts for timer
Loop VAR BYTE ' Loop counter
Index VAR BYTE ' Index counter
IR_PULSE VAR BYTE(13) ' 13-bytes. 8 data ; 5 address
PULSE_IN VAR WORD ' Raw pulsin value
DBYTE VAR BYTE ' Holds 8-bit data byte
ABYTE VAR BYTE ' Holds 5-bit hardware address
Second = 0
Minute1 = 0
Minute2 = 0
Hour1 = 1
Hour2 = 2
Loop = 0
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR1_INT, ReloadTMR1, ASM, no ; MUST be first
INT_Handler TMR1_INT, _T1handler, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
;--- Change these to match the desired interrupt frequency -------------------
;--- See http://DarrelTaylor.com/DT_INTS-14/TimerTemplate.html for more Info.
@Freq = 10 ; Frequency of Interrupts in Hz
@Prescaler = 2 ; Timers Prescaler setting
T1CON = $10 ; $30 = Prescaler 1:8, TMR1 OFF
; $00=1:1, $10=1:2, $20=1:4, $30=1:8 -- Must match @Prescaler value
@ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
GOSUB StartTimer ; Start the Timer
Main:
@ INT_ENABLE TMR1_INT
PULSIN PORTB.7,0,PULSE_IN '// Read-in start pulse
IF (PULSE_IN < 200) OR (PULSE_IN = 0) THEN '// Less than Start pulse, then keep looking
GOTO Main '// so clear outputs & return.
ENDIF
@ INT_DISABLE TMR1_INT
GOTO Verify
'--Main 2 used after values have been entered without Enter press to get around INT
Main2:
PULSIN PORTB.7,0,PULSE_IN '// Read-in start pulse
IF (PULSE_IN < 200) OR (PULSE_IN = 0) THEN '// Less than Start pulse, then keep looking
GOTO Main2 '// so clear outputs & return.
ENDIF
Verify: '// Read, Decode, then verify data
FOR Index = 0 TO 12 '// Setup to read-in 13 pulses
PULSIN PORTB.7,0,IR_PULSE[Index] '// Read 13 low-going pulses on RA.7
NEXT Index '// Loop x times
DBYTE = $FF '// Start with all 1's and find each 0
FOR Index = 0 TO 7 '// Get 8 "data" bits
IF IR_PULSE[Index] < 100 THEN DBYTE.0[Index]=0 '// Less than 1mS = 0
NEXT Index
Result:
Loop = Loop + 1
Out[Loop] = DBYTE + 1
If Out[Loop] = 10 then
Out[Loop] = 0
EndIF
DEBUG "D", Out[1],out[2],out[3],out[4]
PAUSE 500
IF Loop = 5 Then
Loop = 0
EndIF
If TimeSet = 1 then 'Time change
IF OUt[5] = 12 THEN 'If enter pressed, with valid time entry
IF (Out[1] = 2 AND OUt[2]<=4) AND (Out[3]<=5) And (out[4] <=9) Then
Second = 0
HOur1 =Out[1] 'Set new time
Hour2 =Out[2]
Minute1 =Out[3]
Minute2 =Out[4] 'Clear time entry bit.
Out[1] = 20
Out[2] = 20
Out[3] = 20
Out[4] = 20
Out[5] = 20
TimeSet = 0
GOTO Main
ENDIF
IF (Out[1] <= 2 AND OUt[2]<=4) AND (Out[3]<=5) And (out[4] <=9) Then
Second = 0
HOur1 =Out[1] 'Set new time
Hour2 =Out[2]
Minute1 =Out[3]
Minute2 =Out[4] 'Clear time entry bit.
Out[1] = 20
Out[2] = 20
Out[3] = 20
Out[4] = 20
Out[5] = 20
TimeSet = 0
GOTO Main
EndIF
GOTO Main
ENDIF
ENDIF
IF OUT[1]=1 AND Out[2]=7 and OUt[3]=7 and Out[4]=12 THEN 'TimeSet entry correct (177 + enter)?
Out[1] = 20
Out[2] = 20
Out[3] = 20
Out[4] = 20
Out[5] = 20
TimeSet = 1 'If they enter the correct code, then unlock features
GOTO Main
ENDIF
GOTO Main2
T1handler:
Counts = Counts + 1 ; Increase the 1/10th sec count
IF counts = 10 then
Counts = 0
Second = Second + 1 'Calculate time and change values
If Second = 60 then
Minute2 = Minute2 +1
Second = 0
IF Minute2 = 10 THEN
Minute1 = Minute1 + 1
Minute2 = 0
IF Minute1 = 6 then
Hour2 = Hour2 + 1
Minute1 = 0
IF Hour2 = 10 THEN
Hour1 = Hour1 + 1
Hour2 = 0
endif
endif
endif
endif
IF Hour1 = 2 AND HOUR2 = 4 THEN 'Roll clock over from 23 to 0
Hour1 = 0
Hour2 = 0
endif
If Hour1 = 0 then 'If hour 1 is 0 then do not display it
Hour1 = 20 'SLED-C4 will not display anything if the
Endif 'value is above 10
DEBUG "D", Hour1,Hour2,Minute1,Minute2 ' Display time
DEBUG "P",12,"~" ' Display Colon
ELSE
@ INT_RETURN
ENDIF
@ INT_RETURN
;---[TMR1 reload - interrupt handler]-----------------------------------------
ASM ; Calculate Timer Reload Constant
ReloadInst = 8 ; # of Intructions used to reload timer
if ((Prescaler == 1)||(Prescaler == 2)||(Prescaler == 4)||(Prescaler == 8))
MaxCount = 65536 + (ReloadInst / Prescaler)
TimerReload = MaxCount - (OSC*1000000/4/Prescaler/Freq)
if ((TimerReload < 0) || (TimerReload > (65535-ReloadInst)))
error Invalid Timer Values - check "OSC", "Freq" and "Prescaler"
endif
else
error Invalid Prescaler
endif
ENDASM
@Timer1 = TMR1L ; map timer registers to a word variable
Timer1 VAR WORD EXT
TimerReload CON EXT ; Get the External Constant
TMR1ON VAR T1CON.0 ; Alias the Timers ON/OFF bit
;---Reload Timer1------
ASM
ReloadTMR1
MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
MOVLW LOW(TimerReload) ; 1 Add TimerReload to the
ADDWF TMR1L,F ; 1 value in Timer1
BTFSC STATUS,C ; 1/2
INCF TMR1H,F ; 1
MOVLW HIGH(TimerReload) ; 1
ADDWF TMR1H,F ; 1
MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
INT_RETURN
ENDASM
;---Start/Stop controls -----
StartTimer:
Timer1 = TimerReload ; Load Timer
TMR1ON = 1 ; start timer
RETURN
StopTimer:
TMR1ON = 0 ; stop timer
RETURN
Thanks for the help