Atmel Studio simulator fails to turn off BOD while sleep

Go To Last Post
3 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Hi.

I want to disable BOD (Brown-Out Detection) while MCU (ATmega328P) enters sleep mode. Here is my code:

C:

sleep_enable();
MCUCR |= (1<<BODS)|(1<<BODSE);
MCUCR &= ~(1<<BODSE);
sleep_cpu();
sleep_disable();

Assembly:

    in buffer , SMCR        ;buffer = r16
    ori buffer , (1<<SE)
    out SMCR , buffer
    in buffer , MCUCR
    ori buffer , (1<<BODS)|(1<<BODSE)
    out MCUCR , buffer
    in buffer , MCUCR
    andi buffer , ~(1<<BODSE)
    out MCUCR , buffer
    sleep
    in buffer , SMCR
    andi buffer , ~(1<<SE)
    out SMCR , buffer

As I read in datasheet, these codes should work but when I simulate the program, this happens in both:

  1. SE is set.
  2. Just BODSE is set. (BODS doesn't change! Why?! )
  3. BODSE is cleared.
  4. Entered sleep mode.

Even if I set BODS manually (click on it in I/O window) it is cleared automatically after 3 cycles. While datasheet says if you clear BODSE within 3 cycles after setting both BODS and BODSE, BODS remains set.

Is there any problem in my code? or it is simulator's fault?

Also: Should I clear BODS after MCU waked from sleep?

OH, I forgot this: Happy new year!laugh

Slow and Steady!

Last Edited: Wed. Jan 1, 2020 - 05:10 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What's wrong with sleep_bod_disable()?

https://www.nongnu.org/avr-libc/user-manual/group__avr__sleep.html

 

Some devices have the ability to disable the Brown Out Detector (BOD) before going to sleep. This will also reduce power while sleeping. If the specific AVR device has this ability then an additional macro is defined: sleep_bod_disable(). This macro generates inlined assembly code that will correctly implement the timed sequence for disabling the BOD before sleeping. However, there is a limited number of cycles after the BOD has been disabled that the device can be put into sleep mode, otherwise the BOD will not truly be disabled. Recommended practice is to disable the BOD (sleep_bod_disable()), set the interrupts (sei()), and then put the device to sleep (sleep_cpu()), like so:

#include <avr/interrupt.h>
#include <avr/sleep.h>
...
set_sleep_mode(<mode>);
cli();
if (some_condition)
{
    sleep_enable();
    sleep_bod_disable();
    sei();
    sleep_cpu();
    sleep_disable();
}
sei();

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Thu. Jan 2, 2020 - 06:53 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'll try that but what about assembly?

Again: "Is there any problem in my code? or it is simulator's fault?"

EDIT: sleep_bod_disable() result is the same.

Slow and Steady!

Last Edited: Sat. Jan 4, 2020 - 09:12 AM