Например TDA7294

Форум РадиоКот • Просмотр темы - ATTiny13 - помогите разобраться со sleep-mode!
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Чт апр 18, 2024 03:18:44

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


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



Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Сб дек 01, 2012 07:48:39 
Родился

Зарегистрирован: Вс авг 26, 2012 17:46:05
Сообщений: 17
Рейтинг сообщения: 0
Доброго времени суток всем!
Нужна Ваша помощь с простой задачкой - МК, на одном пине (PB3) которого - кнопка, на другом (PB4) - светодиод.
Замыкаем кнопку -светодиод загорается на 4 секунды. Потом гаснет, независимо от состояния кнопки. А главное - пока кнопка не нажата - МК должен пребывать в глубоком сне и не жрать почти ни капли тока.


Собственно код:

Код:
#include <avr/io.h>      // инициализация портов ввода-вывода МК
#include <avr/wdt.h>      // здесь организована работа с ватчдогом
#include <avr/sleep.h>      // здесь описаны режимы сна
#include <avr/interrupt.h>                 // работа с прерываниями
#include <avr/delay.h>      // описание программных задержек

// Обработчик прерываний
ISR (WDT_vect)
{
   WDTCR |=_BV(WDE);   // разрешаем прерывания по ватчдогу, иначе будет резет!
}


// Основная программа
int main()
{

   // Инициализация порта кнопки (PB3)
   DDRB &=~_BV(PB3);      // ставит в DDRB в бит PB3 - "0" (инициирует его работу как "вход")
   PORTB |= _BV(PB3);      // ставит в PORTB в бит PB3 - "1" (при замыкании пина на землю она становится нулем, при размыкании - еденицей)
   
   // Условие включения светодиода по нажатию кнопки
   if((PINB & (1 << PB3)) == 0)
      {        
      // Иницализация порта светодиода (PB4)
      DDRB |= _BV(PB4);    // Указатель пина
      PORTB |= _BV(PB4);   // Выставить на PB4 - "1"
      _delay_ms (4000);   // Задержка
      PORTB &= ~_BV(PB4);   // Выставить на PB4 - "0"
               
            // Инициализация цикла контроля ложного включения светодиода
            while ((PINB & (1 << PB3)) == 0)
            {   // пока кнопка нажата (после завершения цикла включения светодиода)...
               PORTB &= ~_BV(PB4);   // ...светодиод не горит (до отключения, и последующего включения кнопки)
            }


};
      
      // Инициализация ватчдога   
      wdt_reset();         // сброс
      wdt_enable(WDTO_120MS);                 // разрешение ватчдога раз в 120мс
      WDTCR |= _BV(WDE);      // разрешение прерываний по ватчдогу (иначе будет резет)!
      sei();            // разрешение прерывания

      // Инициализация режима сна
      set_sleep_mode (SLEEP_MODE_PWR_DOWN);
      while(1)
      {
         sleep_enable();   // разрешение режима сна
         sleep_cpu();   // активация режима сна
      }
}



Я понимаю что код - не ахти (с МК вожусь считанные месяцы, через раз, по выходным), но в протеусе - работает как надо. А вот в реале - светодиод моргает непрерывно, пока нажата кнопка. Помогите пожалуста разобраться - где косяк?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Сб дек 01, 2012 11:32:49 
Поставщик валерьянки для Кота

Карма: 16
Рейтинг сообщений: 329
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Сообщений: 2222
Откуда: Tashkent
Рейтинг сообщения: 0
1. Кнопка на вход прерывания по низкому уровню. Только прерывание низким уровнем разбудит МК из глубокого сна.
2. В векторе прерывания по низкому уровню отключаем IRQ по уровню чтоб постоянно не молотил, переключим на "по фронту" или вообще отключим если будем потом мониторить статус кнопок софтварно. Запускаем антидребезг кнопки(например таймер).
3. Когда отработал антидребезг реагируем на события(включаем светомузыку, лампочки, биперы и делаем что надо).
4. Ждем/ничего не делаем пока нажата кнопка.
5. Когда отпустили кнопку ждем антидребезг и снова разрешаем прерывание по низкому уровню, усыпляем проц.

