| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| pic16f84a + 7seg + 2buttons http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=7130 |
Страница 1 от 1 |
| Автор: | DanielED [ Пон Сеп 14, 2009 2:06 am ] |
| Заглавие: | pic16f84a + 7seg + 2buttons |
Здравейте, имам задача за правене. Условието е да имам микроконтролер, индикация и два бутона. Замислил съм да направя задачата така, че с натискенто на единия бутон, да се увеличава съдържанието на някакъв регистър и да се изобразява на индикацията, а другия бутон да намаля съдържанието на регистъра при натискане. Почнах да пиша програмата, направих за единия бутон, по най-простия начин, чрез проверка, дали е натиснат бутона. Но за втория бутон, такава проверка не мога да направя или не се сещам как ще стане. Реших да пробвам с прекъсване, като по-удачен вариант. Но и там намирам проблем, има прекъсване, чрез единия извод на контролера - не ми върши работа. Другия вариант е да ползвам RB4 - RB7, които изводи също позволяват прекъсване. Тогава пък ще разваля конфигурацията на изводите за индикацията :\ Какво ще ме посъветвате? |
|
| Автор: | ji4ka [ Пон Сеп 14, 2009 2:15 am ] |
| Заглавие: | |
За бутоните не ти трябва прекъсване. Просто през 0.02сек проверяваш нивото на пиновете на които си вързал бутоните. А виж ,тия 0.02сек вече може да ги генерираш с прекъсване от тмр0 например. Но най-добре прегледай сайта на микрочип - там има много примери за работа с бутони и клавиатури. |
|
| Автор: | tolstolob [ Пон Сеп 14, 2009 10:05 am ] |
| Заглавие: | |
Таймер0 е решението, точно както казва колегата по-горе. Дори не ти трябва прекъсване - в main() сложи един празен цикъл, в който чакай флага за прекъсване на таймера да се вдигне. Като се вдигне, зачисти го и почвай да си вършиш задачите - опреснявай индикацията и чети (и дебаунсвай ако искаш) бутоните. Функциите си ги напиши в 'non-preemtive' стил - ползвай стейт машини. После добавянето на нови задачи се улеснява, също и поддръжката. За това, което се иска, аз бих използвал free run режим за таймера (т.е. не трябва да го зареждаш с някаква стойност) и време за препълване 4096us или 8192us. |
|
| Автор: | optron [ Пон Сеп 14, 2009 11:25 am ] |
| Заглавие: | |
За твой късмет, вече съм правил нещо такова, само че беше таймер, а не брояч, но постановката е подобна. При мен индикацията е динамична, с четири цифри. Аз правя така - при всяка стъпка от динамичната индикация правя проверка за бутон. В крайна сметка, човек не е толкова бърз, че да натисне и отпусне бутона за под 5 милисекунди. След това правя сравнение с регистър, в който съм запаметил последното състояние на бутоните. Така откривам дали имам преден или заден фронт на съответния вход. Нататък е лесно - инкрементиране и декрементиране. Другата особеност на тази задача е да си направиш знакова таблица за изображенията на индикаторите. Ако знаеш как се правят таблици в ПИК, ще ти е лесно. Ако не ти става ясно дотук, кажи, ще ти постна фрагменти от кода си. |
|
| Автор: | DanielED [ Вто Сеп 15, 2009 8:14 pm ] | |||||||||
| Заглавие: | ||||||||||
Здравейте, погледнете дали правилно съм се справил:
Когато тествам на Протеус не се получава. Зарежда и извежда нулата само, но натискането с бутоните не се получава, въпреки, че там мисля трябва да работи(бутоните). Явно нещо с TMR0 не съм се справил добре. |
||||||||||
| Автор: | optron [ Вто Сеп 15, 2009 8:49 pm ] | ||||||||||||||||||
| Заглавие: | |||||||||||||||||||
Следният фрагмент не ти е правилен:
Трябва да е:
И не е нужно да нулираш трис А, щом като после го зареждаш с литерала - това ще ти спести един цикъл, когато това е критично. Ако правилно разбирам, ти работиш с индикатор с един разряд. Не съм преглеждал таблицата ти със сегментния код, приемам, че правилно е съставена. Пусни и схемата да видим дали всичко е наред. |
|||||||||||||||||||
| Автор: | a_stankov [ Вто Сеп 15, 2009 10:34 pm ] | |||||||||
| Заглавие: | ||||||||||
Тука на пръв поглед ми се набива едно нещо.Незнам дали си го симулирал на протеус но според мен така както е написано няма да работи.Защото:
За да знае при прекъсване къде да направи преход. |
||||||||||
| Автор: | tolstolob [ Вто Сеп 15, 2009 11:13 pm ] | |||||||||
| Заглавие: | Кратък курс по използване на '#define' :) | |||||||||
Чак за прекъсване не работата, затова ето и моите 5 стинки:
|
||||||||||
| Автор: | optron [ Сря Сеп 16, 2009 12:30 am ] | ||||||||||||||||||
| Заглавие: | |||||||||||||||||||
Аз бих го направил така:
Толстолоб дава доста обемист пример, според мен е безпредметно да се правят дефиниции на дефиниции. И неговото е решение, разбира се, при други обстоятелства може да се използва. Но той напомня нещо, което не се сетих - да проверяваш да не излизаш извън границите на таблицата си. Възможно е Протеуса така да се държи, защото ако програмния брояч бъде насочен някъде след енд-инструкцията, не е ясно как ще реагира процесорът. Та сложи си проверка за най-малка и най-голяма стойност за всеки случай. Все пак, при мен, когато правя симулации и ми се случи програмния брояч да задраска някъде след енд, тогава просто процесорът не прави нищо и броячът си върви. Мисля си, че е възможно просто да се превърти след като обходи цялата програмна памет и да започне отначало, при което ефектът ще е просто рестартиране на програмата. Но не обещавам, че точно така ще стане! Още нещо - виждам, че следиш флага за прекъсване, значи ще трябва и да се грижиш за него. Имам предвид, че след като си обслужил прекъсването, трябва да нулираш флага. Преди това трябва поне веднъж да си прочел регистъра на порта, иначе флагът ще си остане вдигнат. |
|||||||||||||||||||
| Автор: | DanielED [ Сря Сеп 16, 2009 1:26 am ] |
| Заглавие: | |
tolstolob, благодаря ти. Пробвах програмата ти, но също като моята(след като я поправих и дадох начален адрес на прекъсването) при пускането на програмата сама почва да отброява... |
|
| Автор: | optron [ Сря Сеп 16, 2009 1:34 am ] |
| Заглавие: | |
Нешо ти куца при логиката за бутоните. Трябва да изчакаш да се натисне бутон, проверяваш кой е, след това правиш инкрементиране или декрементиране, след което изчакваш да се отпусне бутонът. Ако не правиш някое от тези изчаквания, почва едно лудо броене в някоя посока, което няма и да го видиш при реална обстановка заради бързодействието на процесора. |
|
| Автор: | tolstolob [ Сря Сеп 16, 2009 9:26 am ] |
| Заглавие: | |
Оптроне, не си разбрал смисъла на цялата верига дефиниции, а именно - с промяна на едно битче да промениш целия сет от символи без да си мърдаш пръста. Причината за това - кода е взет от един проект, при който индикацията на макета беше вързана по един начин, а на платката - по съвсем различен. Даниеле, примера, който съм дал, не ползва прекъсване - за това, което трябва да направиш изобщо не е нужно. Вече ако добавиш още един разряд индикация, нещата вече отиват към ползване на таймер. Не подценявай времето за дебаунс - трябва да има такова. В началото и аз го ядох, докато ми увре тиквата за тези 'подробности'. Още нещо - с цел ловене на непредвидени преходи (обикновено при несъобразен скок при четене на таблици) е добре да се използва FILL директива, с която попълваш незаетите места от програмното пространство - или с преход към ресет вектора или към някакъв друг адрес, така че да изловиш нередността. И още нещо - изхвърли го тоя протеус - така си създаваш двойна работа. Никога не съм ползвал това лайно и не мисля някога да го ползвам. Докато не видиш регистрите реално в контролера какви стойности приемат, реално работа не вършиш. |
|
| Автор: | DanielED [ Сря Сеп 16, 2009 8:25 pm ] |
| Заглавие: | |
Здравейте отново, Програмата като я чета е абсолютно точна вече. Като я пусна на Протеус, нещо не му харесва. В такъв случай, ако изключа Протеуса като помощна програма и използвам само дебъг, когато имам прекъсване в програмата как да го предизвикам в дебъг-а за да си продължи работата? |
|
| Автор: | tolstolob [ Сря Сеп 16, 2009 8:44 pm ] |
| Заглавие: | |
И в дебъг интеръптите си работят както трябва - просто слагаш брейкпойнт и дебнеш Можеш да сетнеш флаг за прекъсване и ръчно в съответния регистър. |
|
| Страница 1 от 1 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|