ULPWU & PLVD on 12F635 & 16F684


Closed Thread
Results 1 to 19 of 19
  1. #1
    Join Date
    Nov 2003
    Posts
    98

    Default ULPWU & PLVD on 12F635 & 16F684

    Hi all
    anyone one have any experience using the ULPWU (ultra low power wake up) module on the PIC12F635 ?
    it seems to have started life in the PIC16F684
    looking for any tips or code snips using PBP

    i need to also use the PLVD (programmable low voltage detect) module but at 20+ uA i don't have the power budget to leave it on all the time for low battery warning indication

    so my thought is to use the ULPWU (if i can figure it out) and wake up once in a while and enable the PLVD to sniff the battery

    at first read it looks like the ULPWU will interrupt and wake up the unit roughly every 30ms using a 1000pf cap
    this way too often for me, guess i could keep a counter or something

    but using PBP it is not clear to me how to proceed
    make the pin an output, set HI briefly, turn it back to an input and go to sleep?
    something like that ?

    TIA
    ds

  2. #2
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Well, that was interesting. I've never used ULPWU or PLVD yet, but I have used the 12F635
    in a ton of applications.

    Out of curiosity, I put this together to tinker with today, and it works just like the book says.

    You'll probably want to experiment with the series resistor & cap value. As voltage drops, the
    wake up frequency increases, so you'll need to find some happy medium there to work in your
    own application. I used a 200ohm series resistor with 1kpF cap.
    Code:
    @ DEVICE PIC12F635,MCLR_OFF,INTRC_OSC_NOCLKOUT,WDT_OFF,BOD_OFF
    @ DEVICE PWRT_ON,FCMEN_OFF,IESO_OFF,WUREN_OFF,PROTECT_OFF
    
        SYMBOL PROBE = GPIO.1  ' scope probe indicates wakeup from sleep
        SYMBOL PLVD_LED = GPIO.2
        
        OSCCON = %01100000 ' Internal 4MHz select
        OPTION_REG = 128   ' internal pull-ups off 
        CMCON0 = 7         ' disable comparator
        VRCON = 0          ' disable internal Vref
            
        GPIO = %00000000   ' LED off on boot
        TRISIO = %00000001 ' GPIO.0 = input, rest outputs
        PIR1 = 0           ' clear peripheral int flags
        PCON.5 = 1         ' ultra low power wakeup enabled
        
    Main:
        GPIO.0 = 1         ' set data latch on GPIO.0
        TRISIO.0 = 0       ' GPIO.0 = output (charging cap)
        PAUSEUS 24         ' charge cap for 24uS
        TRISIO.0 = 1       ' GPIO.0 = input to discharge cap
        IOCA.0 = 1         ' int on change enabled for GPIO.0
        INTCON = %00001000 ' global ints disabled, int on change enabled
        @ SLEEP            ' put PIC to sleep
        TOGGLE PROBE       ' indicate ULPWU wake up from sleep & clear mismatch
        INTCON.0 = 0       ' clear wake up on change int flag
        GOSUB TestVolts    ' go test for under voltage condition
        GOTO Main          ' not sure what this does...;o}
    
    TestVolts:
        INTCON.6 = 1       ' peripheral ints enabled
        LVDCON = %00010101 ' enable PLVD. set trip point to 4.0V
        
        ' enable PLVD interrupt only when PLVD internal Vref is stable
        IF LVDCON.5 = 1 THEN PIE1.6 = 1 ' if stable, enable
        
        IF PIR1.6 = 1 THEN ' voltage <= 4.0V?
           HIGH PLVD_LED   ' yes. indicate voltage is <= 4.0V
           PIR1.6 = 0      ' clear int flag
        ELSE
           LOW PLVD_LED    ' else, indicate voltage is > 4.0V
        ENDIF
        LVDCON = 0         ' PLVD disabled before returning to sleep
        INTCON.6 = 0       ' peripheral ints disabled
        PIE1 = %00000000   ' low voltage detect int disabled
        RETURN
        
        END
    At 5 volts it wakes up around every 30mS, and trips PLVD at <= 4.0 V.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  3. #3
    Join Date
    Nov 2003
    Posts
    98


    Did you find this post helpful? Yes | No

    Default

    wow that's great Bruce, thanks a lot
    you got farther along than i did, but this was pretty much what i was thinking about
    doing

    i think i will go to a 0.1mf cap for about 3 seconds

    question
    do you see a way to distinguish this ULPWU interrupt from some other pin that may have caused wake up from SLEEP ?
    i don't

    also
    in your example code PROBE is for your scope and not directly related to the ULPWU pin, when you
    TOGGLE PROBE
    your comment says 'clear mismatch register'
    does this mean that writing to any pin will clear the mismatch ?
    i thought there was a mismatch bit for each pin ?

  4. #4
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    question
    do you see a way to distinguish this ULPWU interrupt from some other pin that may have
    caused wake up from SLEEP ? i don't
    If you had int on change enabled for more pins, you would need to read the port & look for
    a change immediately on wake up. Other interrupts would set the flag bit associated with
    that interrupt. I don't see any specific flag bit for ULPWU alone.

    also
    in your example code PROBE is for your scope and not directly related to the ULPWU pin, when
    you TOGGLE PROBE
    Yes. I just used this pin for the scope to see the timing when using different cap and resistor
    values.
    your comment says 'clear mismatch register' does this mean that writing to any pin will clear
    the mismatch ?
    A normal wake up on change requires you to read or write to the port to clear the
    mismatch condition. Then clear the interrupt flag bit.
    i thought there was a mismatch bit for each pin
    The only pin that affects wake up on change is the one that has this feature enabled, and
    is an input. There aren't any mismatch bits, but there are individual interrupt on change
    enable and disable bits in IOCA.

    You can remove the TOGGLE PROBE & INTCON.0 = 0 after. This gets taken care of before
    the sleep instruction.
    Last edited by Bruce; - 21st August 2007 at 10:49.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  5. #5
    Join Date
    Nov 2003
    Posts
    98


    Did you find this post helpful? Yes | No

    Default

    thanks again Bruce,

    I have one main input pin which needs to wake up the unit

    so what you are saying is that if it is NOT that pin when it comes out of SLEEP then by elimination it must be the ULPWU pin ?

    so then i would check the state of that pin, i.e. there is no bit that says which specific pin caused the wake up ? (i know there is not for the ULPWU)

    also sorry if i am being dense here but can you explain the mismatch deal some more?
    so if i read or write to *any* pin it will clear that mismatch?

  6. #6
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    I have one main input pin which needs to wake up the unit

    so what you are saying is that if it is NOT that pin when it comes out of SLEEP then by elimination it must be the ULPWU pin?
    Yes. Assuming you don't have anything else enabled that could cause the wake up from
    sleep.

    so then i would check the state of that pin, i.e. there is no bit that says which specific pin caused the wake up ? (i know there is not for the ULPWU)
    Yes.

    also sorry if i am being dense here but can you explain the mismatch deal some more?
    Sure. Say you have GPIO.1 configured for wake up. It's normally held high.

    When a switch or other external device pulls this pin low, you want the PIC to wake up.
    Wait for GPIO.1 to go high (by reading the port pin). Normally it will be held high by an
    external or internal pull-up.

    Once it's in the high state, enable wake up on change, then put the PIC to sleep.

    Once it goes low, there's a mismatch, and it wakes up. Wait for the pin to return high, and
    go through the process again. If the PIC enters sleep mode again, before the port pin was
    returned high, then it will wake up again once the pin returns high.

    so if i read or write to *any* pin it will clear that mismatch?
    Yep. As long as it's a pin on that port, but I normally read the whole port into a variable,
    then test for the bit in question.

    Testing several bits in a row leaves too much time for another one to change.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  7. #7
    Join Date
    Nov 2003
    Posts
    98


    Did you find this post helpful? Yes | No

    Default

    ok i think i have it all now
    my program isn't working right but i will figure it out now that i understand things a bit better

  8. #8


    Did you find this post helpful? Yes | No

    Exclamation Little clarification please

    Hi, I may be too late to ask this as this thread is few years old, but I will take my chances.
    I am trying to understand internal pull up on/off along with making sure pins are low before going to sleep.
    If I wish the pins to be low when the program starts is it ok to use the statement: OPTION_REG=0 : GPIO=0
    Since I am trying to understand internal pull up on/off so I will ask if there is any significance of OPTION_REG=128 over what I wrote above.

    Secondly,
    In the following code
    Code:
    Main:
        GPIO.0 = 1         ' set data latch on GPIO.0
        TRISIO.0 = 0       ' GPIO.0 = output (charging cap)
        PAUSEUS 24         ' charge cap for 24uS
        TRISIO.0 = 1       ' GPIO.0 = input to discharge cap
        IOCA.0 = 1         ' int on change enabled for GPIO.0
        INTCON = %00001000 ' global ints disabled, int on change enabled
        @ SLEEP            ' put PIC to sleep
        TOGGLE PROBE       ' indicate ULPWU wake up from sleep & clear mismatch
        INTCON.0 = 0       ' clear wake up on change int flag
        GOSUB TestVolts    ' go test for under voltage condition
        GOTO Main          ' not sure what this does...;o}
    Suppose my port (Lets say sensor attached to GPIO.1) is held low and I want PIC to wake up once it goes high, does what its suppose to do, and when it again goes low PIC goes to sleep.
    At what position in the code should I check to make sure port is LOW before PIC goes to sleep.

    As lets say I put "WHILE gpio.1:wend" before capacitor is charged in the main loop, I fear that port could go high again while capacitor is getting charged and pic will go to sleep with the port being high.

    If I put it after the capacitor charge statement, I fear the capacitor getting discharged while waiting for the port to go low which may take 1-2 seconds.

    Hope I can have some help over the two issues. Thanks a lot

  9. #9
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    If I wish the pins to be low when the program starts is it ok to use the statement: OPTION_REG=0 : GPIO=0
    Yes, but you might want to clear TRIS registers for any pin you want to be an output, and properly setup the
    WDA and WPUDA registers first.
    Since I am trying to understand internal pull up on/off so I will ask if there is any significance of
    OPTION_REG=128 over what I wrote above.
    Yes. Bit 7 in OPTION_REG enables or disables internal pull-ups/pull-downs. 1=disabled 0=enabled.

    The 12F635 has pull-ups or pull-downs. You write to WDA to select pull-ups or pull-downs, and WPUDA to
    enable or disable each one indidually.

    Secondly,
    In the following code
    Code:
    Code:
    Main:
        GPIO.0 = 1         ' set data latch on GPIO.0
        TRISIO.0 = 0       ' GPIO.0 = output (charging cap)
        PAUSEUS 24         ' charge cap for 24uS
        TRISIO.0 = 1       ' GPIO.0 = input to discharge cap
        IOCA.0 = 1         ' int on change enabled for GPIO.0
        INTCON = %00001000 ' global ints disabled, int on change enabled
        @ SLEEP            ' put PIC to sleep
        TOGGLE PROBE       ' indicate ULPWU wake up from sleep & clear mismatch
        INTCON.0 = 0       ' clear wake up on change int flag
        GOSUB TestVolts    ' go test for under voltage condition
        GOTO Main          ' not sure what this does...;o}
    Suppose my port (Lets say sensor attached to GPIO.1) is held low and I want PIC to wake up once it goes high,
    does what its suppose to do, and when it again goes low PIC goes to sleep. At what position in the code should
    I check to make sure port is LOW before PIC goes to sleep.
    Wait for the pin to go low, clear the interrupt flag bit, then SLEEP.

    As lets say I put "WHILE gpio.1:wend" before capacitor is charged in the main loop, I fear that port could go
    high again while capacitor is getting charged and pic will go to sleep with the port being high.

    If I put it after the capacitor charge statement, I fear the capacitor getting discharged while waiting for the
    port to go low which may take 1-2 seconds.
    If all you need is to wake-up on pin change with low power sleep, I wouldn't use internal pull-ups or pull-downs
    or the pin-change timed wake-up with ULPWU. If your sensor holds the pin low during idle periods, I would just
    let the sensor hold GPIO.1 low with interrupt-on-change enabled only for GPIO.1.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  10. #10


    Did you find this post helpful? Yes | No

    Question

    Hi Bruce, thanks for replying. This is how I am doing now:

    @ __CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_ON & _BOD_OFF & _CPD_ON & _IESO_OFF & _FCMEN_ON & _WUREN_OFF

    OSCCON = %01100000 ' Internal 4MHz select
    OPTION_REG = 0 ' internal pull-ups on/off according to value written on port
    CMCON0 = 7 ' disable comparator
    VRCON = 0 ' disable internal Vref
    GPIO = %00000000 ' LED off on boot
    TRISIO = %011001 ' GPIO.0 / 3,4= input, rest outputs
    PIR1 = 0 ' clear peripheral int flags
    PCON.5 = 1 ' ultra low power wakeup enabled
    Include "modedefs.bas"

    Main:
    GPIO.0= 1 ' set data latch on GPIO.0
    TRISIO.0= 0 ' GPIO.0 = output (charging cap)
    PAUSEUS 100 ' charge cap for 1
    TRISIO.0= 1 ' GPIO.0 = input to discharge cap
    IOCA.0= 1 ' int on change enabled for GPIO.0
    IOCA.4=1 ' int on change enabled for sensor @ GPIO.4
    while gpio.4 : wend
    INTCON= %00001000 ' global ints disabled, int on change enabled
    @ SLEEP ' put PIC to sleep
    GOSUB Test ' go test for under voltage condition AND send data if pin is made high by sensor
    GOTO Main

    Though the code is working fine for now, I would still like an opinion if the above way of doing this is the reliable way in long term.
    Thanks again

  11. #11
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    What exactly is it you're trying to do?
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  12. #12


    Did you find this post helpful? Yes | No

    Post

    I am trying to build an PIR sensor with PIC attached. My aim is to make PIC sleep and wake up like every few seconds or minutes (Which I know will be based on Res/Cap value on GPIO.0) and check for voltage OR wake up if the sensor makes its pin go high.

  13. #13
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    I see. If it's battery powered, then you don't want to waste current with internal pull-ups,
    and you don't want one on GPIO.0 connected to the internal ULPWU current sink.

    You want GPIO.0 to charge the cap through the series resistor, go to input, and let the cap
    discharge through the internal current sink. Kind of defeats the purpose if you have the pin
    held high via the internal pull-up.

    And, if your sensor outputs logic 1 when active, you should probably avoid the while GPIO.4
    since it's detecting something when GPIO.4 = 1.

    A better approach might be to read the port immediately on wake-up, find out which pin
    caused the interrupt on change wake up, then jump to a routine to handle it.

    Maybe something like this?
    Code:
    @ __CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_ON & _BOD_OFF & _CPD_ON & _IESO_OFF & _FCMEN_ON & _WUREN_OFF
    
    Include "modedefs.bas"
    
    OSCCON = %01100000 ' Internal 4MHz select
    OPTION_REG.7 = 1 ' turn off current hog internal pull-ups
    CMCON0 = 7 ' disable comparator
    VRCON = 0 ' disable internal Vref
    GPIO = %00000000 ' LED off on boot
    TRISIO = %011000 ' GPIO.0 / 3,4= input, rest outputs
    PIR1 = 0 ' clear peripheral int flags
    IOCA.0= 1 ' int on change enabled for GPIO.0
    IOCA.4=1 ' int on change enabled for sensor @ GPIO.4
    
    Main:
      IF GPIO.4 THEN HandlePIR ' goto PIR detect routine
      GPIO.0= 1 ' set data latch on GPIO.0
      TRISIO.0= 0 ' GPIO.0 = output (charging cap)
      PAUSEUS 100 ' charge cap for 1
      PCON.5 = 1 ' ultra low power wakeup enabled
      TRISIO.0= 1 ' GPIO.0 = input to discharge cap
      INTCON= %00001000 ' globals disabled, int on change enabled, clear wake up int flag bit
      @ SLEEP ' put PIC to sleep
      IF GPIO.4 THEN
        PCON.5 = 0 ' disable current sink on ultra low power wakeup
        GOTO HandlePIR ' if PIR sensor woke us up, handle it
      ELSE
        GOSUB Test ' go test for under voltage condition AND send data if pin is made high by 
      ENDIF
      GOTO Main
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  14. #14


    Did you find this post helpful? Yes | No

    Post Thanks a lot

    Thanks Bruce. I am going to take your advice as it exactly was my aim towards increasing battery life. Thanks again

  15. #15
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    You're welcome, and good luck. Have a look at this when you have time.

    It has several good tips on power savings for battery apps:
    http://ww1.microchip.com/downloads/e...doc/41200B.pdf

    And this one too: http://www.ac-limoges.fr/sti_ge/IMG/...C_nanowatt.pdf

    Also take a peek in the Electrical Specifications section of the data sheet.

    It shows current required for various peripherals, oscillators, etc..
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  16. #16


    Did you find this post helpful? Yes | No

    Default Current consumption?

    Hello Bruce, can you tell me what is the lowest current consumption you have achieved with 12F635?
    The minimum I have is 320uA, using external 4MHz resonator. which I don't know is a lot or reasonable? Thanks

  17. #17
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    I've never actually tested current consumption on anything I've done with a 12F635, but if
    you post your circuit & code I'm sure someone could help you get it below 320uA if it's
    sleeping during the time you're measuring current draw.
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

  18. #18


    Did you find this post helpful? Yes | No

    Default Hi Bruce

    Any chance I can send you a PM or email ?

  19. #19
    Join Date
    Jul 2003
    Posts
    2,405


    Did you find this post helpful? Yes | No

    Default

    Sure. tech at rentron.com
    Regards,

    -Bruce
    tech at rentron.com
    http://www.rentron.com

Similar Threads

  1. 16F684 Basic Functionality
    By munromh in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 30th September 2009, 20:28
  2. ICSP and 16F684
    By onaclov2000 in forum Schematics
    Replies: 4
    Last Post: - 5th March 2009, 17:31
  3. help with HPWM on 16f684
    By kimvellore in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 23rd May 2006, 08:05

Members who have read this thread : 0

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