[ mzm @ 16.03.2016. 00:21 ] @
Pozdrav dobri ljudi. Zovem se Milos i zivim u Trsteniku. Imam 33 god. i bavim se remontom kocne tehnike na autobusima i kamionima. Elektronika me zanima jos od detinjstva pa sam kao mladi srednjoskolac pravio razna prosta el. kola (audio pojacala, ac-dc ispravljace, disco light ...). Posle sam poceo da trcim za suknjicama i potpuno batalio taj hobi.
Kako se kocioni sistemi ubrzano razvijaju i elektronika (mikrokontroleri) se i tu potpuno integrisala odlucio sam da naucim vise o tome. Procitao sam nekoliko raznih tekstova o mcu i brzo sam ukapirao mnoge stvari. Poceo sam sa PIC-ovima i radim u MPLAB-u sa njihovim kompajlerima. Trenutno sve isprobavam u Proteusu ali uskoro mi stize originalan PICKIT 3.
Jos sam na pocetku i sada se upoznajem sa interrupt-ima. Uspesno sam odradio external interrupt samo pracenjem datasheet-a i objasnjenja naredbi.
Trenutno sam zapeo sa interrupt-om na promeni stanja. U proteusu kada se dogodi interrupt program se zaglavi u interrupt rutini. Za mcu sam izabrao 16f877a. Gde gresim, ne mogu da provalim.

PS: mrzelo me da pisem komentare jer ludim sto ne mogu da ga nateram da radi kako treba.

Code:


// PIC16F877A Configuration Bit Settings

// 'C' source line config statements

#include <xc.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = ON         // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)


#define _XTAL_FREQ 8000000
#define LED0 RA0
#define LED1 RA1


 void interrupt irs(){
     INTCONbits.RBIF=0;
     
        int i;
        for(i=0;i<20;i++){
        LED1=1;
        }
        
}

void main(void){
    
    INTCONbits.GIE=1;
    INTCONbits.RBIE=1;
    INTCONbits.RBIF=0;
    
    
    ADCON1=0b11111111;
    TRISA=0b00000000;
    TRISB=0b11111111;
    
    PORTA=0;
    
    
    while(1){
                 
        LED0=1;
        __delay_ms(200);
        LED0=0;
        __delay_ms(200);
     
       
    }
}


[Ovu poruku je menjao mzm dana 16.03.2016. u 01:37 GMT+1]

[Ovu poruku je menjao mzm dana 16.03.2016. u 01:39 GMT+1]
[ Urke92 @ 16.03.2016. 07:36 ] @
Moras da clearujes interrupt flag INTCON.INTF=0; u svojoj interapt rutini.

Pogledaj ovaj sajt:
https://electrosome.com/interrupt-pic-microcontroller/
[ mzm @ 16.03.2016. 09:44 ] @
Zar nije INTF i INTE za external interrupt na RB0, a RBIF i RBIE za interrupt on change na RB4-RB7?
[ goran_68 @ 16.03.2016. 10:46 ] @
Iz datasheet-a
"A mismatch condition will continue to set flag bit RBIF.
Reading PORTB will end the mismatch condition and
allow flag bit RBIF to be cleared."


Pre nego obrišeš RBIF pročitaj PORTB. Za svaki slučaj pročitaj ga dva puta jer koliko se sećam ti stariji PIC MCU imaju bug. Pogledaj i errata moguće da ima nešto o tome.
[ mzm @ 18.03.2016. 00:12 ] @
Jos uvek mi ne polazi za rukom ono sto hocu. Ovo bi trebalo da procita stanje na PORTB i da ponisti flag.

