ldhavr 发表于 2012-8-20 16:50:36

深入浅出一书中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:18:35

本帖最后由 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 08:58:38

本帖最后由 ldhavr 于 2012-8-21 09:08 编辑

可能我没说清楚,我想问的是mega48,不是16.主要是跟着您的深入浅出从mega48开始学的。您P174中ADC噪声抑制模式的代码应该是进入空闲模式的代码是么?万分感谢您白忙之中的回复谢谢。

   

Gorgon_Meducer 发表于 2012-8-21 09:24:39

本帖最后由 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]
查看完整版本: 深入浅出一书中P174中的小错误