Для прерывания по низкому уровню вход дожен быть подтянут резистором ввех, кнопка замыкает на землю. Можно параллельно кнопке малый кондер добавить чтоб от наводок всяких избавиться.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Сб дек 01, 2012 11:44:23 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
а кнопку будут держать дольше 4 секунд или не обязательно?

_________________
Ставим плюсы: )


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Сб дек 01, 2012 12:05:44 
Родился

Зарегистрирован: Вс авг 26, 2012 17:46:05
Сообщений: 17
Рейтинг сообщения: 0
ibiza11 писал(а):
а кнопку будут держать дольше 4 секунд или не обязательно?

В том то и дело что дольше. Поэтому у меня такой кривоватый код в итоге получился.

Дребезг мне кажется тут маловероятен - подтягивающий резистор имеется, а кнопка - на самом устройстве там оптопара, и проверял я его зажигая светодиод оптопары от батарейки, то есть как мне представляется - там все достаточно стабильно.

А насчет IRQ - честно сказать не просвещен пока. В свое время удачно получилось режим глубокого сна организовать именно на Тини13 - power down. В этом режиме там почти все обесточено в МК, только независимо тактируемы вочдог фурычит. Вот от него то я и плясал. Поэтому и прерывания все - по вачдогу. Благо в Тини он несколько более широкими возможностями наделен, нежели в Мегах.


Вернуться наверх
 
Организация питания на основе надежных литиевых аккумуляторов EVE и микросхем азиатского производства

Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Сб дек 01, 2012 12:12:30 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
тогда вообще зачем здесь микроконтроллер?)))
одновибратор на 4 секунды, а кнопка включает питание одновибратора)))
если обязательно с микроконтроллером, то можно аналогично кнопкой рулить питанием тиньки13, а в программе написать тупо:
Код:
LedOn();
delay_ms(4000);
LedOff();
while(1);
:write:

_________________
Ставим плюсы: )


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Сб дек 01, 2012 12:57:35 
Родился

Зарегистрирован: Вс авг 26, 2012 17:46:05
Сообщений: 17
Рейтинг сообщения: 0
ibiza11 писал(а):
тогда вообще зачем здесь микроконтроллер?)))


Товарищь, который меня попросил это сделать как раз с одновибратора и начинал, но у него что-то там не срослось. Вот он слезно попросил меня попробовать на МК. Плюс - тот самый режим энергосбережения. Схема по его задумке должна вечность пахать от батарейки.

Код:
LedOn();
delay_ms(4000);
LedOff();
while(1);


вообще у меня практически это и сделано. Но что-то не работает оно как надо.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Сб дек 01, 2012 13:06:00 
Поставщик валерьянки для Кота
Аватар пользователя

Карма: 21
Рейтинг сообщений: 143
Зарегистрирован: Сб фев 21, 2009 13:11:40
Сообщений: 1900
Откуда: Москва
Рейтинг сообщения: 0
Цитата:
то можно аналогично кнопкой рулить питанием тиньки13

_________________
Ставим плюсы: )


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Сб дек 01, 2012 13:46:36 
Родился

Зарегистрирован: Вс авг 26, 2012 17:46:05
Сообщений: 17
Рейтинг сообщения: 0
Будить МК по внешнему прерыванию у меня пока получается только из режима Idle. И этот вариант я оставил на крайний случай, если так не выйдет ничего.
Из Power-Down так будить вообще не получится (если я правильно все понял), так как все лишнее обесточено. Остается только ватчдог.
Да уже и бог бы с ним - просто интересно, в чем у меня-то проблема? В целях повышения образованности, так сказать, хотелось бы разобраться. Тем более что в симуляции все как надо работает...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Сб дек 01, 2012 17:52:36 
Друг Кота
Аватар пользователя

