/*************************************************************************** * * * P R I M E R 4 C . C * * prikaz uporabe TMR0 in prekinitev PIC16x84 * * * *==========================================================================* * Verzija Datum Opis Avtor * *--------------------------------------------------------------------------* * 1 1997-12-26 Slavko M. * *==========================================================================* * * * OPIS: * * LED na PB0 utripa s periodo 1s. Zakasnitev je generirana s * * programsko zanko. Majn natanŸno. * * LED na PB7 pa tudi utripa s periodo 1s. Zakasnitev je generirana * * z delitvijo oscilatorjeve frekvence s pomoŸjo çtevca TMR0 in * * prekinitev. Bolj natanŸno. * * ¬asovna prekinitev: * * ætevec çteje urine impulze iz kvarc oscilatorja. Pri prekoraŸitvi * * oz 0xFF X 0x00 generira prekinitev (procesor prekine glavni * * program ter skoŸi na izvajanje prekinitvenega programa). Po konŸanju * * nadaljuje v glavnem programu na prekinjenem mestu. * * Takçne prekinitve sledijo v enakomernih ¬asovnih presledkih in * * so oporabne za izdelavo ure ali poljubnega natanŸnega Ÿasovnega * * intervala. * ***************************************************************************/ #include /* vkljuŸi datoteko s deklaracijami za PIC */ /* KONFIGURACUJSKI BAJT NA NASLOVU 0X2007 */ __CONFIG(_CP_ON & _PWRTE_ON & _WDT_ON & _XT_OSC); /* trenutno: _CP_ON -vkljuŸena zaçŸita vpisanega programa pred kopiranjem _PWRTE_ON - vkljucen "power up timer" _WDT_ON - vkljuŸen "watchdog timer" _XT_OSC - izbran kvarc osilator */ #define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit)) static bit LED_0 @ PORTBIT(PORTB,0); /* izhodni pin naj bo viden,*/ static bit LED_7 @ PORTBIT(PORTB,7); /* ,kot bitna spremnljivka */ static int irq_stevec; /* 16 bitni çtevec prekinitev, globalna sprem. */ /*********************/ /* I N T E R R U P T */ /*********************/ void interrupt timer(void) { /* interrupt je poklican vedno ko çtevec TMR0 odçteje do 0 */ T0IF = 0; if (--irq_stevec == 0) { irq_stevec = 1953; /* med irq-ji je 256micro sek, vzamemo 1953 prekinitev in dobimo 0.499968s. Napaka do 0.5s je 5sek/dan */ LED_7 = !LED_7; /* stanje izhoda LED_7 se invertira */ } /* konec if stavka*/ } /* vrnitev iz prekinitvenega programa */ /***********/ /* M A I N */ /***********/ main() { unsigned i; PORTA = 0; PORTB = 0; TRISB = 0x00; /* PORTB izhodi */ OPTION = 0x8F; /* predelilnik vkljuŸen na WDT = 2.3s */ irq_stevec = 1; /* zaŸetna vrednost */ LED_0 = 1; /* LED_0 na v prvi polperiodi gori */ INTCON = 0xA0; /* omogoŸi prekinitve iz TMR0 */ for(;;) { /* neskonŸna zanka */ CLRWDT(); /*zbriçe watchdog çtevec, da prepreŸi reset*/ for(i = 40900 ; --i ;) continue; /* zakasnitev za 0.5s */ LED_0 = !LED_0; /* stanje izhoda LED_0 se invertira */ } /*konec neskonŸne for zanke */ } /* konec funkcije main */