PDA

View Full Version : Basic problem with interrupts and sleep command



Davidmarks
- 19th February 2012, 13:36
Hi
My recent post on power saving has unfortunately notv produced a solution to my problem and I have therefore tried a different approach which has produced problems which I hope are easier to solve .
My requirement is for a progam which can produce two flashing patterns for an led on portb.7 selected by a pushbutton on portb.0 ( For a model lighthouse a friend is building) I would like to use a single button which can sequence thru' OFF -Pattern 1 - Pattern 2 -Off it is intended that each of the two patterns will run for a finite time (or number of sequences) and then shut down. Alternatively a button press during the sequence can cause shut down. I am very unsure about the use of interrupts but after studying melabs example I have produced the attached program:
Whilst the program enables me to select the next sequece when the current sequence has completed it will not interrrup the sequence if I wish to move to shutdown. Can anyone tell me why and how perhaps I could achieve this ?
An ancillary question is ---- Since I want to shut down the circuit indefinately and I understand the the sleep command has a maximum of about 18 hours do I have to let it wake briefly and execute a routine or am I correct in understanding that by using @sleep I can get an indefinite shutdown . Any help would be greatly appreciated.
[@ DEVICE pic16f628a,intrc_osc_noclkout,mclr_on
led Var PORTB.7
x var byte
delay var byte
OPTION_REG = $7f ' Enable PORTB pullups
On Interrupt Goto myint ' Define interrupt handler
INTCON = $90 ' Enable INTE interrupt

main:
for x = 1 to 10 ' First led flashing pattern
low portb.7 '
pause 200 '
high portb.7 '
pause 200 '
next x '

sleep 500 ' sleep after completing first pattern

for x = 1 to 10 ' Second led flashing pattern
low portb.7 '
pause 500 '
high portb.7 '
pause 500 '
next x '

sleep 500 'sleep after completing second led flashing pattern

sleep 500 ' just sleep

goto main: 'return to first vflashing pattern


disable ' this bit copied from example melabs program
myint: ' but I havent a clue what it means and the
delay = 200 ' picbasicpro manual fails to enlighten me
INTCON.1 = 0 '
resume '



End
]

Jerson
- 19th February 2012, 16:19
At the moment I am a bit dull, but, let me try to answer this for you from memory. Pls correct me if I am wrong.

First, the @sleep command puts the PIC to sleep directly via a machine code whereas the SLEEP command from PBP allows you to put the PIC to sleep for a time duration.

I have successfully used the @sleep command to indefinitely sleep my PIC in many products. Then I use the wake on port change interrupt (RB4..RB7) to come back out of sleep and continue where I left off.

Yes, all this is sounding good, but, where's the code you say.

I can show you the high level pseudo code. You flesh it out in PBP. Neat thing for this sleep operation is that you don't need to enable interrupts at all.


1) Initialize the PIC ports and set to interrupt on change
Put the pushbutton pin on a line which can interrupt the pic (you dont want to poll this all the time esp when sleeping)
Set Patterndelay to 200


2) Clear INT-ON-PIN-Change flag in INTCON
read the button state to reset the int on change state
Do pattern
3) @Sleep
4) LOOP to 2

What goes into the function??

Function:
for cnt = 1 to 10
HIGH PORTB.7

PAUSE PatternDelay
if BUTTON then Breakout ' I am assuming button will go high on pressed
LOW PORTB.7

PAUSE PatternDelay
if BUTTON then Breakout ' I am assuming button will go high on pressed
next
BreakOut:
if PatternDelay=200 then
PatternDelay = 500
else
PatternDelay = 200
endif
return

Davidmarks
- 20th February 2012, 11:05
Thanks for suggestion. I am stuggling rather with the pseudo code but have found some code in another post and copied it with just one modification i.e.the line ansel = 0 in the original code would not compile so I have used cmcon = 7 instead (to set port a to digital). The program runs and goes to sleepok but refuses to wake up when ra2 goes high. If I switch wdt on I notice that the pic wakes itself up after a second or so. I have trawled the forum and the web to find out why without any success at all. I'm sure I must be doing something dumb (an increasingly common occurence !) The code I am using is as follows:
[@ DEVICE pic16f628a,intrc_osc_noclkout,mclr_off,wdt_off
led Var PORTB.7
x var byte

PORTA = 0 ; PortA low
TRISA = 4 ; RA2 = input
cmcon = 7 ; set port a to digital
INTCON.7 = 0 ; turn off global interrupts
OPTION_REG.6 = 1 ; wake on rising edge
main:
for x = 1 to 10 ' First led flashing pattern
low portb.7 '
pause 200 '
high portb.7 '
pause 200 '
next x '

INTCON.1 = 0 ; clear RA2 interrupt flag in case set (right before @ Sleep command)
@ sleep

goto main
]

Dave
- 20th February 2012, 11:47
I thought the Interrupt on change bits were only available on port B?

Jerson
- 20th February 2012, 14:08
Hi David

The pin interrupt bits are only on Port B. I showed you the pseudo code as a guideline of how to do it. Of course you need to look into the datasheets and read a lot to make it work. I am guessing that you are new to PBP judging by the few posts you've made. You may also look at this thread
http://www.picbasic.co.uk/forum/showthread.php?t=11100

Still more questions, feel free to ask here. Someone will surely chime in.

Regards

ps: forgot. While posting your code, enclose them within [ code] and [ /code] tags. Makes it easier to read and keeps your formatting.