Code:
void interrupt blink(){
    unsigned char y;
    PORTB=y;
    
    
    INTCONbits. RBIF=0;


edit:

Sad radi uz izmenu koda. Hvala goran_68 na pomoci.
Code:
unsigned char y;
 

void interrupt blink(){
   
    y=PORTB;
    
    
    INTCONbits. RBIF=0;


[Ovu poruku je menjao mzm dana 18.03.2016. u 09:58 GMT+1]

[Ovu poruku je menjao mzm dana 18.03.2016. u 09:59 GMT+1]
[ mzm @ 27.03.2016. 01:18 ] @
Kako da izvedem da na jednom kontroleru imam vise "on change interrupt" i da svaki interrupt ima razlicit zadatak , konkretno za PIC16F688? Treba mi objasnjenje pa da probam sam da uradim.
Nasao sam microchip uputstvo ali kod je za assembler pa ne mogu da se snadjem.

[ bogdan.kecman @ 27.03.2016. 01:27 ] @
zavisi od kontrolera do kontrolera
PIC16F688 nema prioritete, znaci svi interapti su istog prioriteta, imas
externi interapt na pinu 11 i imas interrapt on change na pinovima
13,12,4,3 i 2. za IOC interapt (on change) ti moras da znas koji ti se
promenio - procitas sadrzaj novih uporedis sa sadrzajem koji si snimo na
prosli interapt i znas koji su razliciti
[ goran_68 @ 27.03.2016. 08:49 ] @
Napiši šta konkretno želiš da uradiš (4x4 tastatura možda?) i daj taj Microchip primer pa da ti predložim šta i kako.
[ mzm @ 27.03.2016. 19:16 ] @
Jos uvek sam na interrupt-ima pa hocu da naucim kako se resava da ima vise takvih interrupt-a.
A ideja mi je da se pritiskom na svaki taster pale led diode razlicitim redosledom (da, kao tastatura). Primer na adresi www.microchip.com
[ goran_68 @ 28.03.2016. 07:27 ] @
U prekidnoj rutini, ukoliko je postavljen RBIF, pročitaš stanje na portu B i uporediš ga sa prethodno pročitanim (u primeru je to promenljiva LASTPB). Nakon toga proveravaš na kom se pinu dogodila promena upoređivanjem ove dve vrednosti i u zavisnosti od toga odrađuješ posao koji si namenio pojedinačnim tasterima. Kad obradiš tastere, poslednje pročitano stanje porta B smeštaš u promenljivu LASTPB čime si se pripremio za novi prekid. Na kraju obrišeš RBIF i to je to.
[ mzm @ 03.04.2016. 22:43 ] @
Nisam bio tu nekoliko dana pa nisam mogao da probam. Iskreno nikakva ideja mi ne pada na pamet. Moze li jedan primer u C da ga prostudiram.
[ mzm @ 10.04.2016. 17:17 ] @
Probao sam nesto kako mislim da treba ali nije dobro. Registruje samo interrupt na RA0. Gde gresim?

Code:
void interrupt isr()
{
    
    
    test=PORTA;
    
    
    if(RA0==1)   
        RC1=1;   
    else if(RA1==1)
        RC2=1;
    else if(RA2==1)
        RC3=1;
    
  
    RAIF=0;
    
    }  
    
void main()
{
    
      
    TRISA=0xFF;
    ANSEL=0x00;
    CMCON0=0xFF;
    TRISC=0x00;
    PORTC=0x00;
    
    GIE=1;
    RAIE=1;
    RAIF=0;
    IOCA=1;
[ goran_68 @ 11.04.2016. 07:20 ] @
Nije ti dobra ova linija u kodu:
Code:
IOCA = 1;



Ovim si omogućio samo prekid sa pina RA0. Zato se tako i ponaša.
Za ono što želiš treba da bude:

Code:
IOCA = 7;

[ mzm @ 11.04.2016. 12:41 ] @
Znao sam da je neka sitnica. Ja sam razumeo sam da se pise IOCA1, IOCA2, IOC3 itd. kada se konfigurise svaki pin posebno.
Hvala puno. Sad sljaka kao sat.

[Ovu poruku je menjao mzm dana 11.04.2016. u 15:08 GMT+1]
[ mzm @ 06.05.2016. 00:14 ] @
Evo mene ponovo. Jos uvek se zanimam sa interrupt-ima. Sada hocu da uradim da kada se desi IOC led dioda blinkne X puta sa pauzom od Y ms. Koriscenjem delay-a u ISR-u sam to postigao ali bih hteo da izbegnem delay zbog svojih mana. Koriscenje TMR0I mi je jasno ali ne znam kako da spojim sa IOC.
[ goran_68 @ 06.05.2016. 06:37 ] @
Kada se desi IOC uključi TMR0 tako da generiše prekid na Yms. Na svaki TMR0 brojiš do X. Kada X dostigne zadatu vrednost onemogući TMR0 i zaustavi ga. Pa sve iznova.
[ mzm @ 08.05.2016. 23:11 ] @
Probao sam ovako ali ne radi. Preskaler je 1:256 a frek. je 4 MHz.
Code:
if(RA1==1){
        TMR0IE=1;
        if(TMR0IF==1){
        ++counter;
        
        if(counter==15){
            counter=0;
            TMR0IE=0;
        RC2=~RC2;
        }
        }
        }
        RAIF=0;

Ipak sam uspeo ono sto sam zamislio.
Code:

void interrupt isr()
{
    
    
    test=PORTA;
    
    
    if(RA1==1){
        TMR0IE=1;
        RC2=1;}
        while(TMR0IF){
            TMR0IF=0;
        ++counter0;
        }
        if(counter0==7){
            ++counter1;
            RC2=~RC2;
            counter0=0;
        }
         if(counter1==5){
        counter1=0;
        TMR0IE=0;
        RAIF=0;
    
        }
    

     /*if(RA0==1){
        RC1=1;
        __delay_ms(300);
        RC1=0;
    }
    else if(RA2==1){
        RC3=1;
         __delay_ms(300);
         RC3=0;
    }
  
    
    RAIF=0;*/
    }  


[Ovu poruku je menjao mzm dana 09.05.2016. u 01:20 GMT+1]

[Ovu poruku je menjao mzm dana 09.05.2016. u 01:21 GMT+1]

[Ovu poruku je menjao mzm dana 09.05.2016. u 01:21 GMT+1]
[ goran_68 @ 09.05.2016. 07:18 ] @
Nije dobro jer stojiš u prekidnoj rutini bez potrebe. Kod radi ali princip nije dobar. Ovaj deo ne valja:

Code:

while(TMR0IF){
            TMR0IF=0;
        ++counter0;
        }


Prekidna rutina mora da sadrži i deo za obradu TMR0 prekida.
[ mzm @ 10.05.2016. 21:38 ] @
Ako imas vremena napisi na brzinu kako treba da bude taj deo.

[Ovu poruku je menjao mzm dana 10.05.2016. u 23:30 GMT+1]
[ mzm @ 10.06.2016. 22:52 ] @
Dosao sam na ideju da napravim za auto daljinsko spustanje bocnih stakala. Predvideo sam tako da kada se pritisne taster dva puta za neko vreme (npr. 2 sec) spustanje se aktivira dok se stakla skroz ne spuste. Kako nemam senzor krajnjeg polozaja stakla moracu da izmerim vreme potrebno za spustanje pa da primenim u kodu. Ako se samo jednom pritisne taster i u roku od dve sekunde ne pritisne ponovo sve se resetuje i krece ponovo.
Evo i kod koji sam probao u proteusu i radi ali bih zeleo da neko iskusan baci pogled i kaze da li sam pravilno napisao.

Code:


// PIC16F688 Configuration Bit Settings

// 'C' source line config statements

#include <xc.h>


// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select bit (MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown Out Detect (BOR enabled)
#pragma config IESO = ON        // Internal External Switchover bit (Internal External Switchover mode is enabled)
#pragma config FCMEN = ON       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)

#define _XTAL_FREQ 4000000
int i,j,k=0;

void interrupt ISR()
{
   if (INTF)
   {
   i++;
   INTF=0;
   }
   else if(TMR0IF)
   {
       j++;
       TMR0IF=0;
   }
   else if(TMR1IF)
   {
       k++;
       TMR1IF=0;
   } 
       
}
   


void main()
{
TRISA=0x04; //Pin A2 ulazni, ostali izlazni
TRISC=0x00; //Port C izlazni
ANSEL=0x00; //Analogni ulaz iskljucen
CMCON0=0x07; //Iskljuceni komparatori
PORTC=0x00; //Port C 0v

GIE=1; //Ukljuceni prekidi
INTE=1;//Ukljucen spoljni prekid
INTF=0;//Prekidna zastava ponistena
INTEDG=1;//Prekid sa 0 na 1

TMR0IE=0; //Ukljucen prekid za Timer 0
TMR0IF=0; //Timer 0 zastava 0
T0CS=0; //Interni oscilator za Timer 0
PSA=0; //Preskaler dodeljen Timer-u 0
PS0=1; //
PS1=1; //Preskaler 1:256
PS2=1; //
TMR0=4;//Brojanje krece od 4


TMR1CS=0;
TMR1ON=1;
TMR1IE=0;
PEIE=1;
TMR1IF=0;
T1CKPS0=0;
T1CKPS1=1;
TMR1=18661;

while(1)
{
    if(i==1)
    {
       TMR1IE=1;
    }
    
    
    if(k==8)
    {
        i=0;
        k=0;
        TMR1IE=0;
    }
    
    if(i==2)
    {
        i=0;
        j=0;
        k=0;
        RC0=1;
        TMR0IE=1;
        TMR1IE=0;        
    }
    else if(j==31)
        {
            j=0;
            TMR0IE=0;
            RC0=0;
        }
     
            
}
}


[Ovu poruku je menjao mzm dana 11.06.2016. u 01:46 GMT+1]

[Ovu poruku je menjao mzm dana 11.06.2016. u 01:54 GMT+1]
[ bogdan.kecman @ 11.06.2016. 02:25 ] @
ne treba da radis sa vremenom nego stavi shunt na motor i meri struju
kroz motor i kad struja "poskoci" stigao si do kraja
[ goran_68 @ 11.06.2016. 06:49 ] @
Dobro je, savladao si prekide. Inicijalizacija treba da ide malo drugačijim redosledom:

Code:


INTF=0;//Prekidna zastava ponistena
INTEDG=1;//Prekid sa 0 na 1
INTE=1;//Ukljucen spoljni prekid

TMR0IF=0; //Timer 0 zastava 0
TMR0IE=0; //[b]Iskljčen[/b] prekid za Timer 0
T0CS=0; //Interni oscilator za Timer 0
PSA=0; //Preskaler dodeljen Timer-u 0
PS0=1; //
PS1=1; //Preskaler 1:256
PS2=1; //
TMR0=4;//Brojanje krece od 4

TMR1IF=0;
TMR1IE=0;
TMR1CS=0;
T1CKPS0=0;
T1CKPS1=1;
TMR1=18661;
TMR1ON=1;

PEIE=1;
GIE=1; //Ukljuceni prekidi


Radiće, ali bi morao bi da meriš struju ukoliko misliš da ovo realizuješ.
[ mzm @ 12.06.2016. 10:50 ] @
Ok. Hvala.
Ako sam dobro razumeo ja cu morati da merim pad napona na krajevima shunt otpornika i da taj napon prvo pojacam pa pustim na analogni ulaz kontrolera i kada motor dodje u krajnji polozaj dolazi do promene struje (i napona) i tada komparator aktivira prekid koji iskljucuje motor.
[ veselinovic @ 12.06.2016. 11:47 ] @
Moze tako, a moze i analogni komparator pa da se signal proslijedi na digitalni ulaz uC.
Lakse, brze i elegantnije.
[ mzm @ 12.06.2016. 13:10 ] @
Misliš na zasebni analogni komparator?
[ veselinovic @ 12.06.2016. 16:17 ] @
Da.
Svakako je pametno na taj sent nakaciti neki OP, da pripremi signal sa senta u podrucje 0-5V.
Zasto onda ne iskoristiti taj OP pa napraviti komparator napona sa senta.
Onda izlaz komparatora vodis u uC kojeg oslobodis dodatnog racunanja.