独闷闷网

 找回密码
 立即注册
搜索
查看: 5388|回复: 3
打印 上一主题 下一主题
收起左侧

[原创] 使用stc15掉电唤醒专用定时器和掉电模式时有哪三个容易犯错的问题?已解答。

[复制链接]
跳转到指定楼层
楼主
发表于 2015-1-15 10:35:34 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 jianhong_wu 于 2015-1-15 10:37 编辑

问:
使用stc15掉电唤醒专用定时器时有哪三个容易犯错的问题?

鸿哥-深圳:
我最近恰好在用到stc15w204s这款单片机,发现有以下三个容易出错的问题:
(1)WKTCH寄存器第7位(从第0位开始)是掉电唤醒专用定时器的使能位,但是只能用赋值语句,不能用或的语句给这个位置1.比如只能用WKTCH=0x80而不能用WKTCH=WKTCH|0x80。经过仔细查看数据手册后发现了原因:

而WKTCH=0x80语句只是写操作,而WKTCH=WKTCH|0x80的“WKTCH|0x80”包含了读操作,本质相当于WKTCH=WKTCH_CNT|0x80 。
比如你想给定时器赋值0x1056,并且要使能定时器,那么只要WKTCL=0x56和WKTCH=90即可。而不能WKTCL=0x56,WKTCH=0x10,WKTCH=WKTCH|0x80。

(2)看到stc官方厂家提供的范例是只要在初始化函数里直接设置WKTCL和WKTCH就可以了,但是实际上,我发现每次在PCON |= 0x02进入掉电模式前都要设置一下WKTCL和WKTCH才能正常用。比如:
  1.       WKTCL = 0x56;    //每次进入掉电模式前都要设置一下这两个定时器才能正常用
  2.       WKTCH = 0x90;                    
  3.       PCON |= 0x02;            //MCU进入掉电模式
  4.       _nop_();
  5.       _nop_();
复制代码

(3)stc官方资料推荐每次执行PCON |= 0x02进入掉电模式后必须后面紧跟两个_nop_()语句,而鸿哥一开始没有遵循这个原则,结果悲剧了,当然这种奇怪的问题可能跟具体的程序有关,网友不一定能自己测试让故障重现。
比如正确的做法是:
  1.       PCON |= 0x02;            //MCU进入掉电模式
  2.       _nop_();
  3.       _nop_();
  4.       a=c; //某标志设置的语句
复制代码

而不应该
  1.       PCON |= 0x02;            //MCU进入掉电模式
  2.       a=c; //某标志设置的语句,这里不推荐这样做,否则有可能引起一些难以言说的奇怪问题。
  3.       _nop_();
  4.       _nop_();
复制代码


乐于分享,勇于质疑!
沙发
发表于 2015-2-11 23:18:53 | 只看该作者
您好!您说得对!估计用WKT的人不多,所以大家暂时不了解您的帖子的价值!
前几天一个程序需要借助于WKT超低功耗设计,居然卡在WKT上。只要或运算置位WKTEN,延时时间永远是最大量程。后来改为赋值就好了,但赋值方法先组装数据,使能WKTEN与赋初值搅在一起,不方便看清开发者的意图,所以我前几天简单改了一下:
               //采用逻辑运算使能WKTEN"位",无论初值如何,永远是最大量程了,一定找不着北啦!
              WKTCL=615;                                                  //WKT量程0.3秒
              WKTCH=(615>>8)|0x80;                                //用赋值法置初值同时置位WKTEN,不可逻辑运算置位WKTCH.7
              PCON |=0x02;                                                //停机无耗WKT延时
              _nop_();                                                        //唤醒不进已屏蔽的中断
              _nop_();
             .............
         但我还为一个似乎很初级的问题抓狂,看来不初级?程序要在WKT唤醒之前由外中断唤醒,5秒量程的WKT仅是最后的补救唤醒措施。外中断唤醒后要计算掉电了多久,但是无论如何程序的表现都不正常,最后不得已仿真(IAP15F61S2仿真),发现几个变量值都不对,哪又出问题了?请您指点一下:
    PowerDownTime=(WKTCH&~0x80)<<8+WKTCL;  
//实际读的是[WKTCH_CNT,WKTCL_CNT]而非[WKTCH,WKTCL],但_CNT从7FFF开始计数,是否应屏蔽最高位的1才正确?
    PowerDownTime++;                                        //既然已屏蔽_CNT最高位的1,需修正才为真实计数值
    WktFreq=DBYTE[0xF8]<<8+DBYTE[0xF9];        //WKT专用振荡器16分频后用于WKT计数,在[F8,F9]中
    WktFreq>>=4;                                                //16分频
//根据掉电时长叠加新状态后恢复设备或端口,奇怪的是WktFreq总是0!
          if(PowerDownTime<0.2*WktFreq)                //若掉电时长0~0.2秒视为干扰
            {                               
             ... ...                                                    //仅恢复掉电前端口状态
            }                                               
          else
            if(PowerDownTime<1*WktFreq)                  //若掉电时长0.2~1秒,
                  {
                    RED_BAK=!RED_BAK;
                    RED =RED_BAK;                                //加入新状态恢复端口
                  }
            else
                  if(PowerDownTime<1.5*WktFreq)        //若掉电时长1~1.5秒,视为长或短掉电的间隔
                    {
                     ... ...                                            //仅恢复掉电前端口状态
                    }                                       
                  else
                    {        //若掉电时长1.5~5秒(5秒是WKT唤醒的边界)
                         GREEN_BAK=!GREEN_BAK;
                         GREEN=GREEN_BAK;                         //加入新状态恢复端口
                    }
      ... ... ... ... ... ... ...
乐于分享,勇于质疑!
板凳
发表于 2015-2-11 23:25:15 | 只看该作者
反复测试(IAP15F61S2仿真)发现:PowerDownTime、WktFreq的值都不正常,真实奇怪。
乐于分享,勇于质疑!
地板
 楼主| 发表于 2015-2-12 15:52:02 | 只看该作者
kingtop 发表于 2015-2-11 23:18
您好!您说得对!估计用WKT的人不多,所以大家暂时不了解您的帖子的价值!
前几天一个程序需要借助于WKT ...

这些问题其实我也不懂什么原因。我也是上个月第一次用stc15,现在都忘得差不多了。
乐于分享,勇于质疑!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|独闷闷网 ( 粤ICP备12007667号-2 )

GMT+8, 2024-4-26 12:06 , Processed in 0.173688 second(s), 19 queries .

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