Карма: 74
Рейтинг сообщений: 607
Зарегистрирован: Ср дек 24, 2008 09:58:58
Сообщений: 3715
Рейтинг сообщения: 0
Медали: 3
Мявтор 1-й степени (1) Мявтор 2-й степени (1) Мявтор 3-й степени (1)
ATTINY13 можно будить из powerdown либо watchdog-ом как Вы делаете, либо низким уровнем, но только на входе INT0, т.к. только при этом низкий уровень отслеживается асинхронно. Первый подход приводит к гораздо большему токопотреблению, по ДШ около 6 мкА при питании от 5в.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Вс дек 02, 2012 09:11:10 
Родился

Зарегистрирован: Вс авг 26, 2012 17:46:05
Сообщений: 17
Рейтинг сообщения: 0
Попробовал переделать на прерывание по INT0.
Вот что получилось:
Код:
#include <avr/io.h>         // инициализация портов ввода-вывода МК
#include <avr/sleep.h>      // здесь описаны режимы сна
#include <avr/interrupt.h>   // работа с прерываниями
#include <avr/delay.h>      // описание программных задержек

// Обработчик прерываний
SIGNAL(SIG_INTERRUPT0)  // Прерывание по низкому уровню на PB1
{           

   PORTB |= _BV(PB4);   // Выставить на PB4 - "1"
   _delay_ms (4000);   // Задержка
   PORTB &= ~_BV(PB4); // Выставить на PB4 - "0"
   while ((PINB & (1 << PB1)) == 0)
   {   
   }
}       


// Основная программа
int main()
{

//   PORTB &= ~_BV(PB4);   // Выставить на PB4 - "0"
//   DDRB |= _BV(PB4);    // Указатель пина

   PORTB = 0b11101111;  // Выставить на PB4 - "0"
   DDRB  = 0b00010000;  // Указатель пина
      
   // Инициализация прерываний по INT0   
   GIMSK = 0b01000000; // Разрешение прерываний INT0 на входе PB1
   MCUCR = 0b00000000; // при перепаде низком уровне на PB1
   sei(); // Общее разрешение прерываний
      
   // Инициализация режима сна
   set_sleep_mode (SLEEP_MODE_PWR_DOWN);
   while(1)
   {
      sleep_enable();   // разрешение режима сна
      sleep_cpu();   // активация режима сна
   }
}

В симуляции работает (хотя это видимо не многого стоит) - подскажите, нет ли опять каких явных ошибок?

Также возник вопрос - почему перестала работать конструкция:
Код:
//   PORTB &= ~_BV(PB4);   // Выставить на PB4 - "0"
//   DDRB |= _BV(PB4);    // Указатель пина

в теле основной программы?

И еще - в обработчике прерывания пришлось опять вставить цикл, ждущий когда будет отпущена кнопка на PB1 (то же самое что мне не нравилось в предидущей версии программы). И все это время МК будет в нормальном режиме работать, а не энергосберегающем, можно ли как-то избавиться от этого? Все мои попытки привели пока только к тому что светодиод не гаснет, пока нажата кнопка...


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Вс дек 02, 2012 10:01:37 
Поставщик валерьянки для Кота

Карма: 16
Рейтинг сообщений: 329
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Сообщений: 2222
Откуда: Tashkent
Рейтинг сообщения: 0
Если в программном коде более понятно, то примерно такая структура выходит:
Код:
volatile uint8_t have_int0 = FALSE;
volatile uint8_t goto_sleep = FALSE;

// Обработчик прерываний INT0
SIGNAL(SIG_INTERRUPT0)  // Прерывание по низкому уровню на PB1
{           

   PORTB |= _BV(PB4);   // Выставить на PB4 - "1"
   
   disable_int0(); //отключить INT0 IRQ, обязательно иначе тутже сюда залетим снова
   enable_timer1(); //включить таймер на 4 сек
   have_int0 = TRUE;//флаг было прерывание, можно пойти в IDLE
}

