| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| Прекъсване от RB4-7 http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=7528 |
Страница 1 от 1 |
| Автор: | iivantodorov [ Пет Фев 05, 2010 9:05 pm ] | |||||||||
| Заглавие: | Прекъсване от RB4-7 | |||||||||
Здравейте, от известно време ползвам асемблер (не мога да кажа, че го знам отлично Но запецнах ..., та реших да потърся вашата помощ. Чета от доста време форума този като "гост" но явно само с четене не става, трябва и някой по знаещ да удари едно рамо. До тук с представянето, време е за въпроса ми. Сигурно е елементарен ама ... Ползвам 16ф914 на порт RB7, 6, 5 има включени бутончета и когато са натиснати, подават 0 на входовете. На RB1, 2, 3 са включени светодиодчета, та идеята ми е просто да си направя една фунцийка която да познава кой бутон е натиснат и този на RB7 примерно да разпознава дали е натиснат или е задъжан. Използвам си една глобална променлива като флаг регистър, където да се отрази състоянието на бутоните и от където да се вземе инфо за по-нататъшното действие. За сега ползвам светодиодите за индикация на състоянието на бутоните. (Знам, че на много места е писано по въпроса, но някои от примерните кодове не разбрах а и реших да си спретна сам.) Ето кода от прекъсването:
Проблема е, че искам при задържан бутон за RB7 (примерно 2 секунди), да се вдигне флаг 4. А той не се вдига. Дали ще задъжа бутона или ще го натисна и отпусна бързо си се вдига 7. Сигурно грешката е много елементарна или просто начина по който съм го написал е не правилен, но като начинаещ ми е малко трудно да я открия. И още едно дребно въпросче: това го правя като прекъсване, но може и да го направя като функция която ще се извиква в главната програма а не да се чака прекъсването. Ако реша да използвам това като управление на някакво елементарно меню, кое е за предпочитане - прекъсване или функцийка? Благодаря Ви предварително. |
||||||||||
| Автор: | ToHu [ Пет Фев 05, 2010 10:12 pm ] |
| Заглавие: | |
Ами ... има няколко неща които като цяло не ми допадат, най вече това чакане в прекъсване, после това бит тест .... много размива писането. Пиковете имат побитови команди, съответно в CCS може да работиш с битови променливи които директно се компилират в побитови команди, много по прегледно ще е ако работиш с битове, това не променя как работи програмата де. Аз това го виждам да работи по друг начин, т.е. няколко други но не и този. Като цяло дори няма нужда да използваш това прекъсване, ако целта е да обработиш тия входове с времеви филтър си направи едно прекъсване по таймер. rttc_isr() ...................... if(rb4) { if(rb4_time>200) { rb4_press=true; } } else { rb4_time=0; } rb4_time++; ............................. Така може да навържеш колкото поискаш входа и всички ще са с филтър по време. Прекъсването може да го използваш ако имаш опасения че може да изтървеш натискането, което пти 4 секундно изчакване няма как да стане. В този случай пак имаш варианти, може да проверяваш в самото прекъсване тези стойности, или просто там да вдигаш флаг rb4_state който да проверяваш в таймера. Разбира се тази проверка може и да не е в таймера а в основния цикъл, също така може да не инкрементваш много стойности а да ползваш твой таймерпо който зареждаш, и след това сравняваш, но това е по бавно като операции. Не збаравяй също че това прекъсване е по промяна, т.е. и при 1 и при 0. След това променливата за състоянието на порта я дефинираш в самото прекъсване, тя не е глобална, въпреки че като гледма я изпозлваш май само в самото прекъсване. Не забравяй че прекъсване имаш и от порт 4. Малко ми е объркано писането ти, това portb дефинирал ли си го някъде като byte=0x06 ? После в твоя код първо определяш кой е източника, да речем ОК, но както е написано ако натиснеш и пуснеш наистина мърда само 7, като задържиш би трябвало да се вдигне и 4 ама ... отделно хубавото на този порт с тия прекъсвания е че можеш да обработваш и 4-те, но ти изкуствено си си създал приоритет, 5,6,7 т.е. ако се задейства порт 5 или 6 ще пропуснеш порт 7. Аха току що загледох for не ти е наред, count =0 ти е условието при което започваш, count++ е правилото по което се изменя, count >=200 определя докога ще се изпълнява този for, в твоя случай ще прекъсва всеки път тъй като count ти е 0, би трябвало да е count<200, т.е. цикъла ще с еизпълнява докато count е по малко от 200. |
|
| Автор: | iivantodorov [ Пет Фев 05, 2010 10:26 pm ] |
| Заглавие: | |
Благодаря за отговора и идеите, ще обмисля написаното и ще пиша дали съм се справил. А да портб е дефиниран #byte PORTB =0x06 а за приоритета - идеята ми е простичка, тоест на едно прекъсване ме интересува само един бутон. Приоритета не би ли трябвало да е важен ако ще имам проверка за 2 натиснати бутона Инак мисля да пробвам дали ще се справя с твоя метод. пп: като направих count<200 стана, ама че грешка съм направил |
|
| Автор: | iivantodorov [ Съб Фев 06, 2010 11:57 pm ] |
| Заглавие: | |
Направих си едно файлче в което дефинирах битови променливи и ще го инклуудвам когато се ползва тази серия пикове. По моя калпав начин тръгна програмката, все пак реших да я направя както си му е реда, но само искам да попитам ако използвам този "времеви филтър" с прекъсване, това значи ли, че програмата ще се прекъсва постоянно от таймера при препълване за да проверява дали е натиснат бутон? Това постоянно прекъсване няма ли да пречи нещо? |
|
| Автор: | relsys [ Нед Фев 07, 2010 10:45 pm ] |
| Заглавие: | |
Да, програмата ще се прекъсва постоянно, това не пречи. Но там няма да проверяваш за натиснат бутон и обработката му, а само ще увеличваш стойността на времевия филтър. Но и това което Тони ти е написал не отнема много време, после някъде във друга функция ще обработиш: if rb4_press {...}; |
|
| Автор: | Tisho [ Пон Фев 08, 2010 6:04 pm ] |
| Заглавие: | |
Това прекъсване не беше ли по фронт? Аз бих го направил не с прекъсване а с таймер и броячи за закъснението. Като му дойде на таймера времето гледа тези входове и с елементарни проверки разбира дали дали бутона е задържан или не. |
|
| Автор: | MegatroniC [ Вто Фев 09, 2010 11:05 am ] | |||||||||
| Заглавие: | Re: Прекъсване от RB4-7 | |||||||||
Добре де, ... и мен това ми е интересно (че и аз съм от начинаещите на С Дори да остане с това прекъсване или да се направи по таймер както казва Тони, какво му е предисмтвото пред това да се направи тази проверка с една фукнция без прекъсване ? Или е все тая |
||||||||||
| Автор: | relsys [ Вто Фев 09, 2010 12:32 pm ] |
| Заглавие: | |
Ей, не четете, ей! Прекъсването дава еталонно време със необходимата резолюция. Там само си слагаш колкото са ти необходими броячи, и после ги обработваш в програмата. От къде иначе ще знаеш за колко време се е изпълнил даден цикъл на програмата? ПРИМЕР: Имаш вход, на който след получаване на сигнал, искаш да имаш изход със продължителност 100 мс. Ако прекъсването ти е на 100 us /10kHz/, след получаване на входния сигнал нулираш брояча на времето, установяваш изхода и започваш да проверяваш брояча. След като достигне стойност 1000 /100ms x 10/, нулираш изхода. |
|
| Автор: | iivantodorov [ Вто Мар 02, 2010 8:15 pm ] | |||||||||||||||||||||||||||
| Заглавие: | ||||||||||||||||||||||||||||
Здравейте отново Благодарение на напътствията на Тони си направих въпросното прекъсване от таймера и продължих да си мисля и да си реализирам по нататък идеите. Значи ето го въпросното прекъсване по време:
Ето и с прекъсване по рб4-7:
Това работи коректно, но по някога не ми е удобно да прекъсва и при 0 и при 1 Ето и майн програмката:
Задържайки тук бутон сет влизам в една функцийка за меню. Но по някога туй задържане може и да отнеме повече от 10 сек Съмнява ме този delay дали като влезе в него прекъсването не действа ... Обаче като го няма прекалено бързо се изпълнява програмата и показанията на дисплея премигват и трудно се вижда Явно както тука всички обичат да казват, нещо не съм дочел. Благодаря! |
||||||||||||||||||||||||||||
| Автор: | Cekins [ Вто Мар 02, 2010 8:59 pm ] |
| Заглавие: | |
Според мен не е от недочитане. Принципа ти на четене на бутоните е кекав. Зарежи тия прекъсвания - натискането на бутон е нещо което се извършва от човек и като такова то не може да бъде някакъв еталон за време, реакция и т.н. При бутона е по-важен така наречения дебоунс - отфлитриране разтрептяването на контактите. За нединамични бутони съм си направил една функцийка още като почнах да се занимавам с МЦУ-та и досега си я ползвам непроменена. Ще ти дам нещо като алгоритъм, а останалото оставям на теб : 1. Един от таймерите си го правя за ... таймер 2. Чета си порта (зависи дали целия или само битове - ненужните се маскират - AND,OR и т.н.) - слагам го в променлива Б1 примерно. 3. Проверявам дали е Б1>0. Ако не е - ясно (тука и Б2 от по-долу става 0) . Ако е: 3.1. Сверявам Б1 с другата променлива Б2. Ако Б2 е нула, Б2=Б1, Т1=12 3.2.1 Ако Б2=Б1 (вече натиснат и задържан бутон), при Т1>0 Б1=0 - тука става все едно не е натиснат бутона. 3.2.1 Б2=Б1, при Т1=0 - Т1 го правя примерно 6 вече, Б1 си го оставям - таймера е изтекъл, бутона е натиснат и се отчита. Цялото това нещо го викаш когато ти скимне - въобще не е чувствително кога става (е не чак толкова рядко че да не хваща въобще - примерно 100-200 пъти в секунда е предостатъчно). След като го извикам си полвам битовете на Б1. Винаги след задържане изчаква време и пак подава сигнал, ако продължиш да дръжиш подава вече на по-кратки интервали. Времето за изчакване не гълта процесорно време. А работи точно като клавиатура на компютър. С малко модификации може да се направи след 10-тия сигнал да прави нещо друго, следене за отпускане на бутоните и т.н. |
|
| Автор: | ToHu [ Сря Мар 03, 2010 5:50 pm ] |
| Заглавие: | |
То идеята ми като цело беше че изпозлвайки пекъсване по време не ти трябва прекъсване по RB .. |
|
| Автор: | iivantodorov [ Чет Мар 04, 2010 1:32 am ] |
| Заглавие: | |
Ама да, аз и ползвам само едното - по време. Другото просто го копирах тук, за да спомена, че с него работи безпроблемно. А идеята ми да използвам прекъсване за бутоните е, че влизайки и ровейки в менюто, и след 1-2 мин не се натисне бутон, програмата да се върне в майн. Сигурно може да стане и с кучето, но трудно бих реализирал голям интервал. |
|
| Автор: | ToHu [ Чет Мар 04, 2010 11:44 am ] |
| Заглавие: | |
Е ами какво типречи да сложиш още един таймер който нулира отделно при всяко натискане на бутон ... там където са ти таймерите по които правиш филтриране слагаш още един, само че не по един за всеки бутон а еидн общ без значение кой бутон се натиска ти си го нулираш, а ако стане достаъчно голям излизаш .... |
|
| Страница 1 от 1 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|