深入浅出一书中P174中的小错误
在深入浅出一书中P174有一个进入休眠模式的语句:SMCR |= 0X01; asm("SELEEP"); 其中的 asm("SELEEP");使用ICC无法编译通过,建议改成: asm("sleep");另外请教一下作者进入其它休眠模式的写法。我用片内RC震荡。是否可以进入掉电模式? 实测无法进入休眠,不知道哪里搞错了。使用 asm("sleep"); 电流也没下降。望解惑。
附源程序:
#include <stdio.h>
#include <iom48v.h>
#include <macros.h>
#include <math.h>
void main (void)
{
SMCR |= (1<<SE);
SMCR |= (1<<SM1); //掉电模式
while(1)
{}
} 本帖最后由 Gorgon_Meducer 于 2012-8-20 17:24 编辑
首先,谢谢你的反馈。
用片内振荡器可以进入Power-Down模式。
没有asm("sleep");肯定不会进入任何休眠模式的。
Sleep函数的编写方式参考下面的例子,注意,请查阅数据手册,把c_chSleepLevel[]这个表格替换成正确的形式
static void set_sleep_mode(uint8_t chLevel)
{
/*! \brief sleep mode select bits
*! MODE SM2SM1 SM0
*! idle 0 0 0
*! ADC Noise Reduction0 0 1
*! Power-down 0 1 1
*! standy by 1 0 0
*/
static FLASH uint8_t c_chSleepLevel[] = {
((0x00 << SM0) | _BV(SE)),
((0x01 << SM0) | _BV(SE)),
((0x02 << SM0) | _BV(SE)),
((0x03 << SM0) | _BV(SE)) };
uint8_t chSleepMode = c_chSleepLevel /* | _BV(SE)*/;
SAFE_ATOM_CODE(
MCUCR = (MCUCR & ~(_BV(SM0) | _BV(SM1) | _BV(SE))) | chSleepMode;
ENABLE_GLOBAL_INTERRUPT(); //! enable interrupt
__sleep(); //! sleep
//!< clear sleep control register
MCUCR &= ~(_BV(SM0) | _BV(SM1) | _BV(SE));
)
}
几个上面代码中遇到的宏的原型:
#ifndef __volatile__
#define __volatile__
#endif
# define ENABLE_GLOBAL_INTERRUPT() __asm__ __volatile__ ("sei")
# define DISABLE_GLOBAL_INTERRUPT() __asm__ __volatile__ ("cli")
#define GLOBAL_INTERRUPT_ENABLED() ((0 != (SREG & 0x80)) ? true : false)
//! \brief The safe ATOM code section macro
# define SAFE_ATOM_CODE(__CODE) {\
volatile uint8_t chSREG = SREG;\
DISABLE_GLOBAL_INTERRUPT();\
__CODE;\
SREG = chSREG;\
}
//! \brief Exit from the safe atom operations
# define EXIT_SAFE_ATOM_CODE() SREG = chSREG;\
本帖最后由 ldhavr 于 2012-8-21 09:08 编辑
可能我没说清楚,我想问的是mega48,不是16.主要是跟着您的深入浅出从mega48开始学的。您P174中ADC噪声抑制模式的代码应该是进入空闲模式的代码是么?万分感谢您白忙之中的回复谢谢。
本帖最后由 Gorgon_Meducer 于 2012-8-21 09:32 编辑
ldhavr 发表于 2012-8-21 08:58 static/image/common/back.gif
可能我没说清楚,我想问的是mega48,不是16.主要是跟着您的深入浅出从mega48开始学的。您P174中ADC噪声抑制 ...
和M48/16没什么关系吧?你自己看数据手册了么?
给你的代码是一个通用代码,可以安全的进入任何休眠模式。
我不记得你说的页数是哪个章节的,如果是外中断,那可能就是进入IDLE模式,如果是ADC例子中的代码应该是要进入噪声抑制模式的,只有在噪声抑制模式下才能启动ADC采样。
如果是M48,把寄存器更换成SMCR就可以了,之前我没有注意,让你造成了误解。这也是为什么我让你一定要看一下数据手册。除了寄存器不同外,操作都是一样的,当然支持的休眠模式可能略微不同,这种情况下更换我代码中的那个表就可以了。
我提供的这个代码是按照官方推荐的方式来编写的,里面体现了一些细节,比如和中断的协调,如何防止死锁,如何防止误触发sleep等等。
页:
[1]