mail_robot Опубликовано 14 марта, 2017 Поделиться Опубликовано 14 марта, 2017 недавно задался таким вопросом, и не смог толком на него ответить дело в следующем. В СТМ мы имеем счетчик времени systick, который ритмично отсчитывает по милисекунде в милисекунду )) Емкость счетчика 32 бита. То есть путем несложных математических инсенуаций получаем некоторое время, через которое он должен переполниться. И все бы ничего, если бы не желание использовать этот самый тик сплошь и рядом как базу для измерений некоторых длинных промежутков времени. Причем за ноль мы обычно берем некоторое уже имеющееся в таймере значение и просто парсим разницу. Но вот пройдет 49,71026963 дней, и таймер переполнится, а в это время может произойти пограничный отсчет какого нибудь такого события. И что? В мануалках порылся, ничего толкового на эту тему не нашел. Мож кто прорабатывал вопрос? 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
dm37 Опубликовано 14 марта, 2017 Поделиться Опубликовано 14 марта, 2017 я сознательно ввожу в AVR подобный счётчик, который отсчитывает количество вхождений в прерывание таймера настроенного на 1 млсек, таким образом счетчик считаем милисекунды. И конечно же он постоянно переполняется. Использую следующим образом: uint8_t counter; uint8_t key_delay; #define KEY_DELAY_NOISE 20 допустим значение counter уже равно 250, а я хочу замерить интервал в 20 млсек (KEY_DELAY_NOISE), key_delay = counter + KEY_DELAY_NOISE; // 250 + 20 = 270 (для uint8_t равно 14) и дальше проверка на сравнение if(key_delay == counter) // когда counter будет равно 14 значит прошёл заданный интервал времени. 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
20% скидка на весь каталог электронных компонентов в ТМ Электроникс!Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!Перейти на страницу акции Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849
Yurkin2015 Опубликовано 14 марта, 2017 Поделиться Опубликовано 14 марта, 2017 (изменено) 3 часа назад, mail_robot сказал: может произойти пограничный отсчет какого нибудь такого события Ничего плохого не будет. Если длительность события не превышает 49 дней, то переполнение не имеет значения - вычитайте просто так. Например, начало события при 0xFFFFFF00, а конец события при 0x00000025, то простое вычитание даст правильный результат: 0x00000025 - 0xFFFFFF00 = 0x00000125 Изменено 14 марта, 2017 пользователем Yurkin2015 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
mail_robot Опубликовано 14 марта, 2017 Автор Поделиться Опубликовано 14 марта, 2017 (изменено) Спасибо, а то уже собирался принимать меры. Башка просто чет перегрелась на кодинге, плохо соображает в ноликах и единичках 2 часа назад, dm37 сказал: и дальше проверка на сравнение if(key_delay == counter) // когда counter будет равно 14 значит прошёл заданный интервал времени. а если вместо сравнения будет стоять превышение? if (counter > key_delay) ? Вроде как на пограничных пунктах работать не должно. В то же время при сравнении есть опасность пропустить событие, если проверка произойдет позже периода счетчитка (по каким то причинам). Счет то в прерывании в то же время Цитата простое вычитание даст правильный результат // делаем засечку key_delay = counter; ... // корректно проверяем условие выполнения if ((counter-key_delay)< KEY_DELAY_NOISE) kount_OK!; такой способ вроде должен отрабатывать корректно в любой ситуации Изменено 14 марта, 2017 пользователем mail_robot 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
dm37 Опубликовано 14 марта, 2017 Поделиться Опубликовано 14 марта, 2017 53 минуты назад, mail_robot сказал: такой способ вроде должен отрабатывать корректно в любой ситуации если значение KEY_DELAY_NOISE будет небольшим, то потеряете событие 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
mail_robot Опубликовано 14 марта, 2017 Автор Поделиться Опубликовано 14 марта, 2017 с чего бы? Времени в любом случае пройдет больше чем KEY_DELAY_NOISE. Не буду же я топтаться на месте и проверять не случилось ли именно это событие. У программы и так забот хватает. Главное что нужное время как минимум прошло 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
dm37 Опубликовано 14 марта, 2017 Поделиться Опубликовано 14 марта, 2017 условие будет действовать только KEY_DELAY_NOISE млсек, потом условие выполняться не будет, составьте табличку с расчётами 1 час назад, mail_robot сказал: if ((counter-key_delay)< KEY_DELAY_NOISE) kount_OK!; 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
mail_robot Опубликовано 14 марта, 2017 Автор Поделиться Опубликовано 14 марта, 2017 (изменено) я вообще знак меньше поправил на знак больше, только редактор похоже тупанул. Поправьте мысленно и все станет нормуль Изменено 14 марта, 2017 пользователем mail_robot 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
dm37 Опубликовано 14 марта, 2017 Поделиться Опубликовано 14 марта, 2017 (изменено) 5 минут назад, mail_robot сказал: я вообще знак меньше поправил на знак больше, только редактор похоже тупанул. Поправьте мысленно тоже работать не будет counter key_delay counter-key_delay 250 14 236 251 14 237 252 14 238 253 14 239 254 14 240 255 14 241 0 14 242 1 14 243 2 14 244 3 14 245 4 14 246 5 14 247 6 14 248 7 14 249 8 14 250 9 14 251 10 14 252 11 14 253 12 14 254 13 14 255 14 14 0 - здесь ваше событие 15 14 1 16 14 2 17 14 3 18 14 4 19 14 5 20 14 6 надо на сравнение, только в вашем случае не с конкретным значением, а с диапазоном Изменено 14 марта, 2017 пользователем dm37 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
mail_robot Опубликовано 14 марта, 2017 Автор Поделиться Опубликовано 14 марта, 2017 тогда фигня получается. Цикл парсинга должен быть гарантированно меньше периода счетчика 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
dm37 Опубликовано 14 марта, 2017 Поделиться Опубликовано 14 марта, 2017 (изменено) а если так, if(counter >= key_delay) // это обычное условие, для работы без переполнения if((counter >= key_delay) && ((counter - key_delay) < aaa), где ааа максимальная допустимая задержка (например в размере одних суток) не проверял, но смыл в том, чтобы определить, что до переполнения меньше суток и если значение key_delay < counter значит было переполнение Изменено 14 марта, 2017 пользователем dm37 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
mail_robot Опубликовано 14 марта, 2017 Автор Поделиться Опубликовано 14 марта, 2017 (изменено) чето смотрел смотрел на вашу табличку. А ведь все не так. Посмотрите внимательно на мой код. key_delay не может принять значение больше чем counter. Поэтому табличку надо переписать иначе. И должно работать без всяких диапазонов и чистых сравнений. Все как у меня написано // делаем засечку key_delay = counter; ... // корректно проверяем условие выполнения if ((counter-key_delay) > KEY_DELAY_NOISE) сount_OK!; разность то в данном случае всегда будет корректной counter key_delay counter-key_delay 250 250 0 251 250 1 ... 9 250 14 10 250 15 (вот тут уже выполняется условие) 11 250 16 (и дальше если пропущено событие) Изменено 14 марта, 2017 пользователем mail_robot 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
Yurkin2015 Опубликовано 14 марта, 2017 Поделиться Опубликовано 14 марта, 2017 (изменено) 1 час назад, dm37 сказал: тоже работать не будет Ваш пример некорректен. Начальное значение key_delay = 14 и Вы успешно дождадись следующего значения 14, которое возникнет через полный период таймера. Поэтому и возникла ошибка. Для 8-ми битных таймеров максимальное условие ожидания (counter-key_delay) должно быть меньше 255. Тогда всё будет нормально. У mail_robot 32-бита, и значение 14 снова появится через 49 дней, никто не будет проверять кнопку так долго, и при разумных величинах KEY_DELAY_NOISE ошибки не будет даже при переполнении счётчика. Изменено 14 марта, 2017 пользователем Yurkin2015 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
mail_robot Опубликовано 14 марта, 2017 Автор Поделиться Опубликовано 14 марта, 2017 (изменено) да тем более что ошибки так и так не будет, хоть 8, хоть 32 бита. В предыдущем посте я все до микробов расписал. Спасибо кстати за арихметику Изменено 14 марта, 2017 пользователем mail_robot 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
dm37 Опубликовано 14 марта, 2017 Поделиться Опубликовано 14 марта, 2017 26 минут назад, mail_robot сказал: key_delay не может принять значение больше чем counter мы просто по разному задаём время срабатывания, у вас существует привязка к задаваемому значению у меня этого нет (наверно надо было мне подробнее описать свои исходные данные). Чтобы понять зачем я так делаю посмотрите мой код обработки клавиатуры: //----- Обработка нажатой клавиши ---------------------------------------------- if(!KEY_DETECT) // клавиша отжата? { RESET_KEY_HOLD; // сбрасываем признак нажатой клавиши } else { if(KEY_HOLD) // идет удержание? { // автоповтор if(KeyDelay == CountInt) // закончилась пауза между нажатиями/повторами? { Key = key; // код нажатой клавиши KeyDelay = CountInt + KEY_DELAY_HOLD; // задержка между нажатиями при удержании для обработки SET_KEY_PRESS; } } else { // первое нажатие BeepCount = DELAY_BEEP; // длительности в мс звукового сигнала BELL_ON; // звуковой сигнал нажатия кнопки SET_START_BEEP; // установить флаг начала выдержки звукового сигнала SET_KEY_HOLD; // устанавливаем признак удержания Key = key; // код нажатой клавиши KeyDelay = CountInt + KEY_DELAY_1PRESS; // задержка после первого нажатия SET_KEY_PRESS; } } здесь я где-то установил задержку (KEY_DELAY_1PRESS или KEY_DELAY_HOLD) и забыл о задаваемом значении, далее идёт только проверка на достижение, рассчитанного один раз, заданного значения. 18 минут назад, Yurkin2015 сказал: У mail_robot 32-бита, и значение 14 снова появится через 49 дней, никто не будет проверять кнопку так долго, и при разумных величинах KEY_DELAY_NOISE ошибки не будет даже при переполнении счётчика. Немного не понял о чём речь. Рассмотрите это с учётом выше сказанного. Я показал на 8-ми битных как происходит переполнение, и KEY_DELAY_NOISE это только пример. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
mail_robot Опубликовано 14 марта, 2017 Автор Поделиться Опубликовано 14 марта, 2017 (изменено) а разве должна быть разница в каком контексте применяется механизм, если он универсальный? вообще использование оператора == не очень красиво смотрится. Прямо аж глаз режет. Я в своем коде стараюсь его избегать всеми доступными способами. Так же как и else. Прямейшая дорожка к куче трудноуловимых багов Изменено 14 марта, 2017 пользователем mail_robot 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
Yurkin2015 Опубликовано 14 марта, 2017 Поделиться Опубликовано 14 марта, 2017 (изменено) @dm37 Ваш последний пример можно же переписать вот так if(CountInt - KeyDelay == KEY_DELAY_1PRESS) // закончилась пауза между нажатиями/повторами? ........ KeyDelay = CountInt ; // задержка после первого нажатия и ничего бы не изменилось и так же работало правильно при переполнениях. Только бы добавилась лишняя операция вычитания каждый раз при сравнении. В смысле экономии арифметических действий, Ваш пример, конечно, лучше. Изменено 14 марта, 2017 пользователем Yurkin2015 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
mail_robot Опубликовано 14 марта, 2017 Автор Поделиться Опубликовано 14 марта, 2017 одно единственное вычитание в масштабах мощностей STM32 это даже не пыль, а наночастица. Можно пожертвовать ради надежности 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
dm37 Опубликовано 14 марта, 2017 Поделиться Опубликовано 14 марта, 2017 57 минут назад, Yurkin2015 сказал: if(CountInt - KeyDelay == KEY_DELAY_1PRESS) наверно можно, но тогда пришлось бы добавить ещё одно условие if(CountInt - KeyDelay == KEY_DELAY_HOLD) у меня же условие одно для разных значений времени if(KeyDelay == CountInt) а вообще каждый делает по своему, я показал свой вариант 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex Опубликовано 17 марта, 2017 Поделиться Опубликовано 17 марта, 2017 А почему бы не использовать long long (расширить разрядность до 64 бит) ? Всего 4 лишних байта (одно маш. слово) и время до переполнения с 49 дней увеличится до миллионов (если не миллиардов) дней. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
mail_robot Опубликовано 18 марта, 2017 Автор Поделиться Опубликовано 18 марта, 2017 (изменено) да как бы можно и увеличить. Только придется заодно переопределить все библиотечные функции, которые этот таймер используют. Фигня делов. Гораздо проще одного единственного вычитания Можно конечно поступить как настоящий индеец, и параллельно систику запустить свой собственный миллисекундный таймер с вечным счетчиком long long. Работать будет Изменено 18 марта, 2017 пользователем mail_robot 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex Опубликовано 18 марта, 2017 Поделиться Опубликовано 18 марта, 2017 41 минуту назад, mail_robot сказал: Только придется заодно переопределить все библиотечные функции, которые этот таймер используют. Фигня делов. Гораздо проще одного единственного вычитания Сарказменный наезд не принят. Где речь шла о каких-то библиотеках, использующих эти тики, которые нужно перелопачивать ? : В 14.03.2017 в 09:10, mail_robot сказал: В СТМ мы имеем счетчик времени systick, который ритмично отсчитывает по милисекунде в милисекунду )) Емкость счетчика 32 бита. То есть путем несложных математических инсенуаций получаем некоторое время, через которое он должен переполниться. И все бы ничего, если бы не желание использовать этот самый тик сплошь и рядом как базу для измерений некоторых длинных промежутков времени. Причем за ноль мы обычно берем некоторое уже имеющееся в таймере значение и просто парсим разницу. Но вот пройдет 49,71026963 дней, и таймер переполнится, а в это время может произойти пограничный отсчет какого нибудь такого события. И что? Отсюда и совет - расширить разрядность таймера. Откуда же я знал, что Вы юзаете чужое... В принципе, даже если и чужое, всяко должны бить какие-либо калбеки от таймера. Если нет, то создать самому - пару кнопок нажать... А там уж расширяй таймер и юзай его сколько душе угодно. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
mail_robot Опубликовано 18 марта, 2017 Автор Поделиться Опубликовано 18 марта, 2017 да я вообщет без особого зла. К чему столько эмиций то? Тем более ваш метод вполне рабочий, и способ его применения я в кратце (саркастично) изложил. Но систик лучше не трогать. Это факт. Можно нарваться на какие нибудь нехорошие грабли, лежащие там, где и не ждал. Хотя конечно если приспичит, можно и его переколбасить. Но честно говоря, имея в руках настолько простое и безотказное по сути решение как точнейшее логическое условие, я не нахожу в этом ни нанометра логики. меня жена кстати тоже ругает за такую манеру разговаривать 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex Опубликовано 18 марта, 2017 Поделиться Опубликовано 18 марта, 2017 Если бы я знал, что Вы используете нечто готовое, что имеет внутренние систики и жёстко к ним привязаны (например ОСь), я бы, естественно, не давал таких советов. Совет мой был бы другим и зависел от того, что Вы используете и моих знаний в области используемого Вами. Возможно, его (совета) бы и вовсе не было. 1 Ссылка на комментарий Поделиться на другие сайты Поделиться
mail_robot Опубликовано 18 марта, 2017 Автор Поделиться Опубликовано 18 марта, 2017 и тем не менее в совете содержится как минимум два ценных пункта. И я их принял к сведению оба 0 Нужно делать то, что нужно. А то, что не нужно, делать не нужно. (С) Винни Пух Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.