Wierd sleep issue


Closed Thread
Results 1 to 4 of 4
  1. #1
    orca's Avatar
    orca Guest

    Question Wierd sleep issue

    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

  2. #2
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    you should consider reading the whole datasheet or at least Section 9.7. Be sure you understand it with your current project configuration, config fuses, and it should be OK. Oh well i didn't read and analyse the whole thing as now so i can be wrong.

    Also...
    asm

    clrf 32h

    endasm
    i don't like it... and what do you expect it will do?

    Maybe i'm now also blind but i don't see any register in that specific address. AND MORE, it's not a valid way to write clrf instruction.

    clrf h'32' OR clrf 0x32 are valid

    PS: help us a little bit when posting your code, use the VB code click here. that way it will be a little bit easier to read.. Even better if some of your code lines are indented.
    Last edited by mister_e; - 12th March 2006 at 10:28.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  3. #3
    orca's Avatar
    orca Guest


    Did you find this post helpful? Yes | No

    Wink

    Thank you Mister e,

    It never occurred to me to read the data sheet, especially any part of section 9. I have since found the problem. Although I'm not sure why yet, somehow on power-up intcon<1> gets set even thought the data sheet indicates that the intcon register 'should' power up to all zeros. Anyway, if I place the clear intcon<1> , ext int flag bit, code just before the sleep command rather than after the problem goes away.

    However, I do appreciate the code help with the assembler code:

    asm
    clrf 32h
    endasm

    The misuse of that explains why I needed the CLEAR statement just prior to the snipet of code as they should be redundant statements, I think. Anyway the reason for that is when exiting sleep the LCD would not work properly. After days of haed wracking I finally took a look at the PBP commands for the LCD, i.e. LCDOUT, LCDIN etc. What I found was when the LCDOUT command is issued it looks at a flag bit called LCDINIT and if the bit is clear it then initializes the LCD, if set it does not go through the initialize routine. So, since exiting sleep is a just a continuation of the code the LCDINIT flag is still set so subsequent calls to LCDOUT ignore the initialization routine even though the LCD was turned off. Therefore the LCDINIT flag needs to be cleared after exiting sleep. Guess where the LCDINIT flag bit, among others, is stored by PBP, 0x32.

    Thanks for your assistance!

  4. #4
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default Damn you searched a lot for that!

    O.K.. so now go on the PBP manual, scroll the page and you'll discover
    FLAGS=0.

    Always trust yourself. All those POR default... may sometimes be true, sometimes not. I always set them myself.

    Great to know it's workinf for you now.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

Similar Threads

  1. Won't go back to SLEEP after 1st Interrupt
    By jellis00 in forum mel PIC BASIC Pro
    Replies: 32
    Last Post: - 29th June 2009, 09:00
  2. Battery powered applications
    By NavMicroSystems in forum Off Topic
    Replies: 7
    Last Post: - 22nd June 2009, 07:12
  3. Using Sleep
    By elec_mech in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 17th August 2008, 04:05
  4. 16F628A current high during sleep
    By Rubicon in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 9th October 2006, 10:21
  5. SLEEP Command and Interupts 16F648A
    By ghoot in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 28th May 2004, 18:35

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts