Например TDA7294

 Форум РадиоКот • Просмотр темы - ATtiny13 и режим IDLE
Форум РадиоКот
Здесь можно немножко помяукать :)



Текущее время: Ср янв 17, 2018 13:54:53



Часовой пояс: UTC + 3 часа [ Летнее время ]


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



Начать новую тему Ответить на тему  [ Сообщений: 12 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: ATtiny13 и режим IDLE
СообщениеДобавлено: Чт дек 14, 2017 12:34:39 
Родился

Зарегистрирован: Чт дек 14, 2017 12:07:27
Сообщений: 4
Рейтинг сообщения: 0
Доброго времени суток. Прошу проанализировать людей знающих. Вот написал такой код:
Код:
#define F_CPU 16000UL
#define fwd PORTB |=(1<<PB2); PORTB &=~(1<<PB0);      // fwd - вперед
#define bwd PORTB |=(1<<PB0); PORTB &=~(1<<PB2);      // bwd - назад
#define stp PORTB &=~(1<<PB0); PORTB &=~(1<<PB2);      // stp - стоп
#define pause1   4                              // 6ч - 1350
#define pause2   3                              // 3ч - 675
#define pause3   2                              // 90мин - 330
#define pause4   1                              // 45 мин - 165
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sleep.h>

// - Varriable -//
unsigned int timer=0;                           // счетчик таймера (увеличивается в прерывании каждые 16 сек)

void movie ()
{
   fwd                                       // включаем двигатель вперед
   _delay_ms(600);                              // пауза 0,5 секунды
   stp
   _delay_ms(100);
   bwd
   _delay_ms(300);
   stp
   timer = 0;
}

unsigned int pause ()                           // время между сработками (pause*16.25)секунд
{
   ADMUX = (0<<REFS0)|                           // Bit 6 – Источник опорного напряжения (0 - VCC, как источник опорного напряжения, 1 - Встроенный источник опорного напряжения)
         (1<<ADLAR)|
         (1<<MUX1)|                           // Bit 1 – Analog Channel and Gain Selection Bits (Выбор канала ADC (см. datasheet)) в данном случае выбираем ADC2
         (0<<MUX0);                           // Bit 0 – Analog Channel and Gain Selection Bits (Выбор канала ADC (см. datasheet))
   ADCSRA |= (1 << ADSC);                        // Начинаем преобразование
   while ((ADCSRA & (1 << ADIF)) == 0);            // Ждем флага окончания преобразования
   ADCSRA|=(1<<ADIF);
   if (ADCH <= 53)                              // в зависимости от АЦП изменяем величину переменной pause
      {
         return (pause4);
      }
   if ((ADCH <= 89) && (ADCH >= 54))
      {
         return (pause3);
      }
   if ((ADCH <= 125) && (ADCH >= 90))
      {
         return (pause2);
      }
   return (pause1);
}

bool light ()
{
   ADMUX = (0<<REFS0)|                           // Bit 6 – Источник опорного напряжения (0 - VCC, как источник опорного напряжения, 1 - Встроенный источник опорного напряжения)
         (1<<ADLAR)|
         (1<<MUX1)|                           // Bit 1 – Analog Channel and Gain Selection Bits (Выбор канала ADC (см. datasheet)) в данном случае выбираем ADC2
         (1<<MUX0);                           // Bit 0 – Analog Channel and Gain Selection Bits (Выбор канала ADC (см. datasheet))
   ADCSRA |= (1 << ADSC);                        // Начинаем преобразование
   while ((ADCSRA&(1 << ADIF))== 0);               // Ждем флага окончания преобразования
   ADCSRA|=(1<<ADIF);
   if ((ADCH <= 176))                           // в зависимости от АЦП изменяем light
      {
         return false;         
      }
   else
      {
         return true;   
      }      
}

ISR (TIM0_OVF_vect)
{
   timer++;                                    //Увеличение timer на 1 каждые 16 секунд
   if (timer >= pause())                           // если timer больше полученного значения pause
   {
      if (light())                              // и "светло"
         {
            movie();                           // срабатываем
            timer = 0;                           // обнуляем timer
         }
      else                                    // а если timer больше полученного значения pause и "темно"
         {                                       
            asm volatile ("nop");
         }
   }
}

ISR (INT0_vect)
{
   movie();
   timer = 0;
}

int main(void)
{
    DDRB   = 0b00101;                           //0 - Назад (выход), 1 - Кнопка (вход), 2 - вперед (выход), 3 - датчик света (вход), 4 - датчик режима(вход)
    PORTB   = 0b00010;
   TCCR0A   |=(0<<COM0A0)                        //Инициализация таймера
         |(0<<COM0A1)
         |(0<<COM0B0)
         |(0<<COM0B1)
         |(0<<WGM01)
         |(0<<WGM00);
   TCCR0B   |=(0<<FOC0A)
         |(0<<FOC0B)
         |(0<<WGM02)
         |(1<<CS02)
         |(0<<CS01)
         |(1<<CS00);
   TCNT0   =0;
   ADMUX = (0<<REFS0)|                           // Bit 6 – Источник опорного напряжения (0 - VCC, как источник опорного напряжения, 1 - Встроенный источник опорного напряжения)
         (1<<ADLAR);                         // Bit 5 – ADC Left Adjust Result (1 - левое выравнивание результата; 0 - правое выравнивание результата измерения)
   ADCSRA = (1<<ADEN)|                           // Bit 7 – ADC включатель (1- включен, 0 - выключен)
         (0<<ADATE)|                           // Bit 5 – ADC постоянное преобразование (1 - включено, 0 - выключено)
         (1<<ADPS2)|                           // Bit 2 – ADC Prescaler Select Bits Выбор частоты преобразования (см. datasheet)
         (1<<ADPS1)|                           // Bit 1 – ADC Prescaler Select Bits Выбор частоты преобразования (см. datasheet)
         (1<<ADPS0);                           // Bit 0 – ADC Prescaler Select Bits Выбор частоты преобразования (см. datasheet)
   TIMSK0   |=(1<<TOIE0);                        // Разрешение прерывания по переполнению таймера 0
   GIMSK   |=(1<<INT0);                        // включение внешних прерываний
   sei();                                    // Общее разрешение прерываний
     while (1)
    {
        set_sleep_mode(SLEEP_MODE_IDLE); //Закомментировав
        sleep_enable();                                 // эти строчки
        sleep_cpu();                                      // все работает так как надо!
   if (timer >= 5000)
      {
         cli();                                    // общий запрет прерываний
         TIMSK0 &=~(1<<TOIE0);                        // отключение прерываний по таймеру (1 раз в 16 секунд)
         sei();                                    // общее разрешение прерываний
         set_sleep_mode(SLEEP_MODE_PWR_DOWN);            // установка "летаргического сна"
         sleep_enable();                              // разрешение спящего режима
         sleep_cpu();                              // сон
         sleep_disable();                           // запрет сна
         cli();                                    // общий запрет прерываний
         TIMSK0   |=(1<<TOIE0);                        // включение прерываний по переполнению таймера (1 раз в 16 секунд)
         sei();                                    // общее разрешение прерываний
         TCNT0   =0;                                 // сброс счетчика
         timer = 0;
      }
    }
}


В нем реализована сработка некоего двигателя с частотой, которая задается в переменной pause в зависимости от значения ADC3. Величина pause сравнивается с переменной timer, и когда timer становится >= pause, происходит сработка. Причем , если пришло время сработки, а переменная light (зависит от ADC2) = false, то сработки не будет. Весь этот алгоритм находится внутри прерывания по переполнению таймера 0, т.е. по моим настройкам примерно 1 раз в 16 секунд.
Все остальное время целесообразно спать.
Проблема: из режима IDLE контроллер по прерыванию то ли не выходит, толи выходит не полностью. ADC3 и ADC2 не реагируют на изменение напряжения. Как только закомментирую строчки перевода в спячку - все работает идеально. Кстати, внешнее прерывание в любом случае отрабатывает прекрасно! Ничего не понимаю. Помогите, кто чем может. Пожалуйста


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: ATtiny13 и режим IDLE
СообщениеДобавлено: Пт дек 15, 2017 11:03:58 
Родился

Зарегистрирован: Чт дек 14, 2017 12:07:27
Сообщений: 4
Рейтинг сообщения: 0
Спасибо всем, кто не остался в стороне, Ответом на мои вопросы является фраза: "Не фиг в прерывании вызывать функции". Нужно перерабатывать алгоритм. Тему можно закрывать.


Вернуться наверх
 Профиль  
 
JLCPCB Prototype, Бесплатная доставка первого заказа + $2 на прототип ПП!

Крупнейший производитель печатных плат в Китае, 290,000+ заказчиков, 8,000+ он-лайн заказов в день.

Цена за 10 плат: $2 за 2-х слойную, $15 за 4-х слойную, $74 за 6-ти слойную.

LCSC Parts: Экономия до 50%, большой выбор компонентов в наличии, отправка заказа в день оплаты.

В сети
 Заголовок сообщения: Re: ATtiny13 и режим IDLE
СообщениеДобавлено: Пт дек 15, 2017 11:55:38 
Сверлит текстолит когтями
Аватар пользователя

Карма: 13
Зарегистрирован: Пт ноя 11, 2016 06:48:09
Сообщений: 1195
Откуда: край интернета... самый край :(
Рейтинг сообщения: 0
с чего вдруг такое ограничение?

Добавлено after 2 minutes 36 seconds:
я наоборот стараюсь всё в прерывания засунуть и, тем самым, например, избавиться от конструкций типа _delay_ms (xxx).

Добавлено after 3 minutes 24 seconds:
так, по прерыванию "системного" таймера удобно разом и семисегментник крутить и кнопки (со встроенным антидребезгом и определением длительности и кратности нажатия) и прочую периферию разквартировать, чтобы у них дружная "коммуналка" получилась...
и функции применяю - полёт нормальный.

_________________
Код:
Year++;


Вернуться наверх
 Профиль  
 

Не в сети
 Заголовок сообщения: Re: ATtiny13 и режим IDLE
СообщениеДобавлено: Пт дек 15, 2017 21:22:36 
Друг Кота
Аватар пользователя

Карма: 44
Зарегистрирован: Вт апр 24, 2007 08:45:40
Сообщений: 4040
Откуда: Minsk
Рейтинг сообщения: 0
Ivanoff-iv писал(а):
и функции применяю - полёт нормальный.

Это при условии, что время выполнения функции гарантировано меньше периода таймера. Иначе результат непредсказуем.

А delay - действительно зло. Таймерные прерывания нужно наполнять полезной работой - с учетом вышесказанного.
Это мое мнение, и я так думаю :)
Блин, юбилейный 4000-й пост! Пойду хлебну валерьянки

_________________
Изображение


Вернуться наверх
 Профиль  
 

Не в сети
 Заголовок сообщения: Re: ATtiny13 и режим IDLE
СообщениеДобавлено: Сб дек 16, 2017 09:02:06 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 91
Зарегистрирован: Чт дек 28, 2006 09:19:56
Сообщений: 11121
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Jack_A писал(а):
А delay - действительно зло
и еще goto :)))

