mega16.RTC+sleep.Pесетится, или зависает после долгой спячки

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Аватара пользователя
O-LED
Мудрый кот
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57
Контактная информация:

mega16.RTC+sleep.Pесетится, или зависает после долгой спячки

Сообщение O-LED »

Вылазит у меня одна проблема, победить её, или понять откуда она растет не могу.
значит так. Atmega16А. работает от внутреннего генератора 8Мгц. также запущен таймер Т2 в асинхронном режиме, и тактируется часовым кварцем 32768. Таймерт настроен на прерывание раз в секунду. т.е. получаем RTC. RTC отлично работает, точно отсчитывая секунды. До этого момента никаких неприятностей нет. а начинаются они когда я усыпляю контроллер по команде SLEEP. делаю я это так. в конце обработчика Т2 усыпляю контроллер командой SLEEP. контроллер засыпает, и просыпается только при следующем прерывании Т2. проснувшись, контроллер выполняет обработчик Т2, в конце которого сново стоит SLEEP, и он сново засыпает. и так до тех пор пока не придет запрет на усыпления контроллера по SLEEP. Так вот, вроде все хорошо, НО рано я радовался. после нескольких срабатываний Т2, контроллер либо перезагружается(чаще), либо зависает(реже). я уже выкинул из кода ВСЕ кроме тикающего асинхронного таймера, но проблема не уходит. кстати количество срабатываний таймера до перезагрузки - строго одинаковое. если обработчик Т2 сделать таким

Код: Выделить всё

interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
x++;   
PORTD=x;  // это нужно чтоб было видно что таймер работает
#asm("sei")      #asm("sleep")
}
то Т2 протикает ~540 раз.
а если таким

Код: Выделить всё

 interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
x++;  if (x==60)  {x=0;  y++;}
PORTD=x;  // это нужно чтоб было видно что таймер работает
PORTA=y;  // это нужно чтоб было видно что таймер работает
#asm("sei")      #asm("sleep")
}
то сработок будет всего ~130

вот весь код(вернее то что от него осталось)

Код: Выделить всё

#include <mega16.h>
unsigned char    x;

interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
x++;   PORTD=x;
#asm("sei")      #asm("sleep")
}
void main(void)
{
PORTA=0x00; DDRA=0xFF;
PORTB=0x00; DDRB=0xFF;
PORTC=0x00; DDRC=0xFF;
PORTD=0x00; DDRD=0xFF;

ASSR=0x08;
TCCR2=0x05;
TCNT2=0x00;
OCR2=0x00;

TIMSK=0x41;
MCUCR|=0b01110000;  //    выбираю режим пониженного энергопотребления - Power Sawe, разрешаю усыплять по команде    "sleep"

#asm("sei")
while (1)
{};
}
В протеусе, кстати сказать, все работает без перезагрузок.....
Если усыпление перенести из обработчика Т2 в основной цикл, то все нормально работает, но мне в основном цикле не удобно. во первых есть куча мест куда программа может зайти и сидеть там минуту-две, а во вторых, перед каждым засыпанием будет один раз отрабатываться основной цикл(пока по кругу дойдет до SLEEP), что скажется на общем потреблении контроллера когда он спит.
Вот такая проблема. кто может подскажите.......
KIT
Аватара пользователя
Rimsky
Грызет канифоль
Сообщения: 299
Зарегистрирован: Вт июн 15, 2010 07:16:42
Откуда: Иркутск
Контактная информация:

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение Rimsky »

Попробуй в послед с часовым кварцем резюк на ~1кОм поставить, может срывается генерация, и кондеи в паралель на землю по пик 80-100 (если не стоят)
Аватара пользователя
Rimsky
Грызет канифоль
Сообщения: 299
Зарегистрирован: Вт июн 15, 2010 07:16:42
Откуда: Иркутск
Контактная информация:

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение Rimsky »

Вот я делал инициализацию, правда на асме, у тебя как-то очень все отдаленно :)

Код: Выделить всё

