PDA

View Full Version : Help me with interupt



azmax100
- 30th January 2009, 15:20
Hi,

I have success to make an LCD Clock and able to do interrupt for an Led to on for certain period. I am trying to do something like moving a servo let say for every one hour. How do I implement the interrupt.

Please show me some example as I am totally newbie.
Also to what value I have to change the Option_Reg to use with 20mhz OSC. Now I'm using pause 667 to make the time almost accurate.

Here's my code:
@ DEVICE pic16F627a, HS_OSC ' System Clock Options check
@ DEVICE pic16F627a, LVP_OFF ' Low-Voltage Programming

DEFINE OSC 20 ' define osc if not using @ device INTRC_OSC_NOCLKOUT
BAUD con 16784 ' 2400 Baud, inverted, NoParity: conservative for testing

'================================================= ======================
Ticks VAR byte 'Tick count (61 ticks = 1 sec)
Hour VAR byte ' Hour variable
Minute VAR byte ' Minute variable
Second VAR byte ' Second variable
Disp VAR byte ' Disp = 1 to update display
Delay VAR byte ' Used to Debounce button
TRISB = %00000011 ' PORTB all outputs
PortB.4 = 0
Led var PortB.2
PinOut VAR PORTB.4 ' Tx on RB4
Hrs var PORTB.0
Mins var PORTB.1
'================================================= ========================

PAUSE 1000 ' Wait 0.5sec for LCD to initialize

' Initialize timer interrupt. The prescaler is set to 64 and the
' TMR0 is left to run from 0 to 255. With a clock frequency of 4MHz,
' The timer interrupt is generated at every 256 * 64 = 16.384ms.
'/ Inside the ISR, variable ticks is incremented by 1. When Ticks = 61
'then time for a timer interrupt is: 61*16.384 = 999.424ms and variable
' Second is then updated. i.e. Second is updated nearly every second.
'
OPTION_REG = $05 ' Set prescaler = 64
ON INTERRUPT GOTO ISR ' ISR routine
INTCON = $A0 ' Enable TMR0 interrupt and global interrupts

SEROUT2 PinOut,BAUD,[27,"1"] 'Clear Lcd
pause 500


' Beginning of MAIN program loop
Hour = 0
Minute = 0
Second = 0
Ticks = 0
'
LOOP:
'
' Check Hour button and if pressed increment variable Hour
'
if (Minute = 0) And (Second = 10) then
' gosub light
high Led

gosub Debounce
endif
if (Minute = 1) And (Second = 0) then
' gosub light
high Led

gosub Debounce
endif
IF Hrs = 0 THEN
Hour = Hour + 1
IF Hour = 24 THEN Hour = 0
Gosub Debounce
ENDIF
'
'Check Minute button and
IF Mins = 0 THEN
Minute = Minute + 1
high Led
IF Minute = 60 THEN Minute = 0
Gosub Debounce
ENDIF
'
' Display update section. The display is updated when variable
' Disp is 1. This variable is set to 1 inside the ISR when the
' seconds changes. The cursor is set to home position and the
' time is displayed on the LCD
'
IF Disp = 1 THEN
serout2 PinOut, BAUD,[ 12," The Time Is " ]
serout2 PinOut, BAUD,[12," H:",DEC2 Hour," M:",DEC2 Minute," S:",dec2 Second]
pause 667 ' if use 20mhz crystal
Disp = 0
ENDIF
GOTO LOOP

' This subroutine Debounces the buttons. Also, a delay is introduced when
' a button is pressed so that the variable attached to the button (Hour or Second)
' can be incremented after a small delay.
'
Debounce:
FOR Delay = 1 To 200
Pause 1 ' Delay 1ms inside a loop. This way,
NEXT Delay ' timer interrupts are not stopped
Disp = 1 ' Set display flag to 1
RETURN
'
' This is the Timer interrupt Service Routine. The program jumps to this code
' whenever the timer overflows from 255 to 0. i.e. every 256 count. The prescaler
' is set to 64 and the clock frequency is 4MHz. i.e. the basic instruction cycle
' time is 1 microsecond. Thus, timer interrupts occur at every 64*256 = 16.384ms.
' Variable Ticks is incremented by 1 each time a timer interrupt occurs. When Ticks
' is equal to 61, then one second has elapsed (16.384*61 = 999.424ms) and then
' variable Second is incremented by 1. When Second is 60, variable Minute is
' incremented by 1. When Minute is 60, variable Hour is incremented by 1.
'
' Timer TMR0 interrupts are re-enabled just before the program exits this routine.
'
DISABLE
ISR:
Ticks = Ticks + 1
IF Ticks < 61 THEN NoUpdate
'
' 1 second has elapsed, now update seconds and if necessary minutes and hours.

Ticks = 0
Second = Second + 1 'Update second
if(Minute = 0) And (Second => 30) then
low Led
endif

if(Minute = 1) And (Second => 30) then
low Led
endif

IF Second = 60 THEN
Second = 0
Minute = Minute + 1 ' Update Minute
IF Minute = 60 THEN
Minute = 0
Hour = Hour + 1 ' Update Hour
IF Hour = 24 THEN
Hour = 0
ENDIF
ENDIF
ENDIF

Disp = 1 ' Set to update display
'
' End of time update
'
NoUpdate:
INTCON.2 = 0 ' Re-enable TMR0 interrupts
Resume
ENABLE ' Re-enable interrupts
END
END 'End of program


Sorry for the long listing.

azmax100
- 2nd February 2009, 15:15
Hi all,
While waiting for somebody to reply I have done few experiment with the code but nothing come close to what I need.

I need my small robot to move around every 10 minutes and sleep after 3 minutes. Can somebody show me how? I can do with the High and Low for Led but not the servo.

I dont need the complete code. Just let me know how or where to put the code. Although I have some experience with Basic Stamp I have never play with interrupt before.

Really appreciate if somebody could give me some light.

thanks & regards.

HenrikOlsson
- 2nd February 2009, 16:22
Hi,
Have a look at Darrell's Instant Interrupt routines, you'll find them on his web-site. (http://darreltaylor.com/DT_INTS-14/intro.html) Then look specifically at the Timer template (http://darreltaylor.com/DT_INTS-14/TimerTemplate.html) that he has there. That should get you started.

azmax100
- 3rd February 2009, 00:17
Thanks Henrik. You light up my life.:)