Микроконтролери и електроника
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 - Помощ!

Здравейте,

От доста време следя форума, но досега не се бях престрашил да пиша. Причината да го направя сега обаче не е много приятна :cry:
Тепърва навлизам в тематиката за използване/програмиране на микроконтролери. От скоро работя по проект, свързан с образованието ми, но преди да започна с какъвто и да е дизайн на схеми, се опитвам да изуча сърцето на моя проект - микроконтролер 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 - Помощ!

itso.t написа:
По принцип съм малко на вие с програмирането, но:
LED= !LED;
не трябва ли да бъде
LED= ~LED;


В случая и двете ще работят.

Автор:  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. Ама те нали по принцип са си входове ако не са сетнати трисите, та си работи и така....
И ако искаш да не плават и да влизат разни случайни работи, ги сетни като изходи, а не като входове. :idea:

Автор:  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() цикъла
Код:
while(1){
  if ( !button )
   LED = 1;
  else
   LED = 0;
}
без използване на хардуерни прекъсвания...
Другото което е не зная как точно трябва да се опредили функцията като прекъсване. На асемблер съм го правил тоя номер, но на 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/