Отговори на тема  [ 13 мнения ] 
Basic PIC Programming - Помощ! 
Автор Съобщение
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Сря Фев 05, 2014 8:43 pm
Мнения: 11
Мнение 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. Ще съм благодарен, ако хвърлите един поглед и ми посочите къде греша.
Благодаря предварително и весели празници! :)


Съб Апр 19, 2014 7:07 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Ное 12, 2004 3:38 pm
Мнения: 9103
Местоположение: Chicago, IL
Мнение Re: Basic PIC Programming - Помощ!
Като гледам така на пръв поглед проблема ти е в прекъсването. Прекъсване не се дефинира и вика така, както ти си го направил.
В компилатора, който ползваш си има специални правила за дефиниране на прекъсане и най-важното то си се вика само, ти не трябва да го викаш.
Виж някой от примерите с прекъсване и ще ти стане ясно.
Така както си го направил му се вика пулиране на пина, където е свързан бутона. Няма проблем да работи и така, ама първо трябва да забраниш прекъсването от тоя пин, за да не ходи процесора на несъществуващ вектор на прекъсване (както си го направил ти) и после в процедурата interrupt махни проверката за флаг на прекъсването и я замени с такава, която проверява дали бутона е натиснат. Трябва и още малко неща да се сложат за да се филтрират шумотевиците от натискането и отпускането на бутона, ама за тях после.
По принцип много по-добре е (според мен) бутони и клавиатури да се сканират с пулиране (на определено време), от колкото да ги оставиш на прекъсване и да си представяш, че сигналите от тях са идеално квадратни :) .


Съб Апр 19, 2014 7:39 pm
Профил
Ранг: Популярен
Ранг: Популярен

Регистриран на: Пон Мар 22, 2010 8:52 pm
Мнения: 328
Мнение Re: Basic PIC Programming - Помощ!
Дори и флага за прекъсване може да се полира. За да не влезе процесора в обработка на прекъсването е достатъчно да се забранят прекъсванията, ако не може през интеръпт контролера (ако има де, или флаг който го прави). Тогава периферията, ще си вдига флага за прекъсване и може да сисе полира.

Но:
while(1)
{
LED=1;
interrupt();
}
Тук в цикъла се сетва изхода и после евентуално е в нула от подпрограмата за малко. Но надали, ще се види на око. Би трябвало ЛЕД=1 да е извън цикъла.


Съб Апр 19, 2014 7:44 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Сря Фев 05, 2014 8:43 pm
Мнения: 11
Мнение 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, за да е видимо мигането на диода.

Нещо обаче не става. Явно ще трябва още малко да попрочета. Толкова за днес, утре пак ще го мъчим. Време е за празнуване.
Веско и Димитър, благодаря Ви отново за вниманието и весело изкарване на празника.


Съб Апр 19, 2014 8:43 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Чет Фев 03, 2005 2:21 am
Мнения: 12765
Местоположение: София
Мнение Re: Basic PIC Programming - Помощ!
От кода ти не става ясно как е конфигурирана и мапната аналоговата и останалата периферия на контролера.
По принцип съм малко на вие с програмирането, но:
LED= !LED;
не трябва ли да бъде
LED= ~LED;


Нед Апр 20, 2014 12:25 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Авг 23, 2005 12:02 pm
Мнения: 3070
Местоположение: София
Мнение Re: Basic PIC Programming - Помощ!
itso.t написа:
По принцип съм малко на вие с програмирането, но:
LED= !LED;
не трябва ли да бъде
LED= ~LED;


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


Нед Апр 20, 2014 12:39 am
Профил ICQ
Ранг: Напреднал
Ранг: Напреднал

Регистриран на: Чет Авг 21, 2008 2:52 pm
Мнения: 476
Местоположение: Пловдив
Мнение Re: Basic PIC Programming - Помощ!
Не трябва ли когато се пише в изходен порт да се записва в LAT регистъра...
тоест #define LED LATAbits.RA1


