Real Time Interrupts Section 4.15
Real-Time Interrupt (RTI) Most operating systems (OS) require an interrupt every T seconds by the RTI RTI interrupts are often counted to determine time and date (XP, LINUX) OS use RTI interrupts for process scheduling IBM PC is interrupted 18.2 times per second by RTI
Real-Time Interrupt Two Bits of Interest –RTIE – Real-Time Interrupt Enable “0” – Disables Interrupts “1” – Enables Interrupts –RTIF – Real-Time Interrupt Flag Set every T Seconds when RTIE=“1” Generates Maskable Interrupt when “1” Write “1” to RTIF to Clear Flag
Real Time Interrupt 68HC12DP256 Set Up and Controlled using 3 Registers: –RTICTL –CRGINT –CRGFLG
Clock Generator Lab Processor Boards uses a 4 MHz Crystal Oscillator Frequency of Bus Clock (ECLK) – 2 MHZ RTI uses the 4 MHZ Crystal Clock
4 MHZ SETS RTI FLAG Prescaler: Divides by 1, 2, 4, 8, 16, 32, or 64 Divides by 1, 2, 3, 4, 5, 6,, 16
Divide 4 MHZ Clock by: 1024 AND BY 1 or 2 or 4 or 8 or 16 or 32 or 64 (Selected by RTR[6:4]) AND BY 1 or 2 or 3 or 4 or 5 or 6 or 7 or 8 or 9 or 10 or 11 or 12 or 13 or 14 or 15 or 16 (Selected by RTR[3:0]) to generate rate of RTI Timeout Output.
Real Time Interrupt Enable
Real Time Interrupt Flag Power-On Reset Flag Self-check Mode Interrupt Flag
Real Time Control Register
/* rtc1 = RTR[6:4], rtc = RTR[3:3] frti = Frequency of RTI */ int rtc1, rtc2; float frti; rtc1 = (RTR>>4)&0x07; rtc2 = RTR&0x0F; if(rtc1==0) frti=0; else frti = /(1024*(1<<(rtc1-1))*(rtc2+1)) Frequency of RTI
Init prescale factor in RTICTL Enable RTIE in CRGINT Reset RTIF in CRGFLG Enable maskable interrupts ENABLE(); CRGFLG
Text RTI Example RTI Interrupt every msec. E Clock is 4 MHZ RTICTL is defined differently Divide E Clock by 2 raised to power 15 –RTR[6:4] = 6 –RTR[3:0] = 0 –RTICTL = 0x60 RTI Interrupt Vector Address = 0xFFF0
TEXT RTI Examples Replace #include with #include Replace interrupt #pragma code with –void RTI_isr() __attribute__ ((interrupt)); Replace init vector #pragma code but place inside of main program Initialize Interrupt Vectors with –SETVECT(0xFFF0,RTI_isr);
Text RTI Example Replace RITCTL=0x84 with Set Interrupt Frequency, enable RTI, clear RTI –RTICTL = 0x60; –CRGFLG=0x80; –CRGINT = CRGINT | 0x80; Replace RTIFLG=0x80 with Clear RTI Flag –CRGFLG = 0x80; Replace CLI() Enable Interrupts with –ENABLE();
/* Real Time Interrupt Example Program Page of Text Modified to Execute on Lab Microcontroller This program keeps track of clock time using the Real Time Interrupts. The RTI generates an interrupt ms. The RTI_isr keeps track of elapsed time. */ /* include files */ #include /* function prototypes */ void RTI_isr(void) __attributes__ ((interrupt)); /* global variables */ unsigned int ms_ctr, sec_ctr, mins_ctr, hrs_ctr, days_ctr;
void main(void){ ms_ctr = 0; // initialize timer variables sec_ctr = 0; mins_ctr = 0; hrs_ctr = 0; days_ctr = 0; /* initialize RTI - - replaces pragma abs_address, etc. */ SETVECT(0xFFF0,RTI_isr); // interrupt vector // Replace RTICTL = 0x84; RTICTL = 0x60; // set interrupt frequency CRGFLG=0x80; // clear RTI interrupt flag CRGINT = CRGINT | 0x80; // enable RTI /* Enable Interrupts – replace CLI() */ ENABLE(); while(1); // wait for interrupts }
/* RTI_isr: RTI Interrupt Service Routine */ void RTI_isr(void) { // replaces RTIFLG CRGFLG = CRGFLG | 0x80; /* update milliseconds */ ms_ctr = ms_ctr+1; /* update seconds */ if(ms_ctr == 122) /* counter equates 1000 ms at 122 */ { ma_ctr = 0; // reset millisecond counter sec_ctr = sec_ctr +1; // increment seconds counter
/* update minutes */ if(sec_ctr == 60) { sec_ctr = 0; // reset seconds counter mins_ctr = mins_ctr+1; // increments minutes counter } /* update hours */ if(mins_ctr == 60) { mins_ctr = 0; // reset minutes counter hrs_ctr = hrs_ctr + 1 // increments hours counter } /* update days */ if(hrs_ctr == 24) { hrs_ctr = 0; // reset hours counter days_ctr = days_ctr + 1; // increment days counter }