Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ATmega48PA не выводится из сна Таймером2 в асинхронном режиме
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
bvn123
Здравствуйте,

не получается вывести МК из спящего режима.

ATmega48PA,
Тактирование микроконтроллера выбрано установкой Fuses от внутреннего RC-генератора 8МГц (проверил, тактирование МК от 8МГц есть)

кварц 32768Гц подключен к TOSC1,2 и тактирует Таймер2 в асинхронном режиме.
Переполнение Таймера2 раз в 0,5с изменяет состояние на контакте МК, для индикации к контакту подключен светодиод.

Если команда _SLEEP() заблокирована, Таймер2 в асинхронном режиме работает, светодиод мигает с расчетной частотой.

МК не пробуждается Таймером2 в асинхронном режиме, если выполнена команда _SLEEP().

В то же время МК пробуждается, если заблокировать асинхронный режим (убрать команду ASSR=(1<<AS2)) - тогда светодиод мигает очень часто (на таймер2 поступает частота 8МГц/1024, кроме того, чтобы видеть мигание, приходится и в TCNT2 грузить 216 вместо 16-ти)

Т.е., проблема возникает при одновременном использовании SLEEP и асинхронного режима Таймера2,
можно сказать, отдельно они работают.

То же написал на ассемблере в AVR Studio с тем же результатом.

В чем ошибка?

CODE
//===========Листинг:=========//
#include <iom48PA.h>
#include <ina90.h>

#pragma vector=TIMER2_OVF_vect //KBD & Indication
__interrupt void TIMER2_OVF(void)
{ SMCR=0;
TCNT2=256-16;
PIND=1<<PD4;}

void main()
{ SP=RAMEND;
DDRD=(1<<PD4);

//Запрет работы WDT - без изменений из описания ATmega48PA
_CLI();
_WDR();
MCUSR &= ~(1<<WDRF);
WDTCSR |= (1<<WDCE) | (1<<WDE);
WDTCSR = 0x00;

//Инициализация Таймера2
ASSR=(1<<AS2); //асинхронный режим: кварц 32768Гц на TOSC1,2 -> Таймер2
TIMSK2=(1<<TOIE2); //прерывание переполнения Таймера2 разрешить
TCNT2=256-16; //при Ftosc2=32768 /1024 = 32Гц это 0.5с срабатывания таймера
TCCR2B=(1<<CS22) | (1<<CS21) | (1<<CS20); // Pre2=1024, Ftimer2 = 32 Гц

_SEI(); //Разрешить прерывания

while (1)
{
SMCR= (0<<SM2) | (1<<SM1) | (1<<SM0) | (1<<SE); // 0000 0111 - разрешить Power Save sleep mode
_SLEEP(); //перевести МК в спящий режим
}
}
Александр1
Возможно, ничего нового, но выполните пошаговую отладку Вашей ассемблерной версии и посмотрите работает ли Т2 в SLEEP режиме и какие у Т2 настройки.
Так лучше поймете тонкости работы МК.
bvn123
может, у кого-нибудь есть работающий фрагмент с асинхронным тактированием таймера2 и Power Save sleep mode для ATmega48p/88p/168p?

===
об отладке:
в отладчике IAR for AVR команда _SLEEP() не отрабатывается,

в AVR Studio 4.19, после установки ASSR.AS2, команды записи в TCNT2 и TCCR2 не приводят к изменению состояний в соотв.окошках этих регистров в окне I/O View, но при этом устанавливаются биты, сигнализирующие о занятости этих регистров в ASSR: ASSR.TCN2UB и ASSR.TCR2BUB;
запись в TIMSK2 вызывает нормальную установку соотв. флажка,

перемещение команды установки ASSR.AS2 за блок команд инициализации TCNT2, TCCR2 и TIMSK2 приводит к установке соотв. флажков этих регистров в IO View, но не к нормальной работе,
к тому же в писании сказано, что этого делать не следует: "When the value of AS2 is changed, the contents of TCNT2, OCR2A, OCR2B, TCCR2A and TCCR2B might be corrupted."

в Atmel Studio 6.2 то же самое, но медленнее работает

сомневаюсь, что астудио7 обеспечит корректную отладку: в шестой версии пропадали простые возможности отладки, которые работали в 4-й.

И на сайте атмел страница, где можно задать вопрос, приглашает зайти позже.
bvn123
нашел решение:
попробовал подождать, не сбросятся ли флаги:
Цитата
в окне I/O View, но при этом устанавливаются биты, сигнализирующие о занятости этих регистров в ASSR: ASSR.TCN2UB и ASSR.TCR2BUB;


чтобы не ждать повторно сброса флага ASSR.TCN2UB при записи в TCNT2 в обработчике Timer2_Ovf, можно
-дать таймеру отсчитывать все 256 импульсов до переполнения, тогда в обработчике в него не потребуется что-либо записывать, а секундный или 2-секундный интервал выбирать Prescaler-ом - делить не на 1024, а на 64, например.
-или работать с прерыванием по совпадению состояния таймера с заранее заданным (CTC)

CODE
//===========Листинг:=========//
#include <iom48PA.h>
#include <ina90.h>

#pragma vector=TIMER2_OVF_vect //KBD & Indication
__interrupt void TIMER2_OVF(void)
{ SMCR=0;
PIND=1<<PD4;}

void main()
{ SP=RAMEND;
DDRD=(1<<PD4);

//Запрет работы WDT - без изменений из описания ATmega48PA
_CLI();
_WDR();
MCUSR &= ~(1<<WDRF);
WDTCSR |= (1<<WDCE) | (1<<WDE);
WDTCSR = 0x00;

//Инициализация Таймера2
TIMSK2=(1<<TOIE2);
ASSR=(1<<AS2); //асинхронный режим: кварц 32768Гц на TOSC1,2 -> Таймер2
TCNT2=0; //при входной частоте Ftim2=32768 /64 = 512Гц и деление на 256 таймером2 - интервал 0.5с
TCCR2B=(1<<CS22) | (0<<CS21) | (0<<CS20); // Pre2=64, Ftimer2 = 512 Гц
while(ASSR & 0x11);

_SEI();

while (1)
{
SMCR= (0<<SM2) | (1<<SM1) | (1<<SM0) | (1<<SE); // 0000 0111 Power Save sleep mode
_SLEEP();
}
}
}
rx3apf
Насколько мне помнится, при выполнении обработчика прерываний таймера 2 в асинхронном режиме нельзя быстро выходить из обработчика, нужен по крайней мере один цикл 1/32768 (можно сделать запись в регистры, которые получают состояние "занято" после записи и опрашивать бит занятости - как бит сбросится, из обработчика можно выходить). Асинхронный режим таймера 2 в AVR реализован исключительно коряво...
bvn123
спасибо, если будет неустойчиво работать, добавлю задержку
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.