_________________
я свою работу за вас делать не буду!


Вернуться наверх
 Профиль WWW  
 
Не в сети
 Заголовок сообщения: Re: ATtiny13 и режим IDLE
СообщениеДобавлено: Сб дек 16, 2017 13:54:48 
Друг Кота
Аватар пользователя

Карма: 44
Зарегистрирован: Вт апр 24, 2007 08:45:40
Сообщений: 4040
Откуда: Minsk
Рейтинг сообщения: 0
Ну это смотря какой goto . В Фортране-IV это, пожалуй, единственный способ организации ветвлений и циклов :)

_________________
Изображение


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: ATtiny13 и режим IDLE
СообщениеДобавлено: Сб дек 16, 2017 14:08:37 
Ум, честь и совесть. И скромность.
Аватар пользователя

Карма: 91
Зарегистрирован: Чт дек 28, 2006 09:19:56
Сообщений: 11121
Откуда: Новочеркасск
Рейтинг сообщения: 0
Медали: 2
Получил миской по аватаре (1) Мявтор 3-й степени (1)
Jack_A писал(а):
Ну это смотря какой goto
то есть delay() зло безапелляционно, а goto - еще бабушка надвое сказала? ;)

_________________
я свою работу за вас делать не буду!


Вернуться наверх
 Профиль WWW  
 
