我遇到一个ATMega2560的奇怪情况。
我想通过进入PowerDown模式来节省电量。在这种模式下,只有少数事件可以唤醒它。
在USART1上,我有一个外部控制器,该控制器将消息发送到AVR。 但是当使用USART1时,我不能使用INT2和INT3进行外部中断(= CPU不会唤醒)。
所以我有一个主意,就是在进入掉电模式之前立即禁用USART1,并启用INT2作为外部中断。
伪代码:
UCSR1B &= ~(1<<RXEN1); //Disable RXEN1: let AVR releasing it
DDRD &= ~(1<<PD2); //Make sure PortD2 is an input - we need it for waking up
EIMSK &= ~(1<<INT2); //Disable INT2 - this needs to be done before changing ISC20 and ISC221
EICRA |= (1<<ISC20)|(1<<ISC21); //Rising edge on PortD2 will generate an interrupt and wake up the AVR from PowerDown
EIMSK |= (1<<INT2); //Now enable INT2
//Sleep routine
cli();
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
在INT2的ISR中,我将所有内容都更改回USART1。
伪:
ISR(INT2_vect) {
EIMSK &= ~(1<<INT2); //Disable INT2 to be able to use it as USART1 again
UCSR1B=(1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1);
}
但是,似乎要花很长时间才能使USART1再次正常工作。 (从PowerDown唤醒后)开始时有太多错误位。
这是多么骇人听闻? 有什么合理的方法可以使更改更快?
主要思想是将“ RX”端口设置为可以唤醒CPU的中断,然后立即将其改回USART并尽快对其进行处理。
PS:为此,我确实必须使用相同的引脚,没有其他可用的选项。因此,不能将使用其他别针的指导作为答案。
答案 0 :(得分:1)
掉电模式禁用振荡器,因此唤醒后必须等待稳定的振荡器。
请查看第51页的数据表:
When waking up from Power-down mode, there is a delay from the wake-up condition occurs until the wake-upbecomes effective. This allows the clock to restart and become stable after having been stopped. The wake-upperiod is defined by the same CKSEL Fuses that define the Reset Time-out period, as described in “ClockSources” on page 40.
假设您使用高速陶瓷振荡器,则您必须等待258个时钟周期(请参阅第42页的表10-4
)。
您可以使用待机模式。如果使用外部振荡器,则CPU进入待机模式,该模式与掉电模式相同,但振荡器不会停止。此外,您可以将Power Reduction Register
设置为其他节电选项。
另一种选择是使用扩展待机模式,该模式与省电模式相同。此模式禁用振荡器,但振荡器会在六个时钟周期内唤醒。