; инициализируем таймер 2 в асинхронном режиме на 32768Гц
;----------
   ldi   r16, (1<<AS2)
   out   ASSR, r16
   out   OCR2, ZERO
   out   TCNT2, ZERO
   ldi   r16, 0x05   ; прескаллер 128 период 1 SEC
   out   TCCR2, r16

LOOP_CLEAN_T2_FLAG:
   in   r16, ASSR
   ldi   r17, 0x08
   eor   r16, r17   
   brbs   SREG_Z, RET_TIM2_INIT
   rjmp   LOOP_CLEAN_T2_FLAG

RET_TIM2_INIT:
   ldi   r16, 0xFF
   out   TIFR, r16
   in   r16, TIMSK
   sbr   r16, (1<<TOIE2)
   out   TIMSK, r16

   sbi   PORTD, PD7
   sei   

Vov123
Опытный кот
Сообщения: 804
Зарегистрирован: Чт мар 12, 2009 16:31:05

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение Vov123 »

volatile unsigned char x;
Аватара пользователя
Goodefine
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение Goodefine »

O-LED писал(а):.. во первых есть куча мест куда программа может зайти и сидеть там минуту-две,

Это говорит о неправильной организации программы
O-LED писал(а): а во вторых, перед каждым засыпанием будет один раз отрабатываться основной цикл(пока по кругу дойдет до SLEEP), что скажется на общем потреблении контроллера когда он спит.

Это проблема легко обходится. Во всяком случае решается малой кровью - лишними будут только восстановление контекста после прерывания и одна проверка: в обработчике ставите флаг, а в main при этом установленном флаге работает только один цикл, состоящий только из усыпления МК...
Возможно, проблема в некорректном усыплении. М16 усыплять не приходилось (не располагает она к экономичным решениям), а вот tiny2313 усыплял подобным образом:

Код: Выделить всё

//Имеем определения:
//---sleep_mode
#define POWER_DOWN_MODE()   MCUCR&=~(0<<SM1); MCUCR|=1<<SM0
#define SLEEP_ENABLE()      MCUCR|=(1<<SE)
#define SLEEP()             asm volatile ("sleep")
#define SLEEP_DSBL()        MCUCR&=~(0<<SE)

При инициализации в main один раз пишем:

Код: Выделить всё

...
POWER_DOWN_MODE();
...

При усыплении:

Код: Выделить всё

 SLEEP_ENABLE();
 SLEEP();

При пробуждении:

Код: Выделить всё

SLEEP_DSBL();

Это к слову.... А, вообще, в вашем случае проблема явно с тем, что контроллер засыпает не успев восстановить стек, т.к. это он делает в последнюю очередь, а вы его усыпляете раньше. А входит то снова сначала... И сохраняет... Т.е. рушится стек. На это также косвенно указывает и то, что проходит разное количество срабатываний, в зависимости от числа операций в обработчике... Посмотрите в листинге как компилятор восстанавливает стек, и попробуйте руками это сделать до засыпания, путем ассемблерной вставки. Если поможет - будет понятно где искать... Но, ИМХО, надо уходить от усыпления в обработчике... Не думаю что возможна такая программа где это невозможно или влечет большие проблемы...
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Аватара пользователя
Danko
Сверлит текстолит когтями
Сообщения: 1287
Зарегистрирован: Пн окт 13, 2008 11:45:54
Откуда: РФ, Крым, г.Бахчисарай
Контактная информация:

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение Danko »

т.к. я усыплением МК занимался очень давно, то я за информацией обратился к литературе.

Вот то, что я накопал:
Изображение
А что идет за командой sleep ?
совершенно верно: выход из подпрограммы, который никогда не происходит т.е. после пробуждения МК входит в подпрограмму обработчика прерывания, выполняет в ней какие-то действия и опять засыпает и при этом выхода из подпрограммы не происходит. И после многократных входов и не выходов происходит переполнения стека и МК перегружается.