Не в сети
 Заголовок сообщения: Re: ATtiny13 и режим IDLE
СообщениеДобавлено: Сб дек 16, 2017 15:38:57 
Друг Кота
Аватар пользователя

Карма: 44
Зарегистрирован: Вт апр 24, 2007 08:45:40
Сообщений: 4040
Откуда: Minsk
Рейтинг сообщения: 0
Yes, Sir !
Но вообще я безапелляционно никогда не заявляю. Даже в этом ответе - сомневаюсь :)

_________________
Изображение


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: ATtiny13 и режим IDLE
СообщениеДобавлено: Пн дек 18, 2017 21:01:24 
Родился

Зарегистрирован: Чт дек 14, 2017 12:07:27
Сообщений: 4
Рейтинг сообщения: 0
И все-таки проблема осталась. Код был упрощен до вот этого:
Код:
#define F_CPU 16000UL
#define fwd PORTB |=(1<<PB2); PORTB &=~(1<<PB0);      // fwd - вперед
#define bwd PORTB |=(1<<PB0); PORTB &=~(1<<PB2);      // bwd - назад
#define stp PORTB &=~(1<<PB0); PORTB &=~(1<<PB2);      // stp - стоп
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sleep.h>

unsigned int timer=0, pause;                           // счетчик таймера (увеличивается в прерывании каждые 16 сек)
unsigned char light, i;

