| Форум РадиоКот https://radiokot.ru/forum/ |
|
| CVAVR, режим SLEEP, прошу помощи. https://radiokot.ru/forum/viewtopic.php?f=57&t=154129 |
Страница 1 из 1 |
| Автор: | kaddet [ Ср апр 11, 2018 16:32:01 ] |
| Заголовок сообщения: | CVAVR, режим SLEEP, прошу помощи. |
Приветствую! Не могу решить казалось бы простую задачу. Имеем: - Контроллер ATMega 644PA (так же проверялось на 644А) - Часовой кварц на тактирование таймера 2 - Контроллер тактируется кварцем 8МГц, выставлен фьюз CKDIV8, т.е. тактовая 1МГц. - Режим энергосбережения: Power-save - Компилятор CodeVisionAVR 2.05.3 и 3.12 Необходимо: - Максимальное энергосбережение (длительное батарейное питание). - Получать 3 прерывания OCR2A, OCR2B, T2OVF с частотой 32Гц. Контроллер проснулся по OCR2A, дернул одной ногой, уснул. Проснулся по OCR2B, дернул другой ногой, уснул. Проснулся по T2OVF, изменил счетчик, уснул. Реализация: - Т2 работает постоянно, прерывание OVF включено постоянно. Делитель частоты кварца PCK/2. Получаем прерывания 128 раз в секунду. Ставим счетчик на переменной от 0 до 3. На каждое 3е значение счетчика разрешаем прерывания OCR2A и OCR2B. В остальные значения счетчика прерывания по совпадению запрещены. Проблема: - Не срабатывают прерывания OCR2A и OCR2B, или следуют сразу после T2OVF, т.е. не в свое время. Если закомментировать #asm("sleep"), то всё работает как нужно. Попытки исправить: - Менял фьюзы, не уверен что выставлено правильно ибо понимаю не до конца. Стоит кварц на 8Мгц, но так же фьюз делителя на 8, т.е. тактовая 1 МГц. Соответственно какой фьюз выставить, на 1 или 8Мгц? Пробовал CKSEL3..0 111, 110,101. Разницы не заметил. Далее CKSEL0 и SUT1..0. Пробовал разные варианты. По даташиту CKSEL нужно ставить в 1, т.к. у меня crystal oscillator, а не ceramic resonator. При выборе ceramic потребление ниже, зато с применением SLEEP прерывания OCR2A и OCR2B “колбасятся” влево-вправо. Видимо таймер останавливается или сбивается. Не понимаю как такое может происходить. При изменении на crystal стабильность на порядок лучше, но теряются или некорректно отрабатываются прерывания OCR2A и OCR2B. - Пытался сбрасывать флаги прерываний OCR2A и OCR2B. В результате они могли просто не появляться или же опять срабатывать не постоянно, а через раз. - Менял режим энергосбережения. В IDLE таких проблем нет. Если закомментировать SLEEP то всё так же работает как надо. Работаю в железе. Протеус не использую. Результат смотрю осцилографом. Читал даташит. Каких-то явных ограничений не увидел. Контроллер должен просыпаться от любого из прерываний Т2. Сильно прошу не пинать, программирование не моя сфера, но есть желание разобраться. И прежде чем написать сюда много раз читал документацию и форумы. Явного решения не увидел. Да и мало кто с энергосбережением заморачивался. Отвечать смогу только по вечерам, так как на работе интернета нет и все коммуникации запрещены… Приму любые наставления, исправления и попытки помочь разобраться. Исходный код: СпойлерFuses: SUT0=0, CKDIV8=0. Остальные не установлены.Код: #include <mega644a.h> #include <delay.h> #include <sleep.h> unsigned char c_on=0; // Счетчик входа а прерывания T2OVF // Timer2 output compare interrupt service routine interrupt [TIM2_COMPA] void timer2_compa_isr(void) { PORTC.2=1; // Контролирую вход в прерывание delay_us(50); // Различаю прерывание А PORTC.2=0; } // Timer2 output compare interrupt service routine interrupt [TIM2_COMPB] void timer2_compb_isr(void) { PORTC.2=1; // Контролирую вход в прерывание delay_us(150); // Различаю прерывание B PORTC.2=0; } // Timer2 overflow interrupt service routine interrupt [TIM2_OVF] void timer2_ovf_isr(void) { c_on++; if (c_on>=4) c_on=0; if (c_on==3){ TIFR2 =(1<<OCF2B) | (1<<OCF2A) | (1<<TOV2); // Сброс флага о предыдущих прерываниях TIMSK2=(1<<OCIE2B) | (1<<OCIE2A) | (1<<TOIE2); // Разрешить прерывания OCR2A OCR2B OCR2OVF } else { TIMSK2=0x01; // Запретить прерывания OCR2A OCR2B } PORTC.2=1; // Контролирую вход в прерывание delay_us(100); // Различаю прерывание OVF PORTC.2=0; } void main(void) { // Crystal Oscillator division factor: 1 #pragma optsize- CLKPR=0x80; CLKPR=0x00; #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif // Port C initialization // Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=0 State2=0 State1=T State0=T PORTC=0x00; DDRC=0x0C; // Timer/Counter 2 initialization // Clock source: Crystal on TOSC1 pin // Clock value: PCK2 // Mode: Normal top=0xFF // OC2A output: Disconnected // OC2B output: Disconnected ASSR=0x20; TCCR2A=0x00; TCCR2B=0x01; TCNT2=0x00; OCR2A=0x57; OCR2B=0x62; // Timer/Counter 2 Interrupt(s) initialization TIMSK2=0x01; /* Prepare the sleep in POWER-SAVE mode*/ SMCR |= (1<<SE) | (0<<SM2) | (1<<SM1) | (1<<SM0); // Global enable interrupts #asm("sei") while (1) { PORTC.3=1; // Для контроля входа в SLEEP PORTC.3=0; #asm("sleep"); } } Осциллограммы: |
|
| Автор: | Dimon456 [ Ср апр 11, 2018 18:13:58 ] |
| Заголовок сообщения: | Re: CVAVR, режим SLEEP, прошу помощи. |
Так как вы используете Код: #include <sleep.h> то с начало выполняется команда Код: sleep_enable(); далее тот режим который вам нужен, к примеру Код: powersave(); , в файле sleep.h список доступных режимов, все мк заснул, после выхода из спячки начнется прерывание, после выхода из прерывания мк будет находится за командой Код: powersave(); , после этой команды следует указать строки Код: //Запись пустого значения в регистр управления: Без этой записи TCCR2A и TCCR2B будет иметь непредсказуемые значения.TCCR2A=0x00; TCCR2B=0x01; //Ожидание завершения обновления TC2: while (ASSR & ((1 << TCN2UB)|(1 << OCR2AUB)|(1 << TCR2AUB))); Полный код СпойлерКод: sleep_enable(); powersave(); //Запись пустого значения в регистр управления: TCCR2A=0x00; TCCR2B=0x01; //Ожидание завершения обновления TC2: while (ASSR & ((1 << TCN2UB)|(1 << OCR2AUB)|(1 << TCR2AUB))); |
|
| Автор: | kaddet [ Ср апр 11, 2018 18:58:08 ] |
| Заголовок сообщения: | Re: CVAVR, режим SLEEP, прошу помощи. |
Благодарю! Поэкспериментирую. Но разве Таймер 2 не является асинхронным, чтобы какраз не зависеть от тактирования ядра? Я к тому, что каким образом изменяется настройка TCCR2A и TCCR2В до/после выхода в режим энергосбережения? |
|
| Автор: | uk8amk [ Ср апр 11, 2018 22:59:43 ] |
| Заголовок сообщения: | Re: CVAVR, режим SLEEP, прошу помощи. |
1. В асинхронном режиме настройки регистров обновляются после сброса флажков UB. Вне зависимоси от режимов энергосбережения. Процесс синхронизации асинхронных регистров для корректного доступа(например чтение) после обновления требует несколько тактов таймера Т2. 2. Внимательно изучите раздел Asynchronous Operation of Timer/Counter2 и следуйте описанным там алгоритмам работы с асинхронными регистами. Это позволит избежать полного зависания контроллера в режимах сна. В частности, необходимо выдерживать определённый интервал времени перед повторным уходом в глубокий сон. 3. В режиме сна кварцевый генератор отключается. При пробуждении генератор включается. На запуск требуется некоторое время, которое зависит от добротности резонатора, фузов и прочих факторов. Я бы ориентировался на интервал 10-100 миллисекунд для вч кварца. Вы выбрали частоту прерываний 32-128 раз в секунду. Таким образом, контроллер может просто не упевать отработать все произошедшие события. 4. Для максимального энергосбережения по причине п.3 лучше применять внутренний RC генератор. |
|
| Автор: | Dimon456 [ Чт апр 12, 2018 07:34:54 ] |
| Заголовок сообщения: | Re: CVAVR, режим SLEEP, прошу помощи. |
Вот мои замеры потребления тока Спойлервнутренний rc 8МГц делитель на 8Схема BOD выключена, где-то потребляет 20mkA active > 2000mkA powerdown - 6mkA - Асинхронный тамер внутренний rc 128кГц active - 56mkA powerdown - 5mkA - Асинхронный тамер Спойлер![]() |
|
| Автор: | akl [ Чт апр 12, 2018 11:33:51 ] |
| Заголовок сообщения: | Re: CVAVR, режим SLEEP, прошу помощи. |
В тексте не видно отключение аналогового компаратора. Уточню, регистр PRR0 отключает/включает тактирование периферийных модулей. Потребление в POWER DOWN ATmega644PA стоящего на столе макета < 2мка, включая потребление стабилизатора MC78LC30HT1. |
|
| Автор: | kaddet [ Чт апр 12, 2018 20:47:16 ] |
| Заголовок сообщения: | Re: CVAVR, режим SLEEP, прошу помощи. |
Dimon456 писал(а): Полный код Это помогло, но не до конца. Столь низкое потребление это конечно хорошо. Но приведенная задача является лишь основой алгоритма. На самом деле всё гораздо обширнее и понижение тактовой частоты ниже 1 МГц не допустимо. Хотя раньше так же пробовал эти режимы и делал замеры Внимательно изучите раздел Asynchronous Operation of Timer/Counter2 Да, почему-то я этот раздел обошел стороной, но переход на RC частично решил проблему. akl писал(а): В тексте не видно отключение аналогового компаратора. Да, он отключен. Текст приведен в "порезанном" виде. Так все нулевые инициализации от кодвизарда в оригинале конечно сохранены. Про регистр PR посмотрю, спасибо за наводки. Режим POWER DOWN к сожалению не могу использовать, так как он не пробуждается от таймера, а мне конкретно в этой поделке нада На сегодняшний вечер благодаря Вашим советам итог таковой: Результат достигнут предложенными методами. На текущем этапе прошивка работает корректно. Не исключаю, что по мере её нарастания могут всплыть проблемы с энергосбережением. Благодарю за помощь всех откликнувшихся! |
|
| Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|



