求救:m88在省电模式下无法用定时器2异步中短唤醒
小弟做一时钟程序:TOSC1和TOSC2外接32.768K晶振。T2设为异步工作模式。发现该程序在正常模式(非省电)和空闲模式下都能正常进入T2溢出中断。但SMCR一被设置为省电模式就无法再进入中断了。但m88的数据手册上提到在省电模式下定时2异步工作模式是可以执行的,并且T2的异步中断是可以唤醒MCU的。小弟现将程序写在此处请高手指点小弟错在那里,又或者小弟对睡眠的方式理解的不正确请指点。#pragma vector=TIMER2_OVF_vect
__interrupt void timer2_isr(void) //T2中断服务子程序
{TCNT2=0xE0;
if(second<59)
{second++;
}
else
{second=0;
if(minute<59)
{minute++;
}
else
{ minute=0;
if(hour<23)
hour++;
else
hour=0;
}
}
}
main()//主程序
{timer2_init();//T2初始化
SMCR=0x06;//设置为省电模式(设为00时可以进入中断)
SMCR|=(1<<SE);//睡眠使能(关闭时也可进入中断)
__enable_interrupt();//开中断
__sleep();//睡眠
while(1)
{;
}
}
//////////////////////////////////////////////////////////////////////
void timer2_init(void)// T2初始化设置
{TCCR2A=0x00;
ASSR=1<<AS2;//AS2为1即设置为异步时钟
TCNT2=0xE0;//定时时间为1秒(定时/计数寄存器)
TCCR2B=(1<<CS22)|(1<<CS21)|(1<<CS20);//预分频设置为1024
TIMSK2=1<<TOIE2;//T2中断使能
}
////////////////////////////////////////////////////////////////////// 难道没人会吗 mark 楼主回了没,我现在也遇到这个问题了,进入省电模式后,T2就挂了,有木有有木有会的,拜谢, mark 本帖最后由 lnso 于 2015-12-1 14:26 编辑
没试过m88的异步时钟 我用32K的同步时钟跑过:也是这个 POWER-SAVE 模式,用 TIM2 的 CTC 模式(OCF2A 中断)来退出休眠,这种方式下没有问题。
细看代码发现出问题的都是在异步时钟下,看了手册,发现异步时钟下访问 TCNT2、OCR2X、TCCR2X 要等待,怀疑此处有问题:
进一步手册已讲明,AS2开启后,所有这些寄存器的数值都写在缓存里,等异步时钟走几步再更新。
然而在 TIM2 的初始化代码里,明显没有看到等待的语句。
猜测出问题的系统都是用 MCU 内部 RC 时钟(远大于32K),仅在休眠时靠 32K 外部晶振再次唤醒 MCU。
如果是这样的话,最差情况 TIM2 的控制寄存器(例如TCCR2B)在写入的数值还没生效前就已进入睡眠了,
此后同步时钟停了,TCCR2B 的写入也就再也不生效了,这也就解释了为什么同步时钟一停,定时器就不好用了。
因而可以大胆推断,即使是 IDLE 类似模式,TIM2 的寄存器生效也是发生在 MCU 进入休眠以后的。
-----------------------------------------------------------------------------------------------------------------------------------------
以上是瞎分析,建议:
1. 原始代码不动,仅在初始化 TIM2 以后加一个 ms 级延时,看是否故障排除,以验证上述猜测的正确性。
2. 删除上述延时(测试用),改为等待状态:AS2开启后,只要有写入 TCNT2、OCR2X、TCCR2X,均添加等待(T....UB 之类)。
3. 好好看手册,关于 Asynchronous Operation of Timer/Counter2 一节,补漏。 我用过,可以唤醒,如楼上所说,不知是进入休眠前要等待很长时间还是初始化后要等待,忘记了,你自己试下即可
页:
[1]