| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| Basic PIC Programming - Помощ! http://mcu-bg.com/mcu_site/viewtopic.php?f=7&t=12859 |
Страница 1 от 1 |
| Автор: | Simurai [ Съб Апр 19, 2014 7:07 pm ] |
| Заглавие: | Basic PIC Programming - Помощ! |
Здравейте, От доста време следя форума, но досега не се бях престрашил да пиша. Причината да го направя сега обаче не е много приятна Тепърва навлизам в тематиката за използване/програмиране на микроконтролери. От скоро работя по проект, свързан с образованието ми, но преди да започна с какъвто и да е дизайн на схеми, се опитвам да изуча сърцето на моя проект - микроконтролер PIC18F25K80. Опитвам се да направя нещо съвсем простичко (на пръв поглед, но не съвсем, поне за мен) - да светна LED с натискане на бутон. С какво разполагам: Pickit3 микропроцесор PIC18F25K80 кварц за такт 8MHz Напрежителен регулатор 7805, с който захранвам микропроцесора с 5V Всички необходими кондензатори (на Vddcore и между Vdd и Vss, според изискванията в дейташийта) На схемата ми съм свързал бутона и LED-а по следния начин: На пин RB4 (според datasheet-a поддържащ interrupt on change) съм поставил бутона (на пина се подава високо ниво, при натискане - ниско ниво) На пин RA1 е LED-a Планът ми: 1. Да задам портът, на който е закачен диода, като изход. 2. Да задам портът, на който е закачен бутона, като вход. 3. Да задам портър, на който е закачен бутона, да приема прекъсвания. 4. Да зацикля основната програма в безкраен цикъл. 5. Да задам при прекъсване от бутона да се преобръща състоянието на порта, на който е закачен диодът. 6. Всички останали портове ще задам като входове (за да избегна плаване на портовете) Използвам MPLAB.70 с добавен MPLAB C18 компилатор за C. Ето го и кодът ми: -------------------------------------------------------- #include <p18f25k80.h> #include <delays.h> #define XTAL_FREQ 8000000 #define LED PORTAbits.RA1 #define button PORTBbits.RB4 void interrupt(); void interrupt() //Interrupt service program { if(INTCONbits.RBIF == 1) { LED= ~LED; // change LED condition INTCONbits.RBIF=0 ; //clear RB Interrupt Flag } } void main() { TRISA = 0 ; // set PORTA as OUTPUT TRISC = 1 ; // set PORTC as an INPUT TRISB = 1 ; // set PORTB as an INPUT INTCONbits.RBIE=1 ; //Interrupt on RB enabled IOCB = 1 ; // Interrupt on change enabled for PORTB INTCONbits.RBIF=0 ; //PORTB interrupt flag down INTCON2bits.RBIP=1 ; //High priority interrupt LED = 1; //LED off while(1) { LED=1; interrupt(); } } -------------------------------------------------------------- За съжаление не се получава желаният ефект. Както може би се вижда в кода, съм начинаещ и в програмирането със C. Ще съм благодарен, ако хвърлите един поглед и ми посочите къде греша. Благодаря предварително и весели празници! |
|
| Автор: | Dimitar [ Съб Апр 19, 2014 7:39 pm ] |
| Заглавие: | Re: Basic PIC Programming - Помощ! |
Като гледам така на пръв поглед проблема ти е в прекъсването. Прекъсване не се дефинира и вика така, както ти си го направил. В компилатора, който ползваш си има специални правила за дефиниране на прекъсане и най-важното то си се вика само, ти не трябва да го викаш. Виж някой от примерите с прекъсване и ще ти стане ясно. Така както си го направил му се вика пулиране на пина, където е свързан бутона. Няма проблем да работи и така, ама първо трябва да забраниш прекъсването от тоя пин, за да не ходи процесора на несъществуващ вектор на прекъсване (както си го направил ти) и после в процедурата interrupt махни проверката за флаг на прекъсването и я замени с такава, която проверява дали бутона е натиснат. Трябва и още малко неща да се сложат за да се филтрират шумотевиците от натискането и отпускането на бутона, ама за тях после. По принцип много по-добре е (според мен) бутони и клавиатури да се сканират с пулиране (на определено време), от колкото да ги оставиш на прекъсване и да си представяш, че сигналите от тях са идеално квадратни |
|
| Автор: | Vesko [ Съб Апр 19, 2014 7:44 pm ] |
| Заглавие: | Re: Basic PIC Programming - Помощ! |
Дори и флага за прекъсване може да се полира. За да не влезе процесора в обработка на прекъсването е достатъчно да се забранят прекъсванията, ако не може през интеръпт контролера (ако има де, или флаг който го прави). Тогава периферията, ще си вдига флага за прекъсване и може да сисе полира. Но: while(1) { LED=1; interrupt(); } Тук в цикъла се сетва изхода и после евентуално е в нула от подпрограмата за малко. Но надали, ще се види на око. Би трябвало ЛЕД=1 да е извън цикъла. |
|
| Автор: | Simurai [ Съб Апр 19, 2014 8:43 pm ] |
| Заглавие: | Re: Basic PIC Programming - Помощ! |
Здравейте, Благодаря ви за отделеното време да погледнете темата. След като прочетох съветите ви, направих следните модификации на кода: ----------------------------- #include <p18f25k80.h> #include <delays.h> #define XTAL_FREQ 8000000 #define LED PORTAbits.RA1 #define button PORTBbits.RB4 void interrupt(); void interrupt() //Interrupt service program { if(button==0x00) { LED= !LED; // change LED condition Delay10KTCYx(100); } } void main() { TRISA = 0 ; // set PORTA as an OUTPUT TRISC = 1 ; // set PORTC as an INPUT TRISB = 1 ; // set PORTB as an INPUT INTCONbits.RBIE=0 ; //Interrupt on RB disabled IOCB = 0 ; // IOC disabled for PORTB INTCONbits.RBIF=0 ; //RB interrupt flag down LED = 1; while(1) { interrupt(); } } ------------------------------- Промени: 1.)Забранил съм каквито и да е прекъсвания. 2.)В подпрограмата interrupt вече проверявам дали бутонът е натиснат (button==0) 3.)В основната програма, в цикъла остана единствено подпрограмата. Да видим дали разбирам правилно - while(1) е зациклена, което значи че на всеки такт след началната инциализация ще проверява условието в подпрограмата interrupt(). При натискане на бутона, нивото на пина, на който той е свързан, би трябвало да падне (мерих го директно от пина с мултицета, за да съм сигурен, че бутонът работи. При натискане и задържане на бутона този пин е закъсен към GND, при отпускане на бутона имам високо ниво там (~5V)). Подпрограмата пък би трябвало да обръща моментното ниво на пин LED при изпълнено if условие (button==0 демек натиснат). 4.)Добавих към подпрограмата interrupt() малък delay, за да е видимо мигането на диода. Нещо обаче не става. Явно ще трябва още малко да попрочета. Толкова за днес, утре пак ще го мъчим. Време е за празнуване. Веско и Димитър, благодаря Ви отново за вниманието и весело изкарване на празника. |
|
| Автор: | itso.t [ Нед Апр 20, 2014 12:25 am ] |
| Заглавие: | Re: Basic PIC Programming - Помощ! |
От кода ти не става ясно как е конфигурирана и мапната аналоговата и останалата периферия на контролера. По принцип съм малко на вие с програмирането, но: LED= !LED; не трябва ли да бъде LED= ~LED; |
|
| Автор: | sparkybg [ Нед Апр 20, 2014 12:39 am ] | |||||||||
| Заглавие: | Re: Basic PIC Programming - Помощ! | |||||||||
В случая и двете ще работят. |
||||||||||
| Автор: | sukhoi [ Нед Апр 20, 2014 1:51 pm ] |
| Заглавие: | Re: Basic PIC Programming - Помощ! |
Не трябва ли когато се пише в изходен порт да се записва в LAT регистъра... тоест #define LED LATAbits.RA1 |
|
| Автор: | ToHu [ Пон Апр 21, 2014 4:49 pm ] |
| Заглавие: | Re: Basic PIC Programming - Помощ! |
Димитър ти е писал за прекъсването което е съвсем вярно, а по долу някой спомена и за това че в майна сетваш да е 1. Ако оправиш тия две неща ще стане. С на мплаб не съм ползвал и не знам как се дефинира там вектора. П.с нещо съм прупуснал коригирания ти код. Това закъснение също не знам дали е правилно написано. Дали си си конфигурирал правилно процесора, генератор и ресет най-вече ??? |
|
| Автор: | Simurai [ Сря Апр 23, 2014 12:34 am ] |
| Заглавие: | Re: Basic PIC Programming - Помощ! |
Здрасти, пичове. Най-после го направих! Оказва се, че трябва следният бит да се сетне: ANCON1bits.ANSEL9=0 За да се настрои R4 като цифров вход. "Не трябва ли когато се пише в изходен порт да се записва в LAT регистъра... тоест #define LED LATAbits.RA1" Благодаря за съвета, въпреки, че не пречи директно да се изпълни кодът, би могло да доведе до проблеми в последствие както го правя аз. Прав си. |
|
| Автор: | slav4o.com [ Чет Апр 24, 2014 9:12 am ] |
| Заглавие: | Re: Basic PIC Programming - Помощ! |
TRISB = 1 e еквивалентно на TRISBbits.RB0 = 1; демек сетваш RB0 като вход а не RB4. Ама те нали по принцип са си входове ако не са сетнати трисите, та си работи и така.... И ако искаш да не плават и да влизат разни случайни работи, ги сетни като изходи, а не като входове. |
|
| Автор: | sukhoi [ Чет Апр 24, 2014 9:32 pm ] |
| Заглавие: | Re: Basic PIC Programming - Помощ! |
Да, винаги стават такива недоглеждания. Първо винаги преглеждай кодове на китове с подобен на твоя контролер- каквото намериш в нета- конкретно от сайта на Майкрочип, предполагам публикуват софтуера към китовете. Да си видиш инициализацията от там и да не се блъскаш за лудо |
|
| Автор: | slav4o.com [ Пон Апр 28, 2014 2:37 pm ] | |||||||||
| Заглавие: | Re: Basic PIC Programming - Помощ! | |||||||||
Сега гледам че има още една грешка фрапираща. Имаш функция interrupt() която се вика при хардуерно прекъсване, а ти си я сложил във main() цикъла. Не трябва да е там. Всъщност и така ще се получи нещо. Светодиода ти LED ще е в някакво състояние. Докато натискаш бутона неговото състояние ще се променя на всеки цикъл, с някаква много висока честото. Зависи от бързината на процесора. Когато отпуснеш бутона той ще остане в едно от двете състояния. За това махни функцията от там. Принципно може да се направи така, да имаш проверка main() цикъла
Другото което е не зная как точно трябва да се опредили функцията като прекъсване. На асемблер съм го правил тоя номер, но на PIC16F627A - имаше си адрес 0x0004 и там като я изпляскаш си става. На тоя процесор имаше 2 нива на прекъсвания едното беше на 0x0008 ако не се бъркам. Но и не зная как трябва да се зададе функцията да стои точно там на този адрес. |
||||||||||
| Автор: | Cekins [ Пон Апр 28, 2014 3:29 pm ] |
| Заглавие: | Re: Basic PIC Programming - Помощ! |
На трите вектора се слага само goto label_na_funkciata. Ако не се исползва low level interrupt се слага само на reset и high interrupt векторите. Но по принцип компилаторите си се оправят с тия неща. |
|
| Страница 1 от 1 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|