搜索
bottom↓
回复: 3

深入浅出一书中P174中的小错误

[复制链接]

出0入0汤圆

发表于 2012-8-20 16:50:36 | 显示全部楼层 |阅读模式
在深入浅出一书中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)            
  {}
}

出0入296汤圆

发表于 2012-8-20 17:18:35 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2012-8-20 17:24 编辑


首先,谢谢你的反馈。
用片内振荡器可以进入Power-Down模式。
没有asm("sleep");肯定不会进入任何休眠模式的。

Sleep函数的编写方式参考下面的例子,注意,请查阅数据手册,把c_chSleepLevel[]这个表格替换成正确的形式

  1. static void set_sleep_mode(uint8_t chLevel)
  2. {
  3.     /*! \brief sleep mode select bits
  4.      *!        MODE                 SM2  SM1 SM0
  5.      *!        idle                 0    0   0
  6.      *!        ADC Noise Reduction  0    0   1
  7.      *!        Power-down           0    1   1
  8.      *!        standy by            1    0   0
  9.      */
  10.     static FLASH uint8_t c_chSleepLevel[] = {
  11.                             ((0x00 << SM0) | _BV(SE)),
  12.                             ((0x01 << SM0) | _BV(SE)),
  13.                             ((0x02 << SM0) | _BV(SE)),
  14.                             ((0x03 << SM0) | _BV(SE)) };
  15.     uint8_t chSleepMode = c_chSleepLevel[chLevel] /* | _BV(SE)*/;
  16.    
  17.     SAFE_ATOM_CODE(
  18.         MCUCR = (MCUCR & ~(_BV(SM0) | _BV(SM1) | _BV(SE))) | chSleepMode;
  19.         ENABLE_GLOBAL_INTERRUPT();      //! enable interrupt
  20.         __sleep();                      //! sleep
  21.         //!< clear sleep control register
  22.         MCUCR &= ~(_BV(SM0) | _BV(SM1) | _BV(SE));  
  23.     )
  24.    
  25. }
复制代码
几个上面代码中遇到的宏的原型:

  1. #ifndef __volatile__
  2. #define __volatile__
  3. #endif

  4. # define ENABLE_GLOBAL_INTERRUPT()      __asm__ __volatile__ ("sei")
  5. # define DISABLE_GLOBAL_INTERRUPT()     __asm__ __volatile__ ("cli")

  6. #define GLOBAL_INTERRUPT_ENABLED()     ((0 != (SREG & 0x80)) ? true : false)

  7. //! \brief The safe ATOM code section macro
  8. # define SAFE_ATOM_CODE(__CODE)     {\
  9.         volatile uint8_t chSREG = SREG;\
  10.         DISABLE_GLOBAL_INTERRUPT();\
  11.         __CODE;\
  12.         SREG = chSREG;\
  13.     }

  14. //! \brief Exit from the safe atom operations
  15. # define EXIT_SAFE_ATOM_CODE()          SREG = chSREG;\
复制代码

出0入0汤圆

 楼主| 发表于 2012-8-21 08:58:38 | 显示全部楼层
本帖最后由 ldhavr 于 2012-8-21 09:08 编辑

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

   

出0入296汤圆

发表于 2012-8-21 09:24:39 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2012-8-21 09:32 编辑
ldhavr 发表于 2012-8-21 08:58
可能我没说清楚,我想问的是mega48,不是16.主要是跟着您的深入浅出从mega48开始学的。您P174中ADC噪声抑制 ...


和M48/16没什么关系吧?你自己看数据手册了么?
给你的代码是一个通用代码,可以安全的进入任何休眠模式。
我不记得你说的页数是哪个章节的,如果是外中断,那可能就是进入IDLE模式,如果是ADC例子中的代码应该是要进入噪声抑制模式的,只有在噪声抑制模式下才能启动ADC采样。

如果是M48,把寄存器更换成SMCR就可以了,之前我没有注意,让你造成了误解。这也是为什么我让你一定要看一下数据手册。除了寄存器不同外,操作都是一样的,当然支持的休眠模式可能略微不同,这种情况下更换我代码中的那个表就可以了。

我提供的这个代码是按照官方推荐的方式来编写的,里面体现了一些细节,比如和中断的协调,如何防止死锁,如何防止误触发sleep等等。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-2 10:53

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表