Davidmarks
- 20th February 2012, 15:45
Hi,
Not exactly new but sporadic (and ancient) Have dumped code using RA2 and after more study produced the following using rb4. Amost works! i can now sequence through the patterns if I allow them to complete but if I press the button whilst the pattern is in progress I can only toggle between patterns 1 and 2 and am unable to get it to shut down ! Sorry about the code layout I seem to be using the tags incorrectly will try again here goes;
code:
'************************************************* **************************
' Lighthouse led flashing routines in which pressing button on rb4 is intended
' to sequence thru Pattern1 -- Pattern2 --off or if no button is pressed
' shutdown will occur when pattern is completed'
' When (if ?) program finally works the simple flashing will be replaced
' by appropriate lighthouse patterns.
' ************************************************** *************************
@ DEVICE pic16f628a,intrc_osc_noclkout,mclr_on,wdt_off
x var byte
TRISB = %11110000
TRISA = %00000000
CMCON = 7
OPTION_REG.7=0 ' 0 = Enable PORTB Pull Ups
@ Device wdt_off ' Disable the WatchDog Timer
INTCON.3=1 ' Interrupt Control Register
PORTB = 0
PORTA = 0
flag var byte

flag = 0
porta.0 = 1
porta.1 = 1
porta.2 = 1

main:
INTCON.0=0 '
@ SLEEP ' Start program with pic asleep
INTCON.0=0 ' rb4 pulled low to wake

pattern1:
for x = 1 to 100
if flag = 1 and portb.4 = 0 then pattern2 ' Interrupts loop to jump to
PORTA.0 = 0 ' pattern 2 flag prevents
pause 200 ' premature jump when rb4
porta.0 = 1 ' first pulled low
pause 200
flag = 1
next x
INTCON.0=0 ' puts pic to sleep at natural
@ SLEEP ' end of pattern1
INTCON.0=0
goto main

pattern2:
flag = 0
for x = 1 to 100
if flag = 1 and portb.4 = 0 then shutdown ' Interrupts loop to jump to
flag = 0 ' shutdown
PORTA.1 = 0
pause 200
porta.1 = 1
pause 200
flag = 1
next x
INTCON.0=0 'puts pic to sleep at natural
@ SLEEP 'end of pattern2
INTCON.0=0
goto main

shutdown: 'puts pic to sleep and returns to program start
INTCON.0=0
@ sleep
INTCON.0=0
goto main
end
/code

Jerson
- 21st February 2012, 01:21
Hello David

You've done quite a bit. I have re-arranged the code a bit. I think this will work. I am awed by your enthusiasm. Changes that I made are highlighted by capitals.



'************************************************* **************************
' Lighthouse led flashing routines in which pressing button on rb4 is intended
' to sequence thru Pattern1 -- Pattern2 --off or if no button is pressed
' shutdown will occur when pattern is completed'
' When (if ?) program finally works the simple flashing will be replaced
' by appropriate lighthouse patterns.
' ************************************************** *************************
@ DEVICE pic16f628a,intrc_osc_noclkout,mclr_on,wdt_off

x var byte
pattern var byte


TRISB = 110000
TRISA = 000000
CMCON = 7
OPTION_REG.7=0 ' 0 = Enable PORTB Pull Ups
@ Device wdt_off ' Disable the WatchDog Timer
INTCON.3=1 ' Interrupt Control Register (RBIE)
PORTB = 0
PORTA = 0

porta.0 = 1
porta.1 = 1
porta.2 = 1

PORTB.4 = 1 ' THIS NEEDS TO BE SET HIGH SINCE YOU ARE LATER
' USING A LOW TO SENSE A BUTTON PRESS
PATTERN = 1

main:
INTCON.0=0 ' clear any pending (RBIF)
@ SLEEP ' Start program with pic asleep
INTCON.0=0 ' clear any pending (RBIF) rb4 pulled low to wake

' BIFURCATE THE OPERATION DEPENDING ON PATTERN SELECTED
IF PATTERN = 1 THEN GOTO PATTERN1
IF PATTERN = 2 THEN GOTO PATTERN2
goto main

pattern1:
for x = 1 to 100
PORTA.0 = 0 ' pattern 2 flag prevents
pause 200 ' premature jump when rb4

' PUTTING THE EVALUATION HERE, SPEEDS UP THE BUTTON SENSING
IF PORTB.4 = 0 THEN
PATTERN = 2 ' INTERRUPTS LOOP TO JUMP TO
GOTO PATTERN2
ENDIF

porta.0 = 1 ' first pulled low
pause 200

' PUTTING THE EVALUATION HERE, PREVENTS A PREMATURE JUMP
IF PORTB.4 = 0 THEN
PATTERN = 2 ' INTERRUPTS LOOP TO JUMP TO
GOTO PATTERN2
ENDIF
next x
goto main 'puts the pic to sleep

pattern2:
for x = 1 to 100
PORTA.1 = 0
pause 200

IF PORTB.4 = 0 THEN
PATTERN = 1 ' INTERRUPTS LOOP TO JUMP TO
GOTO PATTERN1
ENDIF

porta.1 = 1
pause 200

IF PORTB.4 = 0 THEN
PATTERN = 1 ' INTERRUPTS LOOP TO JUMP TO
GOTO PATTERN1
ENDIF

next x
goto main 'puts the pic to sleep

shutdown: 'puts pic to sleep and returns to program start
goto main
end