I am new to PIC programming and had a question regarding using Interrupts. I had tried using the "Standard" way, but I stumbled upon Darrel's instant interrupts and they seemed much easier and more reliable, so I gave them a try. My goal is to make a programmable clock using a PIC16F627A using a Sony remote and TSOP receiver. I have made simple IR comms work and display, along with a clock, but my issue is that I was having trouble interrupting the clock function when I press my program key on the remote. It just wanted to keep timing and ignore my command, so I gave instant interrupts a try.
My goal in the end is to have my main routine looking for IR pulses, and the interrupt generating the time, but for now I just wanted to make sure I am using the interrupt right, so I am trying to use the interrupt to generate 1/10th second counts. Here is my code.
Code:
'****************************************************************
'* Name : UNTITLED.BAS *
'* Author : [select VIEW...EDITOR OPTIONS] *
'* Notice : Copyright (c) 2009 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 2/11/2009 *
'* Version : 1.0 *
'* Notes : *
'* : *
'****************************************************************
; Initialize your hardware first
INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
Include "modedefs.bas"
Define OSC
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
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
AMPM VAR BIT ' 1 when PM
Counts VAR BYTE ' Counts for timer
Second = 0
Minute1 = 0
Minute2 = 0
Hour1 = 1
Hour2 = 2
AMPM = 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:
IF counts = 10 then
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 = 1
Hour2 = 0
endif
endif
endif
endif
IF Hour1 = 1 AND HOUR2 = 3 THEN 'Roll clock over to 1 from 12
Hour1 = 0
Hour2 = 1
IF AMPM = 0 THEN 'Establish AM and PM times
AMPM = 1
endif
IF AMPM = 1 THEN
AMPM = 0
ENDIF
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
GOTO Main
ENDIF
T1handler:
Counts = Counts + 1 ; Increase the 1/10th sec count
@ 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
Basically the code sits at the default 12:00 and never moves. Judging from this, it would seem that it gets to the display time DEBUG statement, or I would have a display of 8888, but I'm not really sure what happens after that. I am assuming the PIC is fast enough to get through the clock routine when Counts = 10 before it is interrupted, but again, not sure where I am hanging up.
Any suggestions from some of the PIC veterans out there?
Another quick question. I don't think I saw how to disable instant interrupts from occuring when I get to a point that I dont want them?
Bookmarks