Я думаю, что все таки sleep нужно из прерывания переместить в main.
Первое, что привлекает в программировании, объяснить просто: ты говоришь компьютеру что то сделать, и он это делает. Безошибочно. Всегда. Без возражений.
---------------------
Линус Торвальдс. "Just for fun. Рассказ нечаянного революционера"
Аватара пользователя
O-LED
Мудрый кот
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57
Контактная информация:

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение O-LED »

Rimsky
Попробуй в послед с часовым кварцем резюк на ~1кОм поставить, может срывается генерация, и кондеи в паралель на землю по пик 80-100 (если не стоят)
кондеры и резисторы тут никаким боком. все тикает сутками, и засыпает-просыпается сутками, если усыплять не в прерывании. тут чтото программное.
Vov123
volatile unsigned char x;
никакой реакции.
Goodefine спасибо за идею. ведь команду #asm("sleep") можно засунуть в цикл while, и не выпускать из цикла до тех пор, пока нет команды на пробуждение. я уже попробовал так

Код: Выделить всё

while (1)
{
//******моя основная программа*********//
     while (MCUCR==0b01110000)
     {
     #asm("sleep")
     }
}
и все пашет.
А вообще есть какой нибудь способ, заставить контроллер после прерывания идти в какое нибудь конкретное место????? помню видел уже на форуме задавали этот вопрос, вот только не помню что там отвечали.(на тот момент меня это мало волновало)
Danko за три дня я уже помню наизусть даже на какой странице эта цитата, и какая таблица находится выше :)) , но без знаний о стеке, эти строчки ничего мне не давали :oops: .
all
Вообще, я посмотрю, все хором гонят меня SLEEPить из прерывания в основной цикл. ну значит так и поступлю. тем боле засунув sleep в цикл, я решаю почти все свои проблемы. осталось только убрать из кода места куда контроллер может заходить надолго.
KIT
Аватара пользователя
DrWatson
Опытный кот
Сообщения: 890
Зарегистрирован: Вт янв 20, 2009 14:49:08
Откуда: Гондурас, Мурманск

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение DrWatson »

Обычное переполнение стека и все. Вызывается прерывание внутри обработчика прерывания, стек постепенно переполняется со всеми вытекающими.
Усыплять лучше в основном цикле, а не в прерывании. Пусть в мэйне крутится while(условие) sleep, где условие - условие "спящего режима", когда нужен только RTC.
- Если вы такие умные, то почему тогда строем не ходите?
ἓν οἶδα ὅτι οὐδὲν οἶδα (с) Σωκράτης
Аватара пользователя
Goodefine
Держит паяльник хвостом
Сообщения: 906
Зарегистрирован: Ср апр 16, 2008 13:22:54
Откуда: Приднестровье, Тирасполь

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение Goodefine »

O-LED писал(а):...А вообще есть какой нибудь способ, заставить контроллер после прерывания идти в какое нибудь конкретное место?..

Этого тоже делать не следует - подобные химеры в коде ни к чему... Достаточно правильной организации программы..
Последний раз редактировалось Goodefine Чт окт 21, 2010 23:59:09, всего редактировалось 1 раз.
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
Аватара пользователя
Danko
Сверлит текстолит когтями
Сообщения: 1287
Зарегистрирован: Пн окт 13, 2008 11:45:54
Откуда: РФ, Крым, г.Бахчисарай
Контактная информация:

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение Danko »

O-LED писал(а): за три дня я уже помню наизусть даже на какой странице эта цитата, и какая таблица находится выше :)) , но без знаний о стеке, эти строчки ничего мне не давали
Си програмисту по большому счету не обязательно думать о стеке, его структуре и вообще как он работает, но вот то, что подпрограмма обработки прерывания вызывается и не закончив свою работу останавливается(засыпает) и затем еще и еще раз все это повторяется - это тебя не настораживало ?
Первое, что привлекает в программировании, объяснить просто: ты говоришь компьютеру что то сделать, и он это делает. Безошибочно. Всегда. Без возражений.
---------------------
Линус Торвальдс. "Just for fun. Рассказ нечаянного революционера"
Аватара пользователя
O-LED
Мудрый кот
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57
Контактная информация:

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение O-LED »

