I am trying to use an interrurpt using RTI module in CRG. The interrupt must keep track of minute and second
elapsed since the start up. The port t bit 7 must set up as an output and toggled every 0.5 ms.
This is how i calculated the prescaler needed :
period = 1/oscClk*prescaler
prescaler = 0.5/(1/16Mhz)
prescaler = 8000000
However, the maximum value for the prescaler is 1048576.
Did i do anything wrong with the calculation?
Do i have to use modulus counter?
The modulus counter will be used to generate periodic interrupt every 2 seconds, so i don't think i can use the modulus
counter there.
the function looks like this
void CRG_SetupRTI(const UINT8 prescaleRate, const UINT8 modulusCount)
Yep i got it... i made this code:
void CRG_SetupRTI(const UINT8 prescaleRate, const UINT8 modulusCount)
{
PORTE_BIT4 = 0;
DDRE_BIT4 =1;
RTICTL = prescaleRate; //prescaleRate is 16384, period = 1.024
CRGINT_RTIE = 1; // enable RTI
counter = 0; // global variable showing how many intterupts were executed
asm cli; // enable interrupts
}
void interrupt RTI_ISR(void)
{
CRGFLG_RTIF = 1;
if(counter == 500)
{
PORTE_BIT4 = 1;
}
else
{
count++;
}
PORTE_BIT4 = 0;
}
I made the period 1.024 and then in the RTI_ISR function, count till 500.
500 x 1.024 = 512
Is this correct?
Does that make the LED toggled approximately every 0.5s?
If so, how do you keep track of the elapsed time?
I'm thinking using PORT T bit 0 and toggle the output of the Port
so it can update the clock?
How do you use a modulus counter to provide a periodic intterupt every 2ms?
I know how the modulus counter works but i don't know how long the system will
take to count for example from 100 counts to 0.
I am using MC9s12 with 16Mhz crystal (oscillator clock)
MC9S12 is not enough. You should mention letters past 12, for example S12C, S12XD etc. S12XD RTI has decimal clock prescaler mode, older families don't have such mode, etc.
Your code has few bugs:
1) You should reset count in ==500 case,
2) you are not toggling port pin, but pulsing it high for less than microsecond.
3) pin pulsing period is going to be 501 RTI periods. When count reaches 500 and you reset it, you exit ISR. But when you reenter ISR one RTI period later, this one period is not counted. So either chnge your code to if(count == 500-1) or maybe change the logic like this
isr()
{
count++;
if(count == 500)
{
PORTE ^= (1<<4);
count = 0;
}
}
4) The ay you clear RTI flag has side effects, which certainly will bite you sooner or later. You are clearing all flags in CRGFLG register, not just RTIF. To clear only RTIF you shoud CRGFLG = CRGFLG_RTIF_MASK;
If you are going to toggle pin on port T, then why are you pulsing pin port E?
Does that make the LED toggled approximately every 0.5s?
If so, how do you keep track of the elapsed time?
Do you mean how to count seconds? The's number of ways to do this. You may sum all milli- and microseconds like 1024us+1024us+ etc and convert microseconds to seconds and minutes. You may also try to find prescaler so that integer number of RTI periods will take exactly 1s. For this at 16MHz oscilator clock 1024 and 5120 prescalers are available. 5120 presclaer gives RTI period if 320us, 320us *3125 = 1s.
How do you use a modulus counter to provide a periodic intterupt every 2ms?
I know how the modulus counter works but i don't know how long the system will
take to count for example from 100 counts to 0.
Do you mean you don't know what clock modulus down counter is operating at? It's bus clock (which is half of oscilator clock).
You should to mention what device are you talking about.
You want to toggle pin every 0.5ms, but are calculating required prescaler for 0.5s.
For long periods you could setup RTI to fire for example every 100ms and toggle pin on every 5th RTI interrupt.