Перейти к содержанию
    

Как распознать кратковременное выключение на Tiny13

"Причесал" и всё расписал

Изменено пользователем ILYAUL

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Там и пояснять то нечего. Регистры не сразу сбрасывают то что в них записано

так вроде проверял VladislavS эту версию и сказал, что все сбрасывается

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ребят, только мне кажется, что ILYAUL курнул "непадецки"?

Одна загрузка константы в R16 через LPM... Ткните что-ли носом какой регистр там не обнуляется при старте?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

я третий раз перечитываю текст программы и ничего не понимаю :unsure:

 

VladislavS, так Вы не попробовали зашунтировать входы драйверов?

Изменено пользователем stells

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет еще. У нас "дымнуло" устройство в Тель-Авиве - готовлюсь к поездке. Так что, приношу извинения, но опыты по появлению свободной минутки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот код для тестирования регистров. несколько экспериментов показали, что разные регистры по-разному реагируют на снятие питания. в моих экспериментах, например, r10 спустя 10 секунд обесточки получал значение при старте 0x08, и сохранял нулевое значение при паузах питания менее 8-10 секунд стабильно. регистр r6 же терял нолик уже спустя 3 секунды обесточки, и принимал значение 1.

 

эффект налицо, но, видимо, для стабильности определения надо брать несколько регистров и анализировать их состояние...

// регистр для эксперимента
#define REG "r10"

volatile __attribute__((section(".noinit"))) uint8_t mem;

__attribute__((section(".init0"), naked)) void get_r10(void){
    register uint8_t tmp asm(REG);
    mem = tmp;
}

int main(void){
    printf_P(PSTR("\n" REG "=%u"),mem);
    asm volatile ("ldi r16,0 \n mov " REG ",r16");
    while(1);
}

 

P.S. как всегда, мега32 и STK500

 

вот еще результаты:

r0 - стабильно 18 (при очень котортких перерывах питания значение 16, нулевого не добился)

r1 - стабильно всегда 34, не добился иного

r2 - 0 всегда

r3 - помнит 0 до 1 секунды, при больших интервалах принимает значение 4 или 6

r15 - стабильно 1, изредка 3, нуля не добился

r20 - стабильно 22, нуля не добился

r25 - стабильно 0 при любых перерывах питания

r30 - стабильно 16, нуля не добился

 

вот, такие пироги... :)

 

еще результаты, с другим экземпляром меги32... неутешительные: повторяемости по регистрам нет никакой, все регистры имеют иное значение и сохранность данных практически не обеспечивают, т.е. записанный 0 практически мгновенно превращается в какое-то ненулевое значение... хотя при долгих перерывах есть тенденция добавления еще одного битика к "дефолтным"...

 

порадовал лишь r3 - как и в предыдущей меге четко видна разница между до-секундным перерывом питания и сверх-трехсекундным. в промежуточных интервалах точно не выверял...

 

первая мега использовалась не больше нескольких часов, перепрошивалась раз 50 (до начала экспериментов), а вторая - юзалась долго, перепрошивалась несколько сотен раз... может, износилась? :lol:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Во-во вот и я с этого начал , только сначала ещё писал в регистр своё значение. В итоге вот "понравился" R7 , но при автономной работе макета , появлялись глюки . Зря только потраченное время.

 

...я третий раз перечитываю текст программы и ничего не понимаю .... Ребят, только мне кажется, что ILYAUL курнул "непадецки"?

Одна загрузка константы в R16 через LPM... Ткните что-ли носом какой регистр там не обнуляется при старте?

 

Забудьте Вы про проверки значений регистров , SRAM и емкостей АЦП - не надо это всё . Всё гораздо проще. Если Вы внимательно всё читали , то я написал алгоритм решения кратковременное выключение на Tiny13

 

Запускаем первый режим при первом вкл фонарика , записывем его в EEPROM , при размыкании питания и вкл , проверяем режим равны меняем , записываем следуюший EEPROM и т.д. А можно просто счётчик режимов (как идея) ....

 

Расшифровываю , есть две абсолютно независимые от питания памяти в тини EEPROM и память программ. В памяти програм ( конкретно для выложенного кода) зарезервирован один байт со значением $55.

Вставили батарейки в фонарик - включили , первая команда после всех инит прочитать 1 ячейку EEPROM ( RCALL EEPROM_RD) которая заносит в регистр R17 (temp1) значение 1-ой ячейки EEPROM $FF.

Дальше из памяти програм командой LPM ( для тех кто не знает - команда чтения из памяти программ) получаем значение $55 ( в таблице - последняя строчка текста кода) .db $55,00 ( 00 не считается)

Сравниваем выяснем , что они не равны ( не может 55=FF) , CP temp, temp1 - зажигаем LED - записываем значение $55 в EEPROM . Любуемся на горящий LED.

Надоело, выкл вкл питание, Проходим тот же путь , что описано выше до строчки CP temp, temp1 , а вот тут и оказывается , что значение EEPROM $55 = значению $55 из памяти программ и здесь срабатывает команда -

раз равно , пшли помигаем светодиодом breq mode1. При этом заносим в EEPROM значение $56 . Наслаждаемся миганием светодиода . Надоело - передёрнули питание теперь значение $55 не равно значению $56 , светодиод будет опять гореть постоянно и так по кругу.

