bvn123 0 22 декабря, 2016 Опубликовано 22 декабря, 2016 (изменено) · Жалоба Здравствуйте, не получается вывести МК из спящего режима. 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 с тем же результатом. В чем ошибка? //===========Листинг:=========// #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(); //перевести МК в спящий режим } } Изменено 22 декабря, 2016 пользователем bvn123 [codebox] для длинного кода, [code] - для короткого! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
АлександрК 0 22 декабря, 2016 Опубликовано 22 декабря, 2016 · Жалоба Возможно, ничего нового, но выполните пошаговую отладку Вашей ассемблерной версии и посмотрите работает ли Т2 в SLEEP режиме и какие у Т2 настройки. Так лучше поймете тонкости работы МК. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bvn123 0 22 декабря, 2016 Опубликовано 22 декабря, 2016 · Жалоба может, у кого-нибудь есть работающий фрагмент с асинхронным тактированием таймера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 0 22 декабря, 2016 Опубликовано 22 декабря, 2016 · Жалоба нашел решение: попробовал подождать, не сбросятся ли флаги: в окне I/O View, но при этом устанавливаются биты, сигнализирующие о занятости этих регистров в ASSR: ASSR.TCN2UB и ASSR.TCR2BUB; чтобы не ждать повторно сброса флага ASSR.TCN2UB при записи в TCNT2 в обработчике Timer2_Ovf, можно -дать таймеру отсчитывать все 256 импульсов до переполнения, тогда в обработчике в него не потребуется что-либо записывать, а секундный или 2-секундный интервал выбирать Prescaler-ом - делить не на 1024, а на 64, например. -или работать с прерыванием по совпадению состояния таймера с заранее заданным (CTC) //===========Листинг:=========// #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 0 22 декабря, 2016 Опубликовано 22 декабря, 2016 · Жалоба Насколько мне помнится, при выполнении обработчика прерываний таймера 2 в асинхронном режиме нельзя быстро выходить из обработчика, нужен по крайней мере один цикл 1/32768 (можно сделать запись в регистры, которые получают состояние "занято" после записи и опрашивать бит занятости - как бит сбросится, из обработчика можно выходить). Асинхронный режим таймера 2 в AVR реализован исключительно коряво... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bvn123 0 22 декабря, 2016 Опубликовано 22 декабря, 2016 · Жалоба спасибо, если будет неустойчиво работать, добавлю задержку Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться