PDA

View Full Version : Interrupts and Sleep help 16f818



andybarrett1
- 1st March 2015, 10:02
Hi thank you for reading…

Using a 16f818/819

I am attempting to put something together that is asleep most of the time and only wakes up for a minute or so to read a display when a button is pressed…To save battery power.

I was thinking of using the ON INTERRUPT command on RB0 , And @SLEEP (the asm version, not the PicBasic Pro)

At the moment I am using the internal Pullups …(Option_Reg.7) … Some talk suggests issues on wakeup ?

I have no code yet as am looking for examples most of what I can find confuses me… I can do hardware but software is not easy !!

Any help / pointers welcome

Thank you for reading.

Acetronics2
- 1st March 2015, 15:08
Hi,

Here is one way to do that ( Pic is a 18F2520 )





Sommeil:

LCDOUT $FE,2, "BYE-BYE "

For I = 8 to 0 Step -1 'Animation arret

LCDOUT $FE,$C0,REP "*"\I," " ' ... 4s
PAUSE 500

NEXT I

PORTB.4 = 0 'Ports LCD à 0
PORTB.5 = 0

PORTC.7 = 0 ' PortC à 0
PORTC.6 = 0
PORTC.5 = 0
PORTC.4 = 0


AlLCD = 1 ' Coupure LCD
AlRef = 0 ' Coupure Vref
ADCON0.0 = 0 ' Désactivation ADC


T3CON.0 = 0 ' arret TMR3
T1CON.0 = 0 ' arret TMR1
T0CON.7 = 0 ' arret TMR0

INTCON.7 = 0 ' Wakeup sans interruptions

INTCON3.0 = 0 ' reset flag INT1
INTCON3.3 = 1 ' validation INT1 pour réveil

Alim = 0 'Coupure alimentation
Signal = 0 'Extinction voyant régime

@ SLEEP
@ Nop ' Redémarrage par mise du contact sans coupure générale
' Arret par décharge capa alim.


INTCON3.3 = 0 'Neutralisation INT1
INTCON3.0 = 0 'Reset Flag INT1
Alim = 1 'Remise alimentation si remise contact rapide.

'************************************************* ****************************
Wakeup: 'Début du Programme - reveil du PIC / Affichage Memoire
'************************************************* ****************************
'
FLAGS = 0 ' Validation Reset LCD

PORTB.4 = 0 'Ports LCD à 0
PORTB.5 = 0

PORTC.7 = 0 ' PortC.4-7 à 0
PORTC.6 = 0
PORTC.5 = 0
PORTC.4 = 0

Reveil = 1
LSelect = 0

GOTO Load 'Rechargement mémoires et Affichage de Départ


Here, the processor stops and restarts @ the line after the "@Sleep" command, because GIE bit has been disabled.
The @NOP is highly recommended here ...

IF GIE is not disabled , processor will jump to the Interrupt stubb ...

Alain

Demon
- 2nd March 2015, 01:57
Merci Alain.

I'm keeping a link to this thread.

Robert
:)

andybarrett1
- 3rd March 2015, 13:28
Hello again...

Have put together some code as I see it... :-


' Name : PI.pbp
' Compiler : PICBASIC PRO Compiler 2.5
' Assembler : MPASM
' Target PIC : PIC16F628A or similar type
' Hardware : VeroBoard
' Oscillator : 4Megs Internal
' Keywords : I2CREAD, I2CWRITE, LCDOUT
' Description : PICBASIC PRO program for an LCD clock program
' using the Dallas DS1307 I2C RTC.


' Define LCD pins
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 6

' Alias pins
SDA Var PORTB.1
SCL Var PORTB.4
wakebutton var PORTB.0 'shake
lcdandrtc var PORTA.6 'LCD and RTC ON/OFF
timeout1 var byte
'timeout2 var byte



' Allocate variables
RTCYear Var Byte
RTCMonth Var Byte
RTCDate Var Byte
RTCDay Var Byte
RTCHour Var Byte
RTCMin Var Byte
RTCSec Var Byte
RTCCtrl Var Byte

TRISA=0 'outputs
TRISB=15 'Bit 0,1,2,3 inputs
CMCON=7 'turns off analogs
wakeup: INTCON=%00010000 'RB0 is interrupt
OPTION_REG.6=0 'Trig on falling
OPTION_REG.7=0 'Enables pull ups
Pause 500 ' Wait for LCD to startup
Lcdout $fe, 1 ' Clear LCD screen
Lcdout "WELCOME TO" ' Display WELCOME TO
Lcdout $fe, $C0, " PI DAY" ' Display PI Day
Pause 2000 ' Wait 2 seconds
Lcdout $fe, 1 ' Clear LCD screen

'Set initial time
RTCYear = $15
RTCMonth = $03
RTCDate = $03
RTCDay = $06
RTCHour = $20
RTCMin = $46
RTCSec = 0
RTCCtrl = 0
'Gosub settime ' Set the time
Goto mainloop ' Skip over subroutines