void movie ()
{
   fwd                                       // включаем двигатель вперед
   _delay_ms(500);                              // пауза 0,5 секунды
   stp
   _delay_ms(100);
   bwd
   _delay_ms(200);
   stp
   timer = 0;
}

ISR (TIM0_OVF_vect)
{
   timer++;                                    //Увеличение timer на 1 каждые 16 секунд
   
}

ISR (INT0_vect)
{
   movie();
}

int main(void)
{
    DDRB   = 0b00101;                           //0 - Назад (выход), 1 - Кнопка (вход), 2 - вперед (выход), 3 - датчик света (вход), 4 - датчик режима(вход)
    PORTB   = 0b00010;
   TCCR0A   |=(0<<COM0A0)                        //Инициализация таймера
         |(0<<COM0A1)
         |(0<<COM0B0)
         |(0<<COM0B1)
         |(0<<WGM01)
         |(0<<WGM00);
   TCCR0B   |=(0<<FOC0A)
         |(0<<FOC0B)
         |(0<<WGM02)
         |(1<<CS02)
         |(0<<CS01)
         |(1<<CS00);
   TCNT0   =0;
   ADMUX = (0<<REFS0)|                           
         (1<<ADLAR)|                         
         (1<<MUX1)|                           
         (1<<MUX0);
   ADCSRA = (1<<ADEN)|                           
         (0<<ADATE)|                           
         (1<<ADPS2)|                           
         (1<<ADPS1)|                        
         (1<<ADPS0);                        
   TIMSK0   |=(1<<TOIE0);                        
   GIMSK   |=(1<<INT0);                        
   sei();                                    
while (1)
    {
      ADMUX   &=~(1<<MUX0);                        
      ADCSRA   |= (1 << ADSC);                        
      while ((ADCSRA&(1 << ADIF))== 0);               
      i= ADCH;
      if (ADCH >=171)                              
      {
         pause = 1;
      }
      else
      {
         if ((ADCH < 171) && (ADCH > 122))
         {
            pause = 2;
         }
         else
         {
            if ((ADCH < 122) && (ADCH > 50))
            {
               pause = 3;
            }
            else
            {
               pause = 4;
            }
         }
         
      }
      
      ADMUX   |=(1<<MUX0);                        
      ADCSRA   |= (1 << ADSC);                        
      while ((ADCSRA&(1 << ADIF))== 0);               
      light = ADCH;
      
      if (timer >= pause)                           
         {
            if (light<=100)                              
               {
                  movie();                              
               }
            else                                    
               {                                       
                  _delay_us(1);
               }
      
         }
      set_sleep_mode(SLEEP_MODE_IDLE);            //при комментировании
      sleep_enable();                        // этих строчек
      sleep_cpu();                        // все работает
      sleep_disable();                        // нормально
      if (timer >= 5000)
         {
            cli();                                    // общий запрет прерываний
            TIMSK0 &=~(1<<TOIE0);                        // отключение прерываний по таймеру (1 раз в 16 секунд)
            sei();                                 // общее разрешение прерываний
            set_sleep_mode(SLEEP_MODE_PWR_DOWN);            // установка "летаргического сна"
            sleep_enable();                              // разрешение спящего режима
            sleep_cpu();                              // сон
            sleep_disable();                           // запрет сна
            cli();                                    // общий запрет прерываний
            TIMSK0   |=(1<<TOIE0);                        // включение прерываний по таймеру (1 раз в 16 секунд)
            sei();                                    // общее разрешение прерываний
            TCNT0   =0;                                 // сброс счетчика
            timer = 0;
         }
    }
}


