span42 发表于 2010-7-17 17:41:13

求助:mega16异步32768HZ时钟T2,可以进省电模式,时间却不累加,附代码,望高人帮忙瞅瞅哪里

整了一下午了,头都大了,问题:断电后进去省电模式,期间通过小电池供电,电流约12uA,加电唤醒后发现时间还是显示断电时的值。大伙帮忙看看哪出问题了,谢谢
代码:

void timer2_ovf_isr(void)                   //timer2溢出中断 500ms中断
{
TCNT2 = 0x80; //reload counter value
if(second500ms==False) second500ms=True;
else second500ms=False;
clock();                   //时间累加函数
if(PIND&0x04)             //如果断电
{
CLI();
PORTA = 0x00;
DDRA= 0x00;
PORTB = 0x00;
DDRB= 0x00;
PORTC = 0x00;
DDRC= 0x00;
PORTD = 0x00;
DDRD= 0x00;

BATTARY_F = True;         

MCUCR=BIT(SE);
MCUCR|=0x70;
SEI();
asm("sleep");          //进入省电模式
}
else if(BATTARY_F)   //上电后
{
init_devices();
BATTARY_F = False;
}

}

void clock (void)
{
    if (second500ms)
   {
      if (++second>=60)
                {   second=0;
                      if (++minute>=60)
                         {
                                minute=0;
                                if (++hour>=24)
                                    {
                                        hour=0;
                                    }
                           }
                  }
   }
}

span42 发表于 2010-7-18 09:36:18

没人懂吗

mcu5i51 发表于 2010-7-18 10:01:45

好像是中断中处理的问题,请确保处理时间超过1个RCT周期,或判断寄存器刷新完成在睡;
另外你好像是从51过来的,使用CTC模式定时精度会很好的。

mcu5i51 发表于 2010-7-18 10:06:18

T/C2 工作于异步模式时要考虑如下几点:
• 警告:在同步和异步模式之间的转换有可能造成TCNT2、OCR2 和TCCR2 数据的损
毁。安全的步骤应该是:
1. 清零OCIE2 和TOIE2 以关闭T/C2 的中断
2. 设置AS2 以选择合适的时钟源
3. 对TCNT2、OCR2 和TCCR2 写入新的数据
4. 切换到异步模式:等待TCN2UB、OCR2UB 和TCR2UB 清零
5. 清除T/C2 的中断标志
6. 需要的话使能中断
• 振荡器最好使用32.768 kHz手表晶振。给TOSC1 提供外部时钟,可能会造成T/C2 工
作错误。系统主时钟必须比晶振高4 倍以上。
• 写TCNT2,OCR2和TCCR2时数据首先送入暂存器,两个TOSC1时钟正跳变后才锁
存到对应到的寄存器。在数据从暂存器写入目的寄存器之前不能执行新的数据写入
操作。3 个寄存器具有各自独立的暂存器,因此写TCNT2 并不会干扰OCR2 的写
操作。异步状态寄存器ASSR 用来检查数据是否已经写入到目的寄存器。
• 如果要用T/C2 作为MCU 省电模式或扩展Standby 模式的唤醒条件,则在TCNT2,
OCR2A和TCCR2A更新结束之前不能进入这些休眠模式,否则MCU可能会在T/C2设
置生效之前进入休眠模式。这对于用T/C2 的比较匹配中断唤醒MCU 尤其重要,因
为在更新OCR2 或TCNT2 时比较匹配是禁止的。如果在更新完成之前(OCR2UB
Bit 7 6 5 4 3 2 1 0
– – – – AS2 TCN2UB OCR2UB TCR2UB ASSR
读/ 写R R R R R/W R R R
初始值0 0 0 0 0 0 0 0
123
ATmega16(L)
2466G–AVR–10/03
为0)MCU 就进入了休眠模式,那么比较匹配中断永远不会发生, MCU 也永远无法
唤醒了。
• 如果要用T/C2作为省电模式或扩展Standby模式的唤醒条件,必须注意重新进入这些
休眠模式的过程。中断逻辑需要一个TOSC1 周期进行复位。如果从唤醒到重新进入
休眠的时间小于一个TOSC1 周期,中断将不再发生,器件也无法唤醒。如果用户怀
疑自己程序是否满足这一条件,可以采取如下方法:
1. 对TCCR2、TCNT2 或OCR2 写入合适的数据
2. 等待ASSR 相应的更新忙标志清零
3. 进入省电模式或扩展Standby 模式
• 若选择了异步工作模式,T/C2 的 32.768 kHz 振荡器将一直工作,除非进入掉电模式
或 Standby 模式。用户应该注意,此振荡器的稳定时间可能长达1 秒钟。因此,建
议用户在器件上电复位,或从掉电/Standby 模式唤醒时至少等待1 秒钟后再使用
T/C2。同时,由于启动过程时钟的不稳定性,唤醒时所有的T/C2 寄存器的内容都可
能不正确,不论使用的是晶体还是外部时钟信号。用户必须重新给这些寄存器赋值。
• 使用异步时钟时省电模式或扩展Standby 模式的唤醒过程:中断条件满足后,在下一
个定时器时钟唤醒过程启动。也就是说,在处理器可以读取计数器的数值之前计数
器至少又累加了一个时钟。唤醒后MCU 停止4 个时钟,接着执行中断服务程序。中
断服务程序结束之后开始执行SLEEP 语句之后的程序。
• 从省电模式唤醒之后的短时间内读取TCNT2 可能返回不正确的数据。因为TCNT2 是
由异步的TOSC 时钟驱动的,而读取TCNT2 必须通过一个与内部I/O 时钟同步的寄
存器来完成。同步发生于每个TOSC1 的上升沿。从省电模式唤醒后I/O 时钟重新激
活,而读到的TCNT2 数值为进入休眠模式前的值,直到下一个TOSC1 上升沿的到
来。从省电模式唤醒时TOSC1 的相位是完全不可预测的,而且与唤醒时间有关。因
此,读取TCNT2 的推荐序列为:
1. 写一个任意数值到OCR2 或TCCR2
2. 等待相应的更新忙标志清零
3. 读TCNT2
• 在异步模式下,中断标志的同步需要3 个处理器周期加一个定时器周期。在处理器可
以读取引起中断标志置位的计数器数值之前计数器至少又累加了一个时钟。输出比
较引脚的变化与定时器时钟同步,而不是处理器时钟。

span42 发表于 2010-7-18 20:00:01

回复【2楼】mcu5i51 学途浪子
-----------------------------------------------------------------------
谢谢你

先前用ctc模式试的,一小时能快十几s,普通模式还好点,一天4s,现在还是睡眠,唤醒不正常,睡眠后有复位的现象

zl_123 发表于 2014-7-15 10:54:33

mark                                          
页: [1]
查看完整版本: 求助:mega16异步32768HZ时钟T2,可以进省电模式,时间却不累加,附代码,望高人帮忙瞅瞅哪里