Создавать новых тем не буду, спрошу здесь.
Вот усыпил я по правильному с вашей помощью контроллер. Теперь нужно максимально уменьшить его потребление во время сна. ведь многие узлы продолжают работать и во сне. это-
1. АЦП
2. Аналоговый компаратор
3. Детектор понижения питания
4. ИОН
5. Сторожевой таймер
6. Порты
Пункты 1,3,5 - тут вроде все просто, - я их не использую, значит они и так выключены по умолчанию, и дополнительно выключать их ненужно? так?
С портами есть вопросы.
а) если порт был выходом, то его лучше и оставить выходом, только записать туда лог 0?
б) если порт является входом, внутренняя подтяжка включена. Имеет ли смысл сделать порт выходом и записать туда 0? просто снять подтяжку наверное не стоит, т.к. на этих выводах висят кнопки, и если убрать подтяжку, и оставить входом, то вывод будет ловить наводки и переключаться туда-сюда, и соответственно много "жрать".
ИОН и компаратор используется. но все время они работающие мне не нужны. может есть смысл поступить так. Перед усыплением выключить их, каждую секунду контроллер просыпается, включить ИОН и компаратор, оценивать состояние компаратора, выключить ИОН и компаратор, усыпить контроллер, и т.д. Имеет ли смысл так делать? ведь для нормальной работы ИОН и компаратора, после включения, должно пройти какое то время, и все это время контроллер будет "молотить" в полную силу. не получится ли так, что общее потребление даже возрастет?

если есть еще какие предложения по уменьшению потребления - с удовольствием выслушаю.
KIT
Аватара пользователя
Danko
Сверлит текстолит когтями
Сообщения: 1287
Зарегистрирован: Пн окт 13, 2008 11:45:54
Откуда: РФ, Крым, г.Бахчисарай
Контактная информация:

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение Danko »

У меня вопрос о целесообразности применения аналового компаратора и ИОНа:

для чего в схеме применяется компаратор? для отслеживания наличия питающего напряжения? а зачем величину питающего напряжения измерять аналоговым компаратором с внутр ИОН, не проще ли использовать вход МК который по сути является цифровым компаратором. Какова величина лог.0 и лог.1 в уровнях ТТЛ. (точно не помню, но меньше 0,7 и больше 2,5 соответственно, при питании 5В). Зачем знать, что питающие напряжение выше напр.ИОН, ведь нас больше интересует есть напряжение или его нет.

И второе: ты похоже перелопатил кучу литературы и книгу "Микроконтроллеры AVR в радиолюбительской практике (Белов)(2007).djvu" наверняка смотрел, если нет, то страница 57 и 58.
Первое, что привлекает в программировании, объяснить просто: ты говоришь компьютеру что то сделать, и он это делает. Безошибочно. Всегда. Без возражений.
---------------------
Линус Торвальдс. "Just for fun. Рассказ нечаянного революционера"
Qwertty
Первый раз сказал Мяу!
Сообщения: 25
Зарегистрирован: Сб окт 31, 2009 12:34:44

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение Qwertty »

O-LED писал(а):Вот такая проблема. кто может подскажите.......

Изучаем даташит, конкретно - примечания к работе таймера в асинхронном режиме. Там найдется интересная информация:
• If Timer/Counter2 is used to wake the device up from Power-save mode,
precautions must be taken if the user wants to re-enter one of these modes: The
interrupt logic needs one TOSC1 cycle to be reset. If the time between wake-up and
re-entering sleep mode is less than one TOSC1 cycle, the interrupt will not occur,
and the device will fail to wake up. If the user is in doubt whether the time before re-
entering Power-save or Extended Standby mode is sufficient, the following algorithm
can be used to ensure that one TOSC1 cycle has elapsed:
1. Write a value to TCCR2, TCNT2, or OCR2.
2. Wait until the corresponding Update Busy Flag in ASSR returns to zero.
3. Enter Power-save or Extended Standby mode.

