/*************************************************************************** * * * Programski primeri za 4 letnik - LAV * * * *==========================================================================* * Verzija Datum Opis Avtor * *--------------------------------------------------------------------------* * 1 1998-03-03 Slavko M. * *==========================================================================* * * * OPIS: * * Program prevzame timerjevo prekinitev 0x1C in jo usmeri v svoj * * prekinitveni program. * * LED0 na LPT portu krnili glavni program, LED7 pa prekinitveni program* * Oba se izvajata neodvisno in en za drugega ne vesta.* ***************************************************************************/ #include #include /*Globalne spremenljivke, ki so dostopne iz vseh podprogramov in prekinitvenih programov */ int inter = 0x1c; /*timerjeva prekinitev 18.2 krat na sekundo */ void interrupt irq_program(void); void interrupt (far *old_vect)(void); void interrupt (far *new_vect)(void); int port = 888; /* default port - standardni printerski izhod */ int irq_stevec; #define LED0 0x01 /*maske za dostop do posameznog botov*/ #define LED7 0x80 /* Rutine za delo s posameznimo biti na 8 bitnem portu*/ void Port_bit_na_0(char maska) { outportb(port,inportb(port) & ~maska); /*0 */ } void Port_bit_na_1(char maska) { outportb(port,inportb(port) | maska); /*1 */ } void Port_bit_invert(char maska) { if ((inportb(port) & maska) == 0) Port_bit_na_1(maska); else Port_bit_na_0(maska); } /**************************************************************************** * Rutina je timer interupt in se izvaja vsakih 1/18.2 [mikro sekund] ****************************************************************************/ void interrupt far irq_program(void) { outportb(0x21,inportb(0x21) | 0x01); /* onemogoci timerjeve prekinitve*/ /* Telo prekinitvenega programa*/ if (++irq_stevec == 9) { Port_bit_invert(LED7); irq_stevec = 0; } /* Konec telesa prekinitvenega programa*/ old_vect(); /* in izvedi staro INT rutino - VSAKIH 18.2 ms*/ outportb(0x21,(0xFE & inportb(0x21))); /*ponovno omogoci timerjeve prekinitve*/ } /*************************/ /* V K L J U C I _ I R Q */ /*************************/ void Vkljuci_irq(void) { /*Preusmeritev interruptov*/ outportb(0x21,inportb(0x21) | 0x01); /* onemogoci timerjeve prekinitve*/ old_vect = getvect(inter); /* prebere naslov stare rutine za to prekinitev*/ new_vect=irq_program; setvect(inter,new_vect); /* postavi novo rutino za timerjevo prekinitev*/ outportb(0x21,(0xFE & inportb(0x21))); /*ponovno omogoci timerjeve prekinitve*/ } /***************************/ /* I Z K L J U C I _ I R Q */ /***************************/ void Izkljuci_irq(void) { /*Nastavitev irq pointerja nazaj na staro vrednost*/ disable(); /* medtem onemogoci vse prekinitve */ setvect(inter,old_vect); /*vrni vektor INT 0x08 na staro vrednost*/ enable(); /* ponovno mogoci prekinitve */ } /***********/ /* M A I N */ /***********/ /* Glavni program */ void main() { /*inicializacija*/ irq_stevec = 0; /*zaŸetna vrednost */ outportb(port,0); Vkljuci_irq(); /* Nastavitev timerja in preusmeritev interruptov*/ /*telo glavnega programa*/ while ( !kbhit() ) { delay(500); /*500ms*/ Port_bit_invert(LED0); } /*konec telesa glavnega programa*/ Izhod: Izkljuci_irq(); /*Nastavitev timerja in irq pointerja INT 0x08 nazaj na staro vrednost*/ }