' Subroutine to write time to RTC

'settime:I2CWrite SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
' Return

' Subroutine to read time from RTC

gettime:I2CRead SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
timeout1=rtcmin
Return

' Main program loop

mainloop:Gosub gettime ' Read the time from the RTC

' Display time on LCD
'Lcdout $fe, 1, hex2 RTCMonth, "/", hex2 RTCDate, "/" , hex2 RTCYear,_
'" ", hex2 RTCHour, ":", hex2 RTCMin, ":", hex2 RTCSec

Lcdout $fe, 1, HEX2 RTCDate, "/", HEX2 RTCMonth," ", HEX2 RTCHour, ":", HEX2 RTCMin, ":", HEX2 RTCSec

IF RTCHour <=$12 then gosub morning
IF RTCHour >=$13 then gosub afternoon

IF RTCHour=$03 and RTCMin=$14 Then CACHE ' Morning Cache
IF RTCHour=$15 and RTCMin=$14 Then CACHE ' Afternoon Cache


if rtcmin=(timeout1+2) then bedtime

Pause 500 ' Do it about 2 times a second
Goto mainloop ' Do it forever

morning: Lcdout $fe, $C0, "CACHE @ 3:14AM"
return

afternoon: Lcdout $fe, $C0, "CACHE @ 3:14PM"
return

CACHE: Lcdout $fe, 1 ' Clear LCD screen
LCDOUT "CONGRATULATIONS"
Lcdout $fe, $C0, "CACHE IS LOCATED"
PAUSE 2000
Lcdout $fe, 1 ' Clear LCD screen
Lcdout "N XX",$DF, " YY.ZZZ " ' Display N 123° 456.789
Lcdout $fe, $C0, "W XX",$DF, " YY.ZZZ " ' Display W 123° 456.789
PAUSE 20000

bedtime:high lcdandrtc 'turn of lcd and rtc
INTCON.1=0 'reset RB0 interupt flag
@ sleep
@ NOP
@ NOP
pause 500 'wakeup delay
goto wakeup

end

Would appreciate some comments .... good or bad on above code.... I am not really sure about my jumps out of the main loop to "bedtime" I have just identified that if it is more than 58 mins to the hour my +2 calc wont work :-) So need to find a work around ?

Thank you for reading... Andy

Tabsoft
- 3rd March 2015, 17:56
Andy,

You are correct that your timeout1 test/calculation will fail when the RTC roles over from 59 to 00.
Also, if for some reason that the execution is delayed you could miss an entire minute which would further affect your timeout1 test.