Изменено пользователем ILYAUL

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Забудьте Вы про проверки значений регистров , SRAM и емкостей АЦП - не надо это всё . Всё гораздо проще. Если Вы внимательно всё читали , то я написал алгоритм решения кратковременное выключение на Tiny13
жаль, что вы невнимательно читали тему. специально для вас конкретизирую: ваш алгоритм одинаково переключит режим и при выключении на 1 секунду, и при выключении на 30 секунд. а надо, чтобы при выключении на 30 секунд режим не менялся, а менялся только при выключении на 1 секунду (это я грубо и кратко задачу перефразировал). прочтите тему с первого поста!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

жаль, что вы невнимательно читали тему. специально для вас конкретизирую: ваш алгоритм одинаково переключит режим и при выключении на 1 секунду, и при выключении на 30 секунд. а надо, чтобы при выключении на 30 секунд режим не менялся, а менялся только при выключении на 1 секунду (это я грубо и кратко задачу перефразировал). прочтите тему с первого поста!

А помоему тема озаглавлена " Как распознать кратковременное выключение на Tiny13" , к тому же я написал , что мне лень писать распознование длительного отключения

Изменено пользователем ILYAUL

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А помоему тема озаглавлена " Как распознать кратковременное выключение на Tiny13" , к тому же я написал , что мне лень писать распознование длительного отключения
ну и где ваш ответ на "кратковременное" ? вы распознали "любое"

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ILYAUL, извиини, конечно, но твои изыски с LPM меня заставляют в судорогах биться. LDI в твоём контроллере сгорел что-ли???

 

А задачу мы решаем как раз ту, которую тебе лень решать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ILYAUL, извиини, конечно, но твои изыски с LPM меня заставляют в судорогах биться. LDI в твоём контроллере сгорел что-ли???

 

А задачу мы решаем как раз ту, которую тебе лень решать.

Длинное это сколько , что бы потом разночтений не было . А LPM - я так привык писать. LDI - загрузка константы в регистор общего назначения, поясните как Вы хотите её использовать вместо LPM ? что-то не врублюсь. Хотя кажется понял , Вас смущает, что в таблице только одно значение, но каr Вы должны были сразу понять , код не окончательный и как он будет развиваться дальше , даже мне пока не все моменты ясны . Так , что пусть так и будет LPM .

Изменено пользователем ILYAUL

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А LPM - я так привык писать. LDI - загрузка константы в регистор общего назначения, поясните как Вы хотите её использовать вместо LPM ? что-то не врублюсь

Вы считаете что команда LPM загружает регистр данными из памяти програм.

А откуда по вашему берутся данные для загрузки в регистор общего назначения командой LDI ???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

эффект налицо, но, видимо, для стабильности определения надо брать несколько регистров и анализировать их состояние...

порадовал лишь r3 - как и в предыдущей меге четко видна разница между до-секундным перерывом питания и сверх-трехсекундным. в промежуточных интервалах точно не выверял...

мне кажется, что даже если анализировать все регистры, то не будет 100% гарантии получения эффекта запоминания, а значит не будет и повторяемости. тем более на АВР и ПИК одновременно. тем более с учетом больших тиражей этих фонарей :(

 

 

если только создавать какой-то адаптивный алгоритм анализа регистров, но это уже почти искусственный интеллект, вряд ли в фонарях с этим заморачиваются :biggrin:

 

пока более-менее стабильный эффект получен с анализом конденсатора УВХ. сбои могут быть связаны с тем, что программа прерывается в произвольном месте. для устранения сбоев нужно анализировать резкое падение напряжения питания и выключаться, например, с логическим 0 на делителе. правда с ПИКом такой вариант не проходит

 

ну и емкость драйверов еще пощупать

Изменено пользователем stells

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

мне кажется, что даже если анализировать все регистры, то не будет 100% гарантии получения эффекта запоминания, а значит не будет и повторяемости. тем более на АВР и ПИК одновременно. тем более с учетом больших тиражей этих фонарей :(

Чтобы была повторяемость д.б. автоподстройка. Но судя по отсутствию записи в EEPROM (есть только одна запись - следующий режим) её нет.

Можно понадеяться на статистику и попробовать сделать примитивнейшим образом - во всё неиспользуемое ОЗУ и регистры писать 0, а при включении считать число битов =1. А вдруг прокатит?!?

 

Т.е. после долгого выключения число битов =1 и =0 примерно равны. А после недолгого - число битов =0 будет больше (ещё будет сказываться обнуление).

Алгоритм такой:

1. Определяем регистры и ячейки ОЗУ, не используемые при работе программы. Условие очень простое т.к. для этой программы достаточно будет 8 регистров.

2. При запуске считаем кол-во битов =1 в избранных регистрах и ячейках ОЗУ. Назовем это число N1, а общее кол-во битов во всех этих регистрах и ячейках ОЗУ Nn.

3. Пишем во все эти регистры и ячейки ОЗУ 0. Этот пункт для последующего включения.

4. Сравниваем N1 с Nn/4.

4.1 Если N1<(Nn/4) - выключение было коротким. Т.е. сохранилось влияние обнуления по п.3 с предыдущего раза. Значит нужно менять режим.

4.2 Если N1>(Nn/4) - выключение было долгим. Т.е. влияние обнуления нет и кол-во битов =0 и =1 примерно одинаковое и равное Nn/2 - режим не меняем.

 

Я бы сейчас этим занялся, но макета никакого под руками нет и времени абсолютно ни на что не хватает. Но при первой же возможности займусь и код выложу, чтобы и на других процессорах проверить и статистику набрать...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость
Эта тема закрыта для публикации ответов.
×
×
  • Создать...