|
Виж темите без отговор | Виж активните теми
Дата и час: Пон Юли 27, 2026 12:48 pm
Притреперване на контактите на бутон
| Автор |
Съобщение |
|
pldimitroff
Ранг: Минаващ
Регистриран на: Чет Мар 19, 2009 11:22 am Мнения: 38 Местоположение: Стара Загора
|
 Притреперване на контактите на бутон
Здравейте, Начинаещ съм и за първи път програмирам микроконтролер, по-точно PIC16F84A. Да, програмата не тръгна от първия път, но както казваше един мой преподавател, ако едно нещо тръгне от първия път, то има груба грешка. И така за проблема ми: На вход RB0/INT съм поставил бутон свързан към 0V, OPTION_REG=0х00, тоест съм включил изтеглящите резистори (дано така се наричат), входът RB0/INT води до прекъсване по заден фронт 1/0 (при натискане на бутона), другите битове не са от значение (TMR0 не го ползвам). При натискане и отпускане на бутона, микроконтролерът го приема като двойно натискане и отпускане. Сложих кондензатор 220 nF паралелно на бутона (от входа към 0V). В подпрограмата за обработка на прекъсването поставих забавяне от 40-70 mS. Но и двете неща не помогнаха. Предполагам, че проблема е от притреперване на контактите на бутона. Интересното е, че някога и при отпускане на бутона се получава проблема. Предполагам, че напредналите, са срещали този проблем. По какъв начин да го отстраня?
Надявам се да съм улучил форума, защото мисля, че програмно може да се отстрани проблема. Благодаря Ви предварително!
Последна промяна pldimitroff на Сря Окт 19, 2016 4:10 pm, променена общо 1 път
|
| Сря Окт 19, 2016 3:09 pm |
|
 |
|
radolin
Ранг: Форумен бог
Регистриран на: Пон Дек 19, 2005 12:21 pm Мнения: 1037
|
 Re: Притреперване на контактите на бутон
Този проблем най-лесно може да се отстрани като филтрираш нежеланите прищраквания в софтуера.
Попитай google за 'debounce'. Може и с прекъсване, но аз лично ползвам просто един таймер който през Nms чете състоянието на входовете където е бутона. Само ако последните 4-5 състояния за стабилни и едни и същи се приема, че е натиснат/отпуснат бутона.
|
| Сря Окт 19, 2016 3:18 pm |
|
 |
|
pldimitroff
Ранг: Минаващ
Регистриран на: Чет Мар 19, 2009 11:22 am Мнения: 38 Местоположение: Стара Загора
|
 Re: Притреперване на контактите на бутон
Благодаря Ви! Този таймер, с който проверявате за стабилното състояние, сте написали Nms, от какъв порядък трябва да бъде? Аз в прекъсването му задавах 40-70 mS, това малко ли е?
|
| Сря Окт 19, 2016 4:16 pm |
|
 |
|
gicho
Ранг: Форумен бог
Регистриран на: Пон Мар 13, 2006 1:59 pm Мнения: 3867 Местоположение: Габрово
|
 Re: Притреперване на контактите на бутон
+1 Друг начин е да ползваш прекъсването, но да добавиш и таймера като single-shot. - чакаш прекъсване - като дойде го забраняваш и пускаш таймер с дефинираното от теб debounce време - типично е няколко десетки мс, зависи от типа на контактите, може и да е 1-2мс, може и да е на 100мс при големи контакти (дето като щракнат мигаш с очи в съседната стая) - като изтече времето за таймера проверяваш състоянието - четеш порта и гледаш - ако е отпуснат бутона значи е нещо кратко и го броиш за смущение (светкавица), ако е още натиснат продължаваш - тук идва логиката за кратко натискане, дълго натискане, двоен клик и тем подобни; разрешаваш порт прекъсването също тук Разликата с реализацията на Radolin е броя прекъсвания и използването на таймера. Ако имаш нужда от тик в системата и вече имаш таймер (например 1мс) лесно можеш да си закачиш изцяло polling решение (без порт прекъсване). Ако се опитваш да постигнеш tick-less реализация то ползваш таймера като single shot и той ти дава времевата база за таймера. Комбинация е да ползваш прекъсването но споменатия от мен "таймер" да стане "софтуерен" - алгоритъм който се държи като single shot но реално е реализиран като код дето работи в tick-а.
|
| Сря Окт 19, 2016 4:26 pm |
|
 |
|
Gogo
Ранг: Форумен бог
Регистриран на: Чет Фев 24, 2005 11:41 pm Мнения: 1049 Местоположение: Pz
|
 Re: Притреперване на контактите на бутон
Махни кондензатора и сложи външен pull-up (изтеглящ) резистор, например 4.7к Пробвай така: в прекъсването от RB0/INT с първата инструкция го забраняваш (самото прекъсване). Правиш си там каквото е нужно и пускаш таймера. 40-70 mS е много според мен, 10 би трябвало да стигнат. Когато пускаш таимера, му разреши прекъсването. Когато таймера свърши, спираш го и разрешаваш пак прекъсването на RB0/INT.
|
| Сря Окт 19, 2016 4:34 pm |
|
 |
|
michev
Ранг: Форумен бог
Регистриран на: Сря Юли 11, 2007 10:16 am Мнения: 1730
|
 Re: Притреперване на контактите на бутон
Много добра (и изпитана) идея за debounce - http://www.cc.gatech.edu/~hadi/teaching ... bounce.pdf И още нещо - смени тоя контролер с някой по-нов, че този скоро ще го има само в антикварните магазини 
|
| Сря Окт 19, 2016 4:44 pm |
|
 |
|
slav4o.com
Ранг: Форумен бог
Регистриран на: Нед Яну 01, 2012 8:04 pm Мнения: 2663 Местоположение: София / Велико Търново
|
 Re: Притреперване на контактите на бутон
