I am working with an ATMEGA8 in a standalone application and need to get it into one of the different sleep modes.
I am trying not to use the avr/sleep.h library as I frankly don’t understand what it is doing. Plus, it is a good opportunity to learn the code and microcontroller better.
In the code snippet below I am trying to put the part into ADC Noise Reduction mode:
MCUCR |= (1<<SE) | (1<<SM1);
In tutorials I have read, they mention a “sleep command”. However, in inspecting sleep.h in the avr library, I don’t see any assembly code representing such a command so I am confused.
I don't see any change in behavior in my program. In otherwords, it does not behave as if it actually is in powderdown mode as it is still performing ADC conversions, responding to inputs, etc.
I apologize for derailing this a little, but why is that code put into a do{} while(0) loop. That looks really odd to me and I'm sure there's a real good reason why it's done there. Isn't that the same as just executing the line of code once? Or is that just to add one more instruction (the comparison) so it doesn't return before it falls asleep?
Delta_G:
I apologize for derailing this a little, but why is that code put into a do{} while(0) loop. That looks really odd to me and I’m sure there’s a real good reason why it’s done there. Isn’t that the same as just executing the line of code once? Or is that just to add one more instruction (the comparison) so it doesn’t return before it falls asleep?
It’s a “standard” convention to do that in macros so that it behaves as much like a function as possible. Without the do{}while(0), you could get errors like:
#define bar(x) y = x; y++;
if (foo) bar(3);
which would unconditionally execute y++, and if you do
#define bar(x) {y = x; y++;}
if (foo) bar(3);
then this would be legal:
#define bar(x) {y = x; y++;}
if (foo) bar(3)
… etc. All to get around the overhead of a function call that would be optimized out anyway.
Anyway, I’m no expert in sleeping and I can’t spend the time to look up the registers. However, remember that the chip will wake up whenever there’s an interrupt, and if you keep timer0 enabled, there’s an interrupt every 1ms to update the millia() timer. You also have to think about what you want to take up the chip, and if that’s getting triggered prematurely.
Delta_G:
I apologize for derailing this a little, but why is that code put into a do{} while(0) loop. That looks really odd to me and I'm sure there's a real good reason why it's done there. Isn't that the same as just executing the line of code once? Or is that just to add one more instruction (the comparison) so it doesn't return before it falls asleep?
It's a "standard" convention to do that in macros so that it behaves as much like a function as possible. Without the do{}while(0), you could get errors like:
#define bar(x) y = x; y++;
if (foo) bar(3);
which would unconditionally execute y++, and if you do
#define bar(x) {y = x; y++;}
if (foo) bar(3);
then this would be legal:
#define bar(x) {y = x; y++;}
if (foo) bar(3)
... etc. All to get around the overhead of a function call that would be optimized out anyway.
Anyway, I'm no expert in sleeping and I can't spend the time to look up the registers. However, remember that the chip will wake up whenever there's an interrupt, and if you keep timer0 enabled, there's an interrupt every 1ms to update the millia() timer. You also have to think about what you want to take up the chip, and if that's getting triggered prematurely.
Ahh, I didn't realize the chip wakes on an interrupt. That may explain what is occurring.