// Обработчик прерываний TIM1
interrupt TIMER1_OVF_IRQ  // 4 сек прошло - залетели сюда
{
   PORTB &= ~_BV(PB4); // Выставить на PB4 - "0"

   disable_timer1();// отключить TIM1
   enable_int0(); // включить прерывание по низкому уровню
   goto_sleep = TRUE; //теперь можно полностью отключиться
}

// Основная программа
int main()
{
   device_init();//настройка портов и периферии
   while(1)
   {
   if( have_int0 == TRUE )
      {
      have_int0 = FALSE;
      sleep_idle();//усыпить в IDLE чтоб меньше жрало, но периферия работает
      };
   if( goto_sleep == TRUE )
      {
      goto_sleep = FALSE;
      sleep_power_down();//теперь все совсем отключено
      };
   }
}


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Вс дек 02, 2012 13:21:29 
Родился

Зарегистрирован: Вс авг 26, 2012 17:46:05
Сообщений: 17
Рейтинг сообщения: 0
uk8amk, спасибо!
А насчет PORTB &= ~_BV(PB4); не подскажете? Почему оно вдруг перестало нормально работать? Разве это не то же самое что и PORTB = 0b11101111;??? Я проверил - дело именно в PORTB, а не DDRB.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Вс дек 02, 2012 18:46:21 
Друг Кота
Аватар пользователя

Карма: 32
Рейтинг сообщений: 482
Зарегистрирован: Сб сен 10, 2011 17:46:25
Сообщений: 3832
Рейтинг сообщения: 0
не одно и тоже первое - установить в "0" один пин порта, второе установить весь порт
тут почитайте: http://we.easyelectronics.ru/AVR/avr-po ... -spat.html


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Пн дек 03, 2012 16:19:10 
Родился

Зарегистрирован: Вс авг 26, 2012 17:46:05
Сообщений: 17
Рейтинг сообщения: 0
Спасибо! Вроде разобрался. Вот еще задумался - я в самом начале фьюзы оставил все по дефолту. Только вотчдог разрешил.
Старший байт - все 1. (Внутренний RC-генератор 9.6МГц; Задержка запуска: 14 тактов + 64мс)
Младший байт:
SPIOEN - 0;
EESAVE -1;
WDTON - 0;
CKDIV8 - 0;
SUT1 - 1;
SUT0 - 0;
CKSEL1 - 1;
CKSEL0 - 0;

Может я чего-то не учел?


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: ATTiny13 - помогите разобраться со sleep-mode!
СообщениеДобавлено: Сб янв 06, 2018 20:45:27 
Сверлит текстолит когтями
Аватар пользователя

Карма: 9
Рейтинг сообщений: 19
Зарегистрирован: Ср мар 10, 2010 22:28:34
Сообщений: 1248
Откуда: Запад Беларуси
Рейтинг сообщения: 0
Написал прошивку под этот контроллер, чтобы отправлял частоту в радиомодуль по I2C. Большую часть времени он будет ждать, когда нажмут на кнопку. Хочу загнать его в sleep mode, чтобы не молотил впустую. Никак не могу с ним разобраться. Контроллер не отправляет данные в TEA5767.
Спойлер
Код:
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/sleep.h>
#include <avr/eeprom.h>
#include "I2C.h"

void tea5767SetFreq(unsigned int);

#define MAX_STATIONS 32
#define FM_FREQ_MIN  870
#define FM_FREQ_MAX 1075

unsigned char vars = 0b0000;//save, next, -, +
EEMEM unsigned int stations[MAX_STATIONS] = { 1007, 1045, 1016, 924, 979, 1000, 1037, 877, 1064, 952, 1068, 997, 976, 894, 1025, 964, 945, 995, FM_FREQ_MIN, FM_FREQ_MIN, FM_FREQ_MIN, FM_FREQ_MIN, FM_FREQ_MIN, FM_FREQ_MIN, FM_FREQ_MIN, FM_FREQ_MIN, FM_FREQ_MIN, FM_FREQ_MIN, FM_FREQ_MIN, FM_FREQ_MIN, FM_FREQ_MIN, FM_FREQ_MIN };
unsigned char divider = 0;
unsigned char currentStation = 0;
unsigned int freq = 0;

