I apologize if this topic has been previously covered but I could not find after searching for alitte while.

I am using a PIC 16F676, ICD2, PICBASIC Pro, internal 4Mhz RC osc.

Basically I am using the PIC to measure temperature and pressure, display them to an Optrex LCD and then place the PIC in sleep mode to conserve battery power.

The problem is the first pass through the code the sleep command is either skipped (highly unlikely) or somehow times out instantly prior to one of the two wake-up methods and continues on to the next pass. The two methods are 1) WTD based on the PBP sleep command or 2) an external interrupt which can wake up the PIC before the WDT exits the sleep command. After the first pass it works fine, i.e. it goes to sleep, if I only allow the wake-up to be WDT based. If I wake it up with the ext int it exhibits the same behavior as the first pass and will then work on the next pass. This is very strange.

I have also tried using only the ext int, turning off the WDT and using @sleep only to get the same results: does not go to sleep in the first pass but will after the second pass. Code is below. Any assistance will be greatly appreciated.

' Set LCD data port to PORTC
DEFINE LCD_DREG PORTC

'Set starting data bit to 4
DEFINE LCD_DBIT 0

'Set LCD register select bit to PORTC
DEFINE LCD_RSREG PORTC

'Set LCD register select bit to bit 4
DEFINE LCD_RSBIT 4

'Set LCD enable port
DEFINE LCD_EREG PORTC

'Set enable bit
DEFINE LCD_EBIT 5

TRISA.5 = 0 'Set PORTA BIT 5 to output, Voltage reg enable/disable
PORTA.5 = 0

TRISA.4 = 0 'Set PORTA BIT 4 to output to be on/off for LCD and temp sensor power
PORTA.4 = 1

'Set clock speed
'DEFINE OSC 4

TEMP VAR word
t0 VAR TEMP.byte0
t1 VAR TEMP.byte1
w0 VAR word
w1 VAR word
w2 var word

DEPTH VAR word
d0 VAR DEPTH.byte0
d1 VAR DEPTH.byte1
RA2 var bit
i var byte

TRISA.1 = 1 'Set PORTA BIT 1 to input
ANSEL.1 = 1 'Select PORTA bit 1 to analog input for Temp Sensor

TRISA.0 = 1 'Set PORTA BIT 0 to input
ANSEL.0 = 1 'Select PORTA bit 0 to analog input for Pressure Sensor

TRISA.2 = 1 'Set PORTA BIT 2 to input
ANSEL.2 = 0 'Be sure PORTA BIT 2 is a digital input for Ext Int Wake Up

option_reg.6 = 0 ' set interrupt to occur on falling edge
intcon.4 = 1 ' enable external interrupt

ADCON1 = %01010000 'Set A/D clock source to 16Tosc
'to ensure sufficient conversion time

MAIN:

for i = 1 to 20
pause 1000
' Temperature measurement
ADCON0 = %10000101 'result is right justified, Vref = external (using 1.024V at present)
'select RA1, enable but not start A/D.

PAUSEUS 25 'A/D acquisition time for sample and hold circuit

ADCON0.1 = 1 'Start A/D conversion

WHILE PIR1.6 == 0 'wait for A/D conversion to finish
WEND

ADCON0.0 = 0 'disable A/D converter to save power
PIR1.6 = 0 'reset interrupt flag

' Place results into TEMP variable
t0 = ADRESL
t1 = ADRESH

' approximate resolution is 4.86mV/ct. Since no floating point
' routines in PBP use fixed point math and keep track of decimal
TEMP = TEMP *54 ' Want to multiply by 486 but too many issues arrise from PBP inability to have variables longer than 16-bits

w0 = TEMP / 10000
w1 = TEMP // 10000

w0 = w0 * 9
w1 = (w1 / 10) * 9 'Remainder seems to be 4 places so divide by 10 first to keep the *9 confined to a 16-bit number

w0 = w0 + w1 DIG 3 ' Whole number plus most significant digit of remainder hand waving
w1 = w1 DIG 2 ' Next significant digit of remainder as the temths decimal place

Lcdout $fe, 1 'Clear LCD screen
Lcdout "T= ", DEC w0,".",DEC w1,"C"

' Pressure or Depth measurement
ADCON0 = %10000001 'result is right justified, Vref = Vdd
'select RA0, enable but not start A/D.

PAUSEUS 25 'A/D acquisition time for sample and hold circuit

ADCON0.1 = 1 'Start A/D conversion

WHILE PIR1.6 == 0 'wait for A/D conversion to finish
WEND

ADCON0.0 = 0 'disable A/D converter to save power
PIR1.6 = 0 'reset interrupt flag
d0 = ADRESL
d1 = ADRESH

'DEPTH = DEPTH - 38 'Subtract offset ~0.183v = ~38 counts
'DEPTH = DEPTH * 44
'DEPTH = DEPTH / 128
'DEPTH = DEPTH *110
'w0 = DEPTH / 169
'w1 = DEPTH // 169

Lcdout $fe, $C0 'Clear LCD screen
Lcdout "D= ", DEC d0 ',".",DEC w1

next i

Lcdout $fe, 1 'Clear LCD screen
Lcdout "ENTERING"
Lcdout $fe, $C0 'Clear LCD screen
Lcdout "SLEEP"

PAUSE 500

' PORTA.5 = 0 'Turn off power to pressure sensor

PORTA.4 = 0 'Turn off power to temp sensor and LCD

TRISC = %000000
PORTC = 0 'Place all output to zero for zero current draw

sleep 300

intcon.1 = 0
PORTA.4 = 1
' PORTA.5 = 1

CLEAR 'Clear all RAM including system RAM. This is important
'because it clears the FLAGS register that includes the
'LCDINITFLAG. The LCDINITFLAG is SET to indicate that
'the LCD has been initialized by the LCDOUT command. But since exiting SLEEP is a
'WatchDog timeout reset which just resumes normal operation
'the LCDINITFLAG is still SET so that when power is restored
'to the LCD the program thinks its initialized and LCDOUT does
'not attempt to re-initialize, which is not good!

asm

clrf 32h

endasm

pause 1000

Lcdout $fe, 1 'Clear LCD screen
Lcdout "End Loop"


GOTO MAIN