Menu

How to put a uC to sleep mode

G. C.
2024-02-21
2024-02-21
  • G. C.

    G. C. - 2024-02-21

    Hi,
    I am trying to experiment with low power modes, and using the Voltage failure interrupt I would like to put the mcu at sleep.. Down here the part of code used, basic and resulting assembler. The event of the HLVD module happens, the interrupt generated, but the SLEEP command does not get executed..
    I can't find reference to such instruction on the Help, so I am not sure if the syntax is correct.
    I tried upper and lower case, no way , the CPU absorbs few mA instead of some tens of uA.
    Suggestions?
    Rgds,
    GC


    'BASIC
    On Interrupt VoltageFail call Interrupt_Handler

    sub Interrupt_Handler

    if  LVDIF=1 then
    
        PORTB=0
        LVDIF=0
        SLEEP '** this is not putting the uC in sleep mode
    
    end if
    

    end sub

    Here is the assembler generated:

    INTERRUPT_HANDLER
    btfss PIR2,LVDIF,ACCESS
    bra ENDIF12
    clrf PORTB,ACCESS
    bcf PIR2,LVDIF,ACCESS
    SLEEP
    nop
    ENDIF12
    return

     
  • Anobium

    Anobium - 2024-02-21

    Ummm.

    What chip?
    Does the ISR get called?
    Does sleep work outside of the ISR?
    Does the LVDIF require any specific config?
    Does the On interrupt enable the correct Enabling bit in the correct register?

     
  • G. C.

    G. C. - 2024-02-21

    Chip is the 18LF24J11.
    For all the other questions you made, except for the work outside the ISR, the answer is yes:
    On interrupt works, the HLVD event fires it, portB is cleared, but then if I measure the current absorbtion from a backup battery, I see some mAmps, as if the sleep mode is not initiated.

    I will try to simplify the overall program and see if sleep works outside the ISR. But just want to make sure the simple "SLEEP" syntax is correct or it's required some special character like # or additional stuff like #asm etc.. Can't find a reference in the Help section about the SLEEP instruction to make sure I write it correctly.

     
  • G. C.

    G. C. - 2024-02-21

    Done some tests..

    if I put the sleep instruction just after the config stuff and varaible declaration etc, it works.
    So I tought it was the use inside the ISR that was not possible.
    Then I changed the ISR removing the sleep instruction and made it to set a flag that the interrupt was served (i.e used a variable set to a known value like pwr_down =15); I would then check into the do-forever-loop if pwr_down=15 then sleep..
    But also inside the loop the sleep instruction does not get executed.
    Very strange behaviour..

     
  • Anobium

    Anobium - 2024-02-21

    Set a flag in the ISR, and SLEEP in the main loop.

     
  • G. C.

    G. C. - 2024-02-21

    That's what I said I did in my previous post..

    Down here is the flow of the program at present. The sleep instruction works only if put outside ISR and outside the main Do-Loop. Can't understand why.


    config & vars etc
    ..
    if I put SLEEP here, it works and gets executed
    ..

    Do forever

    ... other stuff to do forever...

        'reset the Watchdog Timer
        ClrWDT
    
        'if a flag of low voltage is set, put CPU to sleep
        if pow_down=15 then 
            pow_down=0
            sleep           'also here does not get executed
        end if
    

    loop

    sub Interrupt_Handler

    if  LVDIF=1 then
    
        PORTB=0
        LVDIF=0
        pow_down=15
    
    end if
    

    end sub

     
  • G. C.

    G. C. - 2024-02-21

    What happens when the Watchdog has reset from Sleep the CPU? The execution starts from the beginning of program like the one of a Master Reset, or it returns to the Do-Loop?
    I may leave the sleep instruction just before the do-loop starts in such case .. If the pwr_down variable in RAM is preserved during the Sleep (provided the battery backup is still powering the CPU), then the if pwr_down=15 then sleep put before the do-loop could be the solution.
    I'll give it a try. But still do not understand why the sleep does not get executed in ISR/Do-loop.

     
  • G. C.

    G. C. - 2024-02-21

    Sorry, I realized immediately that it's not possible.. Just discard the last post.. Executing a DIM instruction will put to zero the flag anyway, and my problem is to check during the normal operations that if there is a power failure, the cpu must go in sleep, and preserve only WDT/RTC data and oscillators..

     

Log in to post a comment.