ISR (TIM0_COMPA_vect) //~20Hz
{
   if (++divider >= 5) //~4Hz
   {
      if (!(PINB & (1 << 5))) vars |= 1; //+
      if (!(PINB & (1 << 3))) vars |= 1 << 1; //-
      if (!(PINB & (1 << 4))) vars |= 1 << 2; else vars &= ~(1 << 2); //next
      if (!(PINB & (1 << 1))) vars |= 1 << 3; else vars &= ~(1 << 3); //save
      divider = 0;
   }
}

int main(void)
{
   if (freq == 0)
   freq = eeprom_read_word(&stations[currentStation]);

   CLKPR = 0x00;

   // Input/Output Ports initialization
   // Port B initialization
   // Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
   // State5=P State4=P State3=P State2=T State1=P State0=T
   DDRB = 0b000000;
   PORTB = 0b111010;

   // Timer/Counter 0 initialization
   // Clock source: System Clock
   // Clock value: 4,688 kHz
   // Mode: CTC top=OCR0A
   // OC0A output: Disconnected
   // OC0B output: Disconnected
   TCCR0A = 0x02;
   TCCR0B = 0x05;
   TCNT0 = 0x00;
   OCR0A = 0xea;
   OCR0B = 0x00;

   // Timer/Counter 0 Interrupt(s) initialization
   TIMSK0 = 0x04;

   set_sleep_mode(SLEEP_MODE_IDLE);
   
   asm volatile("sei");
   
   /* Replace with your application code */
   while (1)
   {
      if (vars & 1) //+
      {
         if (++freq >= FM_FREQ_MAX) freq = FM_FREQ_MIN;
         tea5767SetFreq(freq);
         vars &= ~1;
      }
      if (vars & (1 << 1)) //-
      {
         if (--freq <= FM_FREQ_MIN) freq = FM_FREQ_MAX;
         tea5767SetFreq(freq);
         vars &= ~(1 << 1);
      }
      if (vars & (1 << 2)) //next
      {
         currentStation = (currentStation < MAX_STATIONS) ? (currentStation - 1 > 0 && eeprom_read_word(&stations[currentStation]) == eeprom_read_word(&stations[currentStation - 1])) ? 0 : currentStation + 1 : 0;
         freq = eeprom_read_word(&stations[currentStation]);
         tea5767SetFreq(freq);
         while (vars & (1 << 2)) _delay_us(30);
      }
      if (vars & (1 << 3)) //save
      {
         eeprom_update_word(&stations[currentStation], freq);
         while (vars & (1 << 3)) _delay_us(30);
      }
      sleep_enable();
      sleep_cpu();
   }
}

void tea5767SetFreq(unsigned int freq)
{
   unsigned int div = ((unsigned long)freq * 12500 + 28125) >> 10; // /1024
   unsigned char var1 = (div >> 8) & 0x3F;
   asm volatile ("cli");
   i2c_start(0xC0);
   i2c_write(var1);
   i2c_write(div & 0xff);
   i2c_write(0b00001010);
   i2c_write(0b00011110);
   i2c_write(0);
   i2c_stop();
   asm volatile ("sei");
}

Схема во вложении. Хочу сделать всё сразу, т.к. выпаивать микру очень неудобно, а надо прошивать "Тритоном", т.к. Reset используется как порт.
Всё работает только когда отправляю в Idle режим.
Как правильно настроить PCINT, чтобы правильно срабатывали кнопки? Чтобы можно было отправлять в PWR_DOWN.


Вложения:
1.PNG [2.89 KiB]
Скачиваний: 611

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

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


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

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


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

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


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