Пробуждение AVR по внешнему прерыванию с последующим немедленным считыванием USART

У меня странная ситуация с ATMega2560.

Я хочу сэкономить электроэнергию, перейдя в режим PowerDown. В этом режиме есть только несколько событий, которые могут разбудить его.

На USART1 у меня есть внешний контроллер, который отправляет сообщения на AVR. Но когда используется USART1, я не могу использовать INT2 и INT3 для внешнего прерывания (= ЦП не просыпается).

Так что у меня возникла идея отключить USART1 прямо перед переходом в режим PowerDown и включить 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();

В ISR INT2 меняю все обратно на 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 на прерывание, которое может разбудить ЦП, а затем немедленно изменить его обратно на USART и обработать его как можно скорее.

PS: Мне действительно нужно использовать для этой цели тот же пин, другого доступного варианта нет. Так что указание на использование других контактов не будет принято в качестве ответа.


person Daniel    schedule 07.07.2019    source источник


Ответы (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 тактовых циклов, если вы используете высокоскоростной керамический генератор (см. Таблицу 10-4 на странице 42).

Вы можете использовать режим ожидания. Если вы используете внешний осциллятор, ЦП переходит в режим ожидания, который идентичен режиму пониженного энергопотребления, но осциллятор не останавливается. Кроме того, вы можете установить Power Reduction Register для дополнительных опций энергосбережения. Другой вариант - использовать расширенный режим ожидания, который идентичен режиму энергосбережения. Этот режим отключает осциллятор, но он просыпается через шесть тактов.

person Kampi    schedule 08.07.2019
comment
Хотя проблема заключалась скорее в неправильной настройке прерывания, этот ответ имеет дополнительную ценность. - person Daniel; 08.07.2019