Нед Апр 20, 2014 1:51 pm
Профил
Online
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 9:21 pm
Мнения: 30686
Местоположение: София
Мнение Re: Basic PIC Programming - Помощ!
Димитър ти е писал за прекъсването което е съвсем вярно, а по долу някой спомена и за това че в майна сетваш да е 1. Ако оправиш тия две неща ще стане. С на мплаб не съм ползвал и не знам как се дефинира там вектора.
П.с нещо съм прупуснал коригирания ти код.
Това закъснение също не знам дали е правилно написано. Дали си си конфигурирал правилно процесора, генератор и ресет най-вече ???


Пон Апр 21, 2014 4:49 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Сря Фев 05, 2014 8:43 pm
Мнения: 11
Мнение Re: Basic PIC Programming - Помощ!
Здрасти, пичове.

Най-после го направих!
Оказва се, че трябва следният бит да се сетне:
ANCON1bits.ANSEL9=0
За да се настрои R4 като цифров вход.
"Не трябва ли когато се пише в изходен порт да се записва в LAT регистъра...
тоест #define LED LATAbits.RA1"

Благодаря за съвета, въпреки, че не пречи директно да се изпълни кодът, би могло да доведе до проблеми в последствие както го правя аз. Прав си.


Сря Апр 23, 2014 12:34 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Яну 01, 2012 8:04 pm
Мнения: 2663
Местоположение: София / Велико Търново
Мнение Re: Basic PIC Programming - Помощ!
TRISB = 1 e еквивалентно на TRISBbits.RB0 = 1; демек сетваш RB0 като вход а не RB4. Ама те нали по принцип са си входове ако не са сетнати трисите, та си работи и така....
И ако искаш да не плават и да влизат разни случайни работи, ги сетни като изходи, а не като входове. :idea:

_________________
https://github.com/slav4ocom/


Чет Апр 24, 2014 9:12 am
Профил
Ранг: Напреднал
Ранг: Напреднал

Регистриран на: Чет Авг 21, 2008 2:52 pm
Мнения: 476
Местоположение: Пловдив
Мнение Re: Basic PIC Programming - Помощ!
Да, винаги стават такива недоглеждания.
Първо винаги преглеждай кодове на китове с подобен на твоя контролер- каквото намериш в нета- конкретно от сайта на Майкрочип, предполагам публикуват софтуера към китовете.

Да си видиш инициализацията от там и да не се блъскаш за лудо :)


Чет Апр 24, 2014 9:32 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Яну 01, 2012 8:04 pm
Мнения: 2663
Местоположение: София / Велико Търново
Мнение Re: Basic PIC Programming - Помощ!
Сега гледам че има още една грешка фрапираща.
Имаш функция interrupt() която се вика при хардуерно прекъсване, а ти си я сложил във main() цикъла. Не трябва да е там. Всъщност и така ще се получи нещо. Светодиода ти LED ще е в някакво състояние. Докато натискаш бутона неговото състояние ще се променя на всеки цикъл, с някаква много висока честото. Зависи от бързината на процесора. Когато отпуснеш бутона той ще остане в едно от двете състояния.
За това махни функцията от там. Принципно може да се направи така, да имаш проверка main() цикъла
Код:
while(1){
  if ( !button )
   LED = 1;
  else
   LED = 0;
}
без използване на хардуерни прекъсвания...
Другото което е не зная как точно трябва да се опредили функцията като прекъсване. На асемблер съм го правил тоя номер, но на PIC16F627A - имаше си адрес 0x0004 и там като я изпляскаш си става. На тоя процесор имаше 2 нива на прекъсвания едното беше на 0x0008 ако не се бъркам. Но и не зная как трябва да се зададе функцията да стои точно там на този адрес.

_________________
https://github.com/slav4ocom/


Пон Апр 28, 2014 2:37 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Апр 20, 2005 12:02 pm
Мнения: 9119
Местоположение: Разград
Мнение Re: Basic PIC Programming - Помощ!
На трите вектора се слага само goto label_na_funkciata. Ако не се исползва low level interrupt се слага само на reset и high interrupt векторите. Но по принцип компилаторите си се оправят с тия неща.


Пон Апр 28, 2014 3:29 pm
Профил ICQ
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 13 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 3 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни