Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

PIC16f628A програма
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=12678
Страница 1 от 3

Автор:  maguss4o [ Пон Фев 10, 2014 6:50 pm ]
Заглавие:  PIC16f628A програма

Здравейте, сега навлизам в програмирането на PIC-ове и все още не знам доста...

Тръгнах да си играя с горепосочения пик...
Та пиша на C и се чудя как ще стане, че когато на RA1,2,3,4 имам светодиоди и на RB1,2,3,4 съответните им бутони и когато натисна бутон 1 да се изгаси ra1, натисна бутон 2 да се изгаси RA2, и съответни RB4->RA4, RB3->RA3...

RA0 ми е входящ старт на програмата...

Код:

#include <htc.h> //CALL PIC CONFIGS
#include <stdio.h> //CALL LIBRARY
#include <stdlib.h> //CALL LIBRARY
#define _XTAL_FREQ 4000000 //SET XTAL FREQ on 4MHZ

__CONFIG(FOSC_INTOSCIO & WDTE_OFF & PWRTE_OFF & MCLRE_ON & BOREN_ON & LVP_OFF & CPD_OFF & CP_OFF);

void delayS(int s){
    for(int i=0; i<s; i++){
        __delay_ms(800);
    }
}

/*void closePin(int b1, int b2, int b3, int b4){
    if(b1==1){
        RA1=0;
    }else if(b2==1){
        RA2=0;
    }else if(b3==1){
        RA3=0;
    }else if(b4==1){
        RA4=0;
    }

}*/

int main(int argc, char** argv) {
    TRISA = 0b01100001;
    TRISB = 0b00011110;
    PORTB = 0x00;
    OSCF = 1;
    while(1){
        if(RA0==1){
            while(RB1==0 || RB2==0 || RB3==0 || RB4==0){
                RA1=1;RA2=1;RA3=1;RA4=1;
                   //Тука вече не знам как да изгасям съответния светодиод независимо, кой бутон съм натиснал да изгасне точно неговия светодиод ;(
            }
        }else if(RA6=1){
            delayS(8);
            RA7=1;
            delayS(1);
        }
    }

    return (EXIT_SUCCESS);
}




Изображение

Автор:  valioman [ Пон Фев 10, 2014 11:32 pm ]
Заглавие:  Re: PIC16f628A програма

Не знам на колко си годинки но е похвално ,че си почнал от някъде и се блъскаш Браво !
Сега по темата ... не пиша точно на този компилатор и може да греша синтаксиса но образно мисля ще ме разбереш.
1.На практика запомни ВИНАГИ когато имаш механичен бутон ей така за късмет слагай по един delayms(50) че и повече за да избегнеш "претреперването" на пластинките :)
2.Ако искаш РА0 да ти стартира програмата тогава дефинирай едно флагче (да речем start) и го вдигай/сваляй при натиснат РА0;

while(1)
{
if(RA0==1) // ако има натиснат РА0
{
delay_ms(50);
start=!start;//тук вдигаш или сваляш флагчето
}
while(start) {//циклиш докато ти е вдигнато флагчето т.е. стартирал си си програмката :)
if(RB1){
delay_ms(50);
RA1=!RA1; //не помня можеше ли по този начин да четеш регистъра едновременно за вход и изход ... но образно казано това е "трика" , ако не можеш по този начин просто си дефинирай по едно флагче за всеки пин и си го манипулирай .
}
......... /// за четирите бутона еднакво
}
}

има и много по оптимални начини но за насока и ориентир се надявам да съм помогнал :)

Автор:  maguss4o [ Вто Фев 11, 2014 12:28 am ]
Заглавие:  Re: PIC16f628A програма

valioman написа:
Не знам на ... за насока и ориентир се надявам да съм помогнал :)


Здравей,
на 18 съм и те първа почвам да му го уча електрониката. Все още съм в гимназия, но специалността, която съм си избрал за ВУЗ-а ми се налага да уча и електроника та си и падам по програмирането и реших поне да имам някакви знания за PIC-овете и как се управляват.

С 2 изречения това, което се стремя да направя. Двете програми да работят разделено и в зависимост от настиснатото копче /RA6, RA0/, да се изпълнява съответната програма. След изпълняване на програмата при повторно натискане да се изпълнява отново.
- Добре това има по-лесен начин да го направя, след като се изпълнят програмите да ресетвам PIC-а и отново да гледам, кое копче ще бъде натиснато, но не искам така...

Опитах по твоя начин и никакъв напредък :(

Код:

void prog1(){
    if(RA6==1){
        delayS(1);
        while(RA6==1){
            if(RA6==1){
                RA7=1;

            }else{
                RA7=0;
            }
        }
    }
}

void prog2(){
    RA1=1;RA2=1;RA3=1;RA4=1;
    while(RB1==0 || RB2==0 || RB3==0 || RB4==0){
        if(RB1==1 && RA1==1){
            __delay_ms(50);
            RA1=0;
        }
        if(RB2==1 && RA2==1){
            __delay_ms(50);
            RA2=0;
        }
        if(RB3==1 && RA3==1){
            __delay_ms(50);
            RA3=0;
        }
        if(RB4==1 && RA4==1){
            __delay_ms(50);
            RA4=0;
        }
    }
}

int main(int argc, char** argv) {
    TRISA = 0b01100001;
    TRISB = 0b00011110;
    PORTA = 0x00;
    PORTB = 0x00;
    OSCF = 1; //OSC FREQUENSY AT 4MHZ

    int startL=0, startW=0;
    while(1){
        if(RA6==1){
            __delay_ms(50);
            startL=!startL;
        }
        while(startL){
            prog1();
        }
        if(RA0==1){
            __delay_ms(50);
            startW=!startW;
        }
        while(startW){
            prog2();
        }
    }
   

    return (EXIT_SUCCESS); //RETURN TO BUILDER SUCCESS
}



Изображение

Автор:  valioman [ Вто Фев 11, 2014 12:43 am ]
Заглавие:  Re: PIC16f628A програма

Обатачил си се повече :) .. сега дай да подкараме едната па после мисли за втора "подпрограма"
та по първата .
Дефинирай 4 променливи от тип boolean
да речем b1,b2,b3,b4 ı edna startW

в основния while нищо не пипай само махни
if(RA6==1){
__delay_ms(50);
startL=!startL;
}
while(startL){
prog1();
}

засега ... пък после щ еги включваш но по малко по елегантен начин .

сега да помислим за prog2()

няма смисъл вътре да въртиш цикъл защото while(startW)..... ти го прави
сега да помислим .... като натиснем бутон РБ1 искаме да светнем или угаснем РА1. Приемаме ,че променливата "флаг" b1 ти е състоянието на изхода РА1 т.е. когато направиш РА1=b1; това значи че каквото е състоянието на b1 (1 или 0) това щ ее и на изхода.
накратко

if(RB1==1){ //натиснат бутон
delayms(50); //трепкането
b1=!b1; //смяна на нсъстоянието на флагчето т.е. това е еквивалентно на израза if(b1==1)b1=0;else b1=1;
RA1=b1; //присвояване стойността на флагчето на пин-а
} // и така за 4 те пина

Автор:  Vesko [ Вто Фев 11, 2014 6:58 am ]
Заглавие:  Re: PIC16f628A програма

RA1 = !RA1;
Не работи ли?

Автор:  TheWizard [ Вто Фев 11, 2014 8:44 am ]
Заглавие:  Re: PIC16f628A програма

порта(GPIO вход) го ползвай за четене, а LAT-а за запис (GPIO изход)

Автор:  Wise [ Вто Фев 11, 2014 10:23 am ]
Заглавие:  Re: PIC16f628A програма

Не съм пикльофен, но си мисля, че това ще ти е от полза
http://www.mikroe.com/products/view/285 ... ming-in-c/

Автор:  maguss4o [ Вто Фев 11, 2014 10:50 am ]
Заглавие:  Re: PIC16f628A програма

valioman написа:
Обатачил си се повече :) .. сега дай да подкараме едната па после мисли за втора "подпрограма"
та по първата .
Дефинирай 4 променливи от тип boolean
да речем b1,b2,b3,b4 ı edna startW

в основния while нищо не пипай само махни
if(RA6==1){
__delay_ms(50);
startL=!startL;
}
while(startL){
prog1();
}

засега ... пък после щ еги включваш но по малко по елегантен начин .

сега да помислим за prog2()

няма смисъл вътре да въртиш цикъл защото while(startW)..... ти го прави
сега да помислим .... като натиснем бутон РБ1 искаме да светнем или угаснем РА1. Приемаме ,че променливата "флаг" b1 ти е състоянието на изхода РА1 т.е. когато направиш РА1=b1; това значи че каквото е състоянието на b1 (1 или 0) това щ ее и на изхода.
накратко

if(RB1==1){ //натиснат бутон
delayms(50); //трепкането
b1=!b1; //смяна на нсъстоянието на флагчето т.е. това е еквивалентно на израза if(b1==1)b1=0;else b1=1;
RA1=b1; //присвояване стойността на флагчето на пин-а
} // и така за 4 те пина



При натискане на RA0 светват RA1,RA2,RA3,RA4 и чак когато се натисне RB1,RB2,RB3,RB4 се изгася съответния светодиод. При натискане на RA0 програмата се повтаря, а не когато натисна RB1-4 да светват и изгасят диодите. Целта е винаги да изгасят ако са светнати..

Автор:  valioman [ Вто Фев 11, 2014 11:21 am ]
Заглавие:  Re: PIC16f628A програма

Е това е друга бира тогава :) но принципа е същия .
while(1){
if(RA0==1){
delayms(50);
startW=!startW;
RA1=RA2=RA3=RA4=startW;//swetwame/izgasiame wsichki
}
if(startW){
if(RB1){delayms(50);RA1=0;}//pri natiskane gasim syotwetnia
........//// i taka za wsichki
}
}

Дано захапа идеята на променливите и логиката на работа .
Протеуса има едно много хубаво нещо а именно ,че можеш да дебъгваш т.е. задай вместо .hex -> .cof файла и после с brekpoints i F10 можеш да си се движиш по кода и да си гледаш стойности на променливите и регистрите и да видиш постъпково как се изпълнява програмата ти и какво се случва на всеки един ред ;)

Автор:  Vesko [ Вто Фев 11, 2014 11:37 am ]
Заглавие:  Re: PIC16f628A програма

valioman написа:
Е това е друга бира тогава :) но принципа е същия .
while(1){
if(RA0==1){
delayms(50);
startW=!startW;
RA1=RA2=RA3=RA4=startW;//swetwame/izgasiame wsichki
}
if(startW){
if(RB1){delayms(50);RA1=0;}//pri natiskane gasim syotwetnia
........//// i taka za wsichki
}
}

Дано захапа идеята на променливите и логиката на работа .
Протеуса има едно много хубаво нещо а именно ,че можеш да дебъгваш т.е. задай вместо .hex -> .cof файла и после с brekpoints i F10 можеш да си се движиш по кода и да си гледаш стойности на променливите и регистрите и да видиш постъпково как се изпълнява програмата ти и какво се случва на всеки един ред ;)

Така написана програмата докато е натиснат бутона на РА0 StartW, ше прави тогъл през 50mS. И при отпускане, ще е гадаене в какаво състояние ще е. И също така ако целта е просто при натискане на RBx съответният диод да изгасне закъснението от 50мС е излишно. Може би нещо подобно:

x = RB1;
while(1)
{
delayms(20);
x1 = RB1;
if(x!= x1)
{
x = x1;
start = !start;
}
if(start)
{
if(RB1)
RA1 = 0; // led off
}
else
RA1=RA2=RA3=RA4=1; // all off
}

Автор:  valioman [ Вто Фев 11, 2014 12:04 pm ]
Заглавие:  Re: PIC16f628A програма

Начини и мераци много ... :) разбира се че на практика ще трябва да се сложат подходящите закъснения и полирания но за виртуални тестове на рпотеус не са критични . Аи доколкото виждам детето не може да оправи битовете а ние искаме времена да смята ;) . Едно по едно ... най лесно е да му се напише наготово ама не е това целта .

Автор:  maguss4o [ Вто Фев 11, 2014 6:54 pm ]
Заглавие:  Re: PIC16f628A програма

valioman написа:
Начини и мераци много ... :) разбира се че на практика ще трябва да се сложат подходящите закъснения и полирания но за виртуални тестове на рпотеус не са критични . Аи доколкото виждам детето не може да оправи битовете а ние искаме времена да смята ;) . Едно по едно ... най лесно е да му се напише наготово ама не е това целта .


Здравей, не искам да се хваля но съм се занимавал с програмиране, мога да чета код всякакъв и да го разбирам. Отделно от това се занимавам и с правенето на сайтове и мога да разсъждавам логично, кое как преди кое трябва да стане, но като почнах пиковете, явно моят начин на логическо мислене не съвпада с техния :D. Така че, за мен няма никакво значение дали ще бъде цял код или отделни сегменти подсказани. Аз още от началото разбрах, че не сте ме разбрали какво се мъча да направя, но ще дойде сетния старт на програмата, че когато натисна START в протеуса да няма бъг ;d Все още не съм го направил. Ще видя довечера или утре, ще се помъча още малко. Все пак Ви благодаря много :)

Автор:  maguss4o [ Пет Мар 07, 2014 8:12 pm ]
Заглавие:  Re: PIC16f628A програма

Изведнъж музата ми дойде и седнах да го оправя кода, ся всичко бачка ;) Реших да го направя по най-елементарния начин за мен. Благодаря на всички Ви за времето, което оделихте за мен (:

Код:
void delayS(int s){
    for(int i=0; i<s; i++){
        //RA0 = 1;
        __delay_ms(400);
       // RA0 = 0;
        __delay_ms(400);
    }
}

void prog1(){
   delayS(1);
   int chek=0;
   while(chek==0){
      if(RA6==1){
         RA7=1;
      }else{
         RA7=0;
         chek=1;
      }
   }
}

void prog2(){
    RA1=1;RA2=1;RA3=1;RB0=1;
    int chek=0;
    while(chek==0){
        if(RB1==1 && RA1==1){
            RA1=0;
        }else if(RB2==1 && RA2==1){
            RA2=0;
        }else if(RB3==1 && RA3==1){
            RA3=0;
        }else if(RB4==1 && RB0==1){
            RB0=0;
        }else if(RA1==0 && RA2==0 && RA3==0 && RB0==0){
            chek=1;
        }
    }
}

int main(int argc, char** argv) {
    TRISA = 0b01100001;
    TRISB = 0b00011110;
    PORTA = 0x00;
    PORTB = 0x00;
    OSCF = 1; //OSC FREQUENSY AT 4MHZ

    while(1){     
        if(RA0 == 1){
            prog2();
        }
        if(RA6==1){
            prog1();
        }   
    }
    return (EXIT_SUCCESS); //RETURN TO BUILDER SUCCESS
}


Изображение

Автор:  ToHu [ Съб Мар 08, 2014 7:37 pm ]
Заглавие:  Re: PIC16f628A програма

Без да се засягаш, но каквото и да си писал явно е било далеч от истината ..
while(chek==0) избягвай такива цикли, както казаха колегите варианти има много, един от най-удобните е прекъсване, но дори и с полиране да е пак е по добре от този безкраен while който ако забелязваш може да те държи вътре безкрайно дълго време. От друга страна ако WDT като му изтече времето ще те рестартне .. и от там насетне нкой не зна екакво ще стане.

Автор:  rikotech [ Нед Мар 09, 2014 4:03 pm ]
Заглавие:  Re: PIC16f628A програма

ToHu, без да се засягаш ама аргументите са ти "майко мила". Какво значи while може да го държи вечно? Естествено че може, докато е изпълнено условието check == 0. По този начин maguss4o остава в цикъла на prog1, prog2. Но maguss4o много хитро е направил и условие за излизане от така наречения от теб "вечен цикъл", и това условие е:
Код:
else if(RA1==0 && RA2==0 && RA3==0 && RB0==0){
            chek=1;
        }

А това за WDT e направо ъпсурд. След като се рестартне процесора е абсолютно ясно къде ще отиде. Има едно нещо наречено reset vektor, ако погледнеш datasheet ще видиш че при рестарт няма "кой знае какво ще стане". Има точно определен адрес от програмната памет "който ще стане :D"

maguss4o много добре за начало! Като за образувателна цел програмката е супер!

Страница 1 от 3 Часовете са според зоната UTC + 2 часа [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/