ADC3 вообще не считывается! ADC2 считывается с ошибкой, т.е. не то, что должно быть. В чем подвох? В чем ошибка? Где собака зарыта? В протеусе работает идеально. Если IDLE убрать - тоже прекрасно работает.


Вернуться наверх
 Профиль  
 
В сети
 Заголовок сообщения: Re: ATtiny13 и режим IDLE
СообщениеДобавлено: Вт дек 19, 2017 04:51:07 
Сверлит текстолит когтями
Аватар пользователя

Карма: 13
Зарегистрирован: Пт ноя 11, 2016 06:48:09
Сообщений: 1195
Откуда: край интернета... самый край :(
Рейтинг сообщения: 0
почитай еррату на чип, может там чего есть?

_________________
Код:
Year++;


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: ATtiny13 и режим IDLE
СообщениеДобавлено: Вт дек 19, 2017 20:56:16 
Родился

Зарегистрирован: Чт дек 14, 2017 12:07:27
Сообщений: 4
Рейтинг сообщения: 0
Случилось чудо!!
Наконец-то получилось!
Ответ нашелся в datasheet`e Attiny13 на стр.82, пункт 14.3, 3 абзац (перевод с помощью онлайн переводчика):
АЦП включен по настройка АЦП включить бит aden в ADCSRA. Опорное напряжение и
входных каналов не вступят в силу пока Аден установлен. АЦП не потребляет
мощность, когда Аден очищается, поэтому рекомендуется отключить перед входом АЦП мощности
сохранение режима сна.
как-то так...
Итог: в первом варианте перед переходом в IDLE устанавливаю ADEN в 0. И перед запуском конвертации устанавливаю ADEN в 1. Все работает прекрасно.
Может кому-нибудь мой опыт пригодится ;-)


Вернуться наверх
 Профиль  
 
В сети
 Заголовок сообщения: Re: ATtiny13 и режим IDLE
СообщениеДобавлено: Вт дек 19, 2017 21:56:44 
Сверлит текстолит когтями
Аватар пользователя

Карма: 13
Зарегистрирован: Пт ноя 11, 2016 06:48:09
Сообщений: 1195
Откуда: край интернета... самый край :(
Рейтинг сообщения: 0
как ни странно, но мне, примерно через месяц эта инфа скорее всего и пригодится :) тиньки 13 придут, полюбому чего нибудь из них наделаю.

_________________
Код:
Year++;


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



Часовой пояс: UTC + 3 часа [ Летнее время ]


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

Сейчас этот форум просматривают: strengerst и гости: 11


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

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


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