Например TDA7294

Форум РадиоКот • Просмотр темы - CVAVR, режим SLEEP, прошу помощи.
Форум РадиоКот
Здесь можно немножко помяукать :)

Текущее время: Вс фев 22, 2026 21:28:32

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 7 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: CVAVR, режим SLEEP, прошу помощи.
СообщениеДобавлено: Ср апр 11, 2018 16:32:01 
Родился

Зарегистрирован: Чт авг 06, 2015 21:14:23
Сообщений: 15
Откуда: г. Саров
Рейтинг сообщения: 0
Приветствую! Не могу решить казалось бы простую задачу.
Имеем:
- Контроллер 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");
 }
}


Осциллограммы:
СпойлерИзображение Изображение Изображение Изображение Изображение Изображение


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CVAVR, режим SLEEP, прошу помощи.
СообщениеДобавлено: Ср апр 11, 2018 18:13:58 
Мудрый кот

Карма: 20
Рейтинг сообщений: 145
Зарегистрирован: Вс дек 25, 2016 08:34:54
Сообщений: 1849
Рейтинг сообщения: 0
Так как вы используете
Код:
#include <sleep.h>
то с начало выполняется команда
Код:
sleep_enable();
далее тот режим который вам нужен, к примеру
Код:
powersave();
, в файле sleep.h список доступных режимов, все мк заснул, после выхода из спячки начнется прерывание, после выхода из прерывания мк будет находится за командой
Код:
powersave();
, после этой команды следует указать строки
Код:
          //Запись пустого значения в регистр управления:
         TCCR2A=0x00;
         TCCR2B=0x01;
         //Ожидание завершения обновления TC2:
          while (ASSR & ((1 << TCN2UB)|(1 << OCR2AUB)|(1 << TCR2AUB)));                       
Без этой записи TCCR2A и TCCR2B будет иметь непредсказуемые значения.
Полный код
Спойлер
Код:
            sleep_enable();
            powersave();
          //Запись пустого значения в регистр управления:
         TCCR2A=0x00;
         TCCR2B=0x01;
         //Ожидание завершения обновления TC2:
          while (ASSR & ((1 << TCN2UB)|(1 << OCR2AUB)|(1 << TCR2AUB)));                       


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CVAVR, режим SLEEP, прошу помощи.
СообщениеДобавлено: Ср апр 11, 2018 18:58:08 
Родился

Зарегистрирован: Чт авг 06, 2015 21:14:23
Сообщений: 15
Откуда: г. Саров
Рейтинг сообщения: 0

Благодарю! Поэкспериментирую.
Но разве Таймер 2 не является асинхронным, чтобы какраз не зависеть от тактирования ядра? Я к тому, что каким образом изменяется настройка TCCR2A и TCCR2В до/после выхода в режим энергосбережения?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CVAVR, режим SLEEP, прошу помощи.
СообщениеДобавлено: Ср апр 11, 2018 22:59:43 
Поставщик валерьянки для Кота

Карма: 16
Рейтинг сообщений: 329
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Сообщений: 2222
Откуда: Tashkent
Рейтинг сообщения: 0
1. В асинхронном режиме настройки регистров обновляются после сброса флажков UB. Вне зависимоси от режимов энергосбережения. Процесс синхронизации асинхронных регистров для корректного доступа(например чтение) после обновления требует несколько тактов таймера Т2.
2. Внимательно изучите раздел Asynchronous Operation of Timer/Counter2 и следуйте описанным там алгоритмам работы с асинхронными регистами. Это позволит избежать полного зависания контроллера в режимах сна. В частности, необходимо выдерживать определённый интервал времени перед повторным уходом в глубокий сон.
3. В режиме сна кварцевый генератор отключается. При пробуждении генератор включается. На запуск требуется некоторое время, которое зависит от добротности резонатора, фузов и прочих факторов. Я бы ориентировался на интервал 10-100 миллисекунд для вч кварца. Вы выбрали частоту прерываний 32-128 раз в секунду. Таким образом, контроллер может просто не упевать отработать все произошедшие события.
4. Для максимального энергосбережения по причине п.3 лучше применять внутренний RC генератор.


Вернуться наверх
 
Эиком - электронные компоненты и радиодетали
Не в сети
 Заголовок сообщения: Re: CVAVR, режим SLEEP, прошу помощи.
СообщениеДобавлено: Чт апр 12, 2018 07:34:54 
Мудрый кот

Карма: 20
Рейтинг сообщений: 145
Зарегистрирован: Вс дек 25, 2016 08:34:54
Сообщений: 1849
Рейтинг сообщения: 0
Вот мои замеры потребления тока
Спойлервнутренний rc 8МГц делитель на 8
Схема BOD выключена, где-то потребляет 20mkA
active > 2000mkA
powerdown - 6mkA - Асинхронный тамер

внутренний rc 128кГц
active - 56mkA
powerdown - 5mkA - Асинхронный тамер
С тактированием от кварца 32768Гц
СпойлерИзображение
При желании можно получить потребляемый ток МК 18-56 мкА в активном режиме(не забудьте про регистр PRR, можно отрубить практически все модули кушающие питание).


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CVAVR, режим SLEEP, прошу помощи.
СообщениеДобавлено: Чт апр 12, 2018 11:33:51 
Друг Кота

Карма: 66
Рейтинг сообщений: 1025
Зарегистрирован: Пт мар 07, 2008 06:54:43
Сообщений: 4400
Откуда: Ижевск
Рейтинг сообщения: 0
В тексте не видно отключение аналогового компаратора. Уточню, регистр PRR0 отключает/включает тактирование периферийных модулей.
Потребление в POWER DOWN ATmega644PA стоящего на столе макета < 2мка, включая потребление стабилизатора MC78LC30HT1.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: CVAVR, режим SLEEP, прошу помощи.
СообщениеДобавлено: Чт апр 12, 2018 20:47:16 
Родился

Зарегистрирован: Чт авг 06, 2015 21:14:23
Сообщений: 15
Откуда: г. Саров
Рейтинг сообщения: 0
Dimon456 писал(а):
Полный код

Это помогло, но не до конца.
Столь низкое потребление это конечно хорошо. Но приведенная задача является лишь основой алгоритма. На самом деле всё гораздо обширнее и понижение тактовой частоты ниже 1 МГц не допустимо. Хотя раньше так же пробовал эти режимы и делал замеры :) Спасибо Вам за Ваши замеры.

Внимательно изучите раздел Asynchronous Operation of Timer/Counter2

Да, почему-то я этот раздел обошел стороной, но переход на RC частично решил проблему.

akl писал(а):
В тексте не видно отключение аналогового компаратора.

Да, он отключен. Текст приведен в "порезанном" виде. Так все нулевые инициализации от кодвизарда в оригинале конечно сохранены.

Про регистр PR посмотрю, спасибо за наводки.
Режим POWER DOWN к сожалению не могу использовать, так как он не пробуждается от таймера, а мне конкретно в этой поделке нада :)

На сегодняшний вечер благодаря Вашим советам итог таковой: Результат достигнут предложенными методами. На текущем этапе прошивка работает корректно. Не исключаю, что по мере её нарастания могут всплыть проблемы с энергосбережением.
Благодарю за помощь всех откликнувшихся!


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 7 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 25


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y