Точно така и аз мисля за прекъсването, то по принцип се забранява когато се ползва някакво прекъсване.
|
| Сря Окт 19, 2016 6:01 pm |
|
 |
|
pldimitroff
Ранг: Минаващ
Регистриран на: Чет Мар 19, 2009 11:22 am Мнения: 38 Местоположение: Стара Загора
|
 Re: Притреперване на контактите на бутон
Благодаря Ви много на всички! Да, зная, че PIC16F84A е вече стар, но четох преди време от къде да се започне и дадоха съвет за него. А и аз съм зле с английския и намерих на руски, където се справям. Освен, че съм начинаещ с микроконтролерите, съм начинаещ и в програмирането. Има доста термини (debounce, single-shot и др.), които не са ми ясни, но ще ги потърся в нета. Надявам се да се справя. Ако срещна проблем, пак ще попитам. Отново БЛАГОДАРЯ!
|
| Сря Окт 19, 2016 6:37 pm |
|
 |
|
slav4o.com
Ранг: Форумен бог
Регистриран на: Нед Яну 01, 2012 8:04 pm Мнения: 2663 Местоположение: София / Велико Търново
|
 Re: Притреперване на контактите на бутон
Аз бих ти препоръчал PIC16F627/628/648 той е почти същия, като има някои допълнитени нещица - повече рам, по-вече програмна памет, повече EEPROM . USART модул. Може да работи без кварц. А цената е по-ниска. Идеален е за начинаещи, като почти всичко писано за 84 става и за него.
|
| Сря Окт 19, 2016 7:02 pm |
|
 |
|
bongo_x2
Ранг: Форумен бог
Регистриран на: Вто Яну 20, 2009 11:54 pm Мнения: 11338 Местоположение: "Занзибар"
|
 Как бае бай Бонго:
Ся, само с кондензатор не става, иска и токоограничаващ резистор за да не се *** бутонът рано или късно. Освен това хистерезисът е задължителен. Най-доброто софтуерно решение е имитация на най-доброто хардуерно. Пример: променливата Х1 може да е от 0 до 9, а Х2 е 0 или 1. Периодично, да речем през 10мс, четеш порта и ако е "1" увеличаваш Х1, ако е "0" намаляваш Х1 с по единица - това е интегратор. После проверяваш Х1 дали е над 6 или под 3 - два компаратора. В първия случай установяваш Х2=1, а във втория Х2=0, това е тригерът. Ба маа му таймер 555!  Разбира се, ако не си индиец може да си оптимизираш горния алгоритъм.
|
| Чет Окт 20, 2016 1:09 pm |
|
 |
|
sparkybg
Ранг: Форумен бог
Регистриран на: Вто Авг 23, 2005 12:02 pm Мнения: 3070 Местоположение: София
|
 Re: Притреперване на контактите на бутон
Аз често когато позволява приложението на нещото, чета порта през прекъсване на таймер, а не през прекъсване на порт. Примерно 100 пъти в секунда. И проблема практичеки до няма.
|
| Чет Окт 20, 2016 2:54 pm |
|
 |
|
ToHu
Ранг: Форумен бог
Регистриран на: Нед Сеп 26, 2004 9:21 pm Мнения: 30684 Местоположение: София
|
 Re: Притреперване на контактите на бутон
Това става ако е бутон, ако трябва да реагираш по време това не върши работа. Примерно отически енкодер, имах такъв случай и се налага да знам кога точно е фронта на сигнала, в същото време обаче трябва да съм сигурен и че не е смущение, в този случай тайм стамп по фронта а след това си правя филтрирането, и ако не е смущение се обрбаотва нататък.
|
| Чет Окт 20, 2016 4:16 pm |
|
 |
|
sparkybg
Ранг: Форумен бог
Регистриран на: Вто Авг 23, 2005 12:02 pm Мнения: 3070 Местоположение: София
|
 Re: Притреперване на контактите на бутон
Тъй де. Темата е за бутон, затова съм и добавил уговорката след това. А то и не за всеки бутон става де, но в 99% от случаите работи екстра и практически на иска нищо като код. С енкодер съм го правил общо взето по твоя начин - input capture например, и изхвърляне на "боклука" по критерий, зависещ от конкретното приложение.
|
| Чет Окт 20, 2016 4:41 pm |
|
 |
|
pldimitroff
Ранг: Минаващ
Регистриран на: Чет Мар 19, 2009 11:22 am Мнения: 38 Местоположение: Стара Загора
|
 Re: Как бае бай Бонго:
По тази логика, възможно ли е променливата Х1 да е от 0 до 3, а Х2 си остава същата 0 или 1. Периодично, но примерно през 30мс (3 пъти по-голямо време) да се чете порта и по същата логика да се увеличава или намалява Х1 според състоянието на порта. И когато Х1=0, то Х2=0 и когато Х1 =3, то Х2=1.
|
| Чет Окт 20, 2016 10:13 pm |
|
 |
|
gicho
Ранг: Форумен бог
Регистриран на: Пон Мар 13, 2006 1:59 pm Мнения: 3867 Местоположение: Габрово
|
 Re: Притреперване на контактите на бутон
Не е точно нищо, а има един известен цитат: [url]the fastest code is the code that never runs[/url] Което би ни върнало в темата за алтернативния подход и event-driven, но няма значение. Периодичното следене (polling) има недостатъка че яде ток - изисква tick, който е анти-патерн за пестене на ток и ресурс на CPU. Което автоматично го праща на заден план ако искаме да правим преизползваем код, който да леко универсален. Но не отричам че е лесно да се направи така.
|
| Пет Окт 21, 2016 10:32 am |
|
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 4 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|