Ваш случай.
Аватара пользователя
O-LED
Мудрый кот
Сообщения: 1800
Зарегистрирован: Вт окт 05, 2010 01:08:57
Контактная информация:

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение O-LED »

Danko
Целесообразность такая. компаратором я могу засечь падение с 5 до 4,5 вольт. а без компаратора можно только знать, что у меня на выводе (0 или 1) С падением напряжения питания контроллера, изменяется и уровень этой единицы. например при питании 3 вольт, единицей уже будет считаться всё от 2,7 до 3вольт. Вот какая у меня схема.
Изображение
для того чтоб можно было обойтись без компаратора, нужно чтоб первый конденсатор быстро разрядился. но, у меня основной потребитель - сам МК, т.е. первый конденсатор, не спеша разряжается на делителе, и все это время контроллер думает что с питанием всё хорошо, питается вполную силу от батарейки,и не засыпает. Короче, нужно как то разряжать первый конденсатор. с этим я еще поэкспериментирую.
кстати, померял сколько потребляет ИОН и компаратор. при их включении, ток увеличивается примерно на 15-20мка, так что не так уж и много. во сне (с ежесекундными пробуждениями) мега потребляет 24 мка без компаратора, и примерно 40-43 с компаратором.

попутно поигрался с понижением питания контроллера, и с ионистором. МК у меня мега16А. захотелось мне выяснить минимальное рабочее напряжении МК. был очень приятно удивлен - две меги16А, купленные в разное время и даже в разных городах, показали совершенно одинаковый результат - уверенно работали при снижении питания до 1,4 вольта. при 1,35 - уже как повезет, иногда продолжали работать, а иногда останавливались. Скорее всего все новые меги(с индексом А) можно запрасто питать от 1,8 вольта, и не париться.

потом решил поиграться с ионистором. подключил вместо батарейки ионистор на 1Ф. и оставил на ночь. за ночь (10часов) напряжение на ионисторе упало с 4,3 до 3,9вольт. т.е. на 0,4 вольта. если учитывать что мега еще работоспособна при 1,4 вольта, то по рассчетам она сможет проработать от ионистора на 1Ф 72часа. трое суток!!! на практике я думаю еще больше, ведь с уменьшением напряжения питания, уменьшается и потребляемый ток. Во как...... А если ионистор взять на 4Ф...... короче я не понимаю почему ионистор непопулярен в радиолюбительской практике в качестве резервного источника питания. Обслуживания никакого, зарад - секунд 10, размером - меньше CR2032.....

Qwertty Я думаю это здесь не причем. Все прекрасно засыпает и просыпается если SLEEP в основном цикле. здесь действительно переполняется стек. При каждом вхождении в прерывание в стек заносится что нужно делать после прерывания. а у меня было так что многократо заходим в прерывании, и ни разу не выходим......
Общем этот вопрос уже решен.
Вложения
ПИТ.GIF
(4.3 КБ) 941 скачивание
KIT
Аватара пользователя
Danko
Сверлит текстолит когтями
Сообщения: 1287
Зарегистрирован: Пн окт 13, 2008 11:45:54
Откуда: РФ, Крым, г.Бахчисарай
Контактная информация:

Re: mega16.RTC+sleep.Pесетится, или зависает после долгой сп

Сообщение Danko »

первое: уже давно тебе нужно заменить фразу "МОЖЕТ БЫТЬ....". Она тебе уже не соответствует.

второе: раз уж ты не ленив к лабораторным испытаниям, то проверь пожалуйста потребление МК затактированного от внутр RC и от внешнего кварца (ноги у мега16 для кварца все равно свободные). Где-то читал, что от кварца МК потребляет меньше.

Про ионистор: 4,3 вольта это 5 вольт минус падение 0,7В на диоде, а если взять диод шотки с падением 0,1В, то продолжительность работы от резервного источника можно будет продлить еще на полтора суток.
Первое, что привлекает в программировании, объяснить просто: ты говоришь компьютеру что то сделать, и он это делает. Безошибочно. Всегда. Без возражений.
---------------------
Линус Торвальдс. "Just for fun. Рассказ нечаянного революционера"
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»