I took the liberty of adding/modifying the logic to make this portion more robust (although I can't test this :-) )
Take a look at the revised code and see if this helps you.



' Name : PI.pbp
' Compiler : PICBASIC PRO Compiler 2.5
' Assembler : MPASM
' Target PIC : PIC16F628A or similar type
' Hardware : VeroBoard
' Oscillator : 4Megs Internal
' Keywords : I2CREAD, I2CWRITE, LCDOUT
' Description : PICBASIC PRO program for an LCD clock program
' using the Dallas DS1307 I2C RTC.


' Define LCD pins
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 6

' Alias pins
SDA Var PORTB.1
SCL Var PORTB.4
wakebutton var PORTB.0 'shake
lcdandrtc var PORTA.6 'LCD and RTC ON/OFF
timeout1 var byte
'timeout2 var byte
PrevTime var byte 'Holds previously read RTCMin
CurTime var byte 'Holds currently read RTCMin
TimeoutMax var byte 'You can change this to a constant if it is not changed during execution
WakeupFlag var bit 'Used for wakeup/reset tracking for timer

TimeoutMax = $02 'You can delete this if TimeoutMax is a constant
WakeupFlag = 1 'Preset to true

' Allocate variables
RTCYear Var Byte
RTCMonth Var Byte
RTCDate Var Byte
RTCDay Var Byte
RTCHour Var Byte
RTCMin Var Byte
RTCSec Var Byte
RTCCtrl Var Byte

TRISA=0 'outputs
TRISB=15 'Bit 0,1,2,3 inputs
CMCON=7 'turns off analogs



wakeup: INTCON=%00010000 'RB0 is interrupt
OPTION_REG.6=0 'Trig on falling
OPTION_REG.7=0 'Enables pull ups
Pause 500 ' Wait for LCD to startup
Lcdout $fe, 1 ' Clear LCD screen
Lcdout "WELCOME TO" ' Display WELCOME TO
Lcdout $fe, $C0, " PI DAY" ' Display PI Day
Pause 2000 ' Wait 2 seconds
Lcdout $fe, 1 ' Clear LCD screen


timeout1 = TimeoutMax 'Preset timeout1 for countdown

'Set initial time
RTCYear = $15
RTCMonth = $03
RTCDate = $03
RTCDay = $06
RTCHour = $20
RTCMin = $46
RTCSec = 0
RTCCtrl = 0
'Gosub settime ' Set the time
Goto mainloop ' Skip over subroutines

' Subroutine to write time to RTC

'settime:I2CWrite SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
' Return

' Subroutine to read time from RTC

gettime:I2CRead SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
'timeout1=rtcmin
CurTime = RTCMin '
if WakeupFlag = 1 then '1st time after a wakeup/reset
PrevTime = CurTime 'Set PrevTime after wakeup/reset
WakeupFlag = 0 'Clear the flag
endif

Return

' Main program loop

mainloop:
Gosub gettime ' Read the time from the RTC

' Display time on LCD
'Lcdout $fe, 1, hex2 RTCMonth, "/", hex2 RTCDate, "/" , hex2 RTCYear,_
'" ", hex2 RTCHour, ":", hex2 RTCMin, ":", hex2 RTCSec

Lcdout $fe, 1, HEX2 RTCDate, "/", HEX2 RTCMonth," ", HEX2 RTCHour, ":", HEX2 RTCMin, ":", HEX2 RTCSec

IF RTCHour <=$12 then gosub morning
IF RTCHour >=$13 then gosub afternoon

IF RTCHour=$03 and RTCMin=$14 Then CACHE ' Morning Cache
IF RTCHour=$15 and RTCMin=$14 Then CACHE ' Afternoon Cache


'if rtcmin=(timeout1+2) then bedtime
If CurTime > PrevTime Then
timeout1 = timeout1 - (CurTime - PrevTime)
PrevTime = CurTime
else
'Oops something happened. Current time is less than Previous time
'This should take care of the rollover from 59 to 00 minutes and unexpected delays
'If timeout1 = 0 no need to do anything, the timeout1 test below will put the unit to sleep
'The WakeupFlag will be set when we go to sleep and PrevTime and CurTime will be set properly
'after we wakeup and proceed through the mainloop
if timeout1 > 0 then
timeout1 = timeout1 - 1 'decrement the timeout value
PrevTime = CurTime 'Reset Previous time to a valid number for the countdown timer
endif
endif

if timeout1 = 0 then 'Timeout reached
WakeupFlag = 1 'Reset the flag
goto bedtime 'countdown has reached 0, go to sleep
endif

Pause 500 ' Do it about 2 times a second
Goto mainloop ' Do it forever

morning: Lcdout $fe, $C0, "CACHE @ 3:14AM"
return

afternoon: Lcdout $fe, $C0, "CACHE @ 3:14PM"
return

CACHE: Lcdout $fe, 1 ' Clear LCD screen
LCDOUT "CONGRATULATIONS"
Lcdout $fe, $C0, "CACHE IS LOCATED"
PAUSE 2000
Lcdout $fe, 1 ' Clear LCD screen
Lcdout "N XX",$DF, " YY.ZZZ " ' Display N 123° 456.789
Lcdout $fe, $C0, "W XX",$DF, " YY.ZZZ " ' Display W 123° 456.789
PAUSE 20000

bedtime:high lcdandrtc 'turn of lcd and rtc
INTCON.1=0 'reset RB0 interupt flag
@ sleep
@ NOP
@ NOP
pause 500 'wakeup delay
goto wakeup

end

andybarrett1
- 5th March 2015, 16:38
Missed this...

Thanks TABSoft..... Will try later.

Let you know how I get on

BR
Andy

andybarrett1
- 7th March 2015, 21:09
Just had a play with this….

Sorted a few problems out around the sleep…. Still got issues jumping out of the main loop to go to sleep…But the sleep works !!

Tabsoft
- 7th March 2015, 21:56
Andy,

You can encase your mainloop code in a Do/Loop While with a test of the WakeupFlag.
Then when the WakeupFlag is set at timeout, the loop will terminate and you can replace the "GOTO mainloop" instruction with a GOTO bedtime as the last instruction of mainloop.

Or

You can use a Do/Loop with an "Exit" statement in place of the "GOTO bedtime" instruction in the timeout1 If/Then test. Still replace the "GOTO mainloop" instruction with a "GOTO bedtime" instruction as the last instruction in mainloop.

Also, I overlooked the fact that you are jumping to CACHE twice a day and CACHE falls through to bedtime without setting the WakeupFlag. You shou set the WakeupFlag before you jump to CACHE.

What kind of problems are you having?

andybarrett1
- 8th March 2015, 09:43
Idea in the night of using a FOR / NEXT loop with a IF / THEN / GOTO

Easy Fix ??

Wil try later !!!

andybarrett1
- 8th March 2015, 20:33
FOR / NEXT Instruction worked…

One Cycle of my loop takes a .5 Seconds so :-

Timeout = 0 to 240
Code…
………..

Next Timeout
GOTO Label

Thank you for help

Andy

andybarrett1
- 8th March 2015, 21:54
Thank you for reading

Just need to get the quiescent current down whist in sleep mode. Currently seeing around the 2mA mark.

I am hoping we can get it lower than that…?

Thank you for reading.

Andy