S12 Basic Timer System with RTI

advertisement
HC12 Basic Timer System
ME 4370/5370, ECE 4240
Introduction:
(From Cady and Sibigtroth, 2000). The M68HC12 timer system is based on the 16-bit freerunning counter called TCNT. This counter uses the M-clock (the system clock) as its source
and a prescaler of 1,2,4,8, or 16 to provide time information to the HC12. The prescaler can be
controlled by seting the three bits, PR2:PR0 in the Timer Interrupt Mask Register 2 (TMSK2)
(see the fig. below). The default setting is a prescaler of 1. The TCNT register can be read at
any time to provide this time information. When the register reaches a count of 65,536 pulses
($FFFF), the counter overflows and is reset to 0 ($0000). At this point, a timer overflow flag
(TOF) is set, which can be used to record longer periods of time. Note that with a 4 MHz clock
and a prescaler of 1, the timer will go from $0000 to $FFFF in 0.0164 seconds. The counter is
reset when the MCU is reset and runs continuously in general. The counter cannot be set when
the MCU is operating in normal mode. The following paragraphs describe the procedure to use
the timer in its most basic form.
Step 1: Turn on the timer: The timer is enabled by setting the MSB of the TSCR (timer system
control register).
TSCR1 -- $0006 – Timer System Control Register 1
Bit 7
TEN
Reset 0
6
TSWAI
0
5
TSBCK
0
4
TFFCA
0
3
0
0
2
0
0
1
0
0
bit 0
0
0
with
TEN: Timer enable; 0 disables the timer including TCNT (default, reduces power consumption),
1 enables the timer
TSWAI: Timer stops while in wait; 0 allows timer to continue running during a wait (default), 1
stops the timer while in wait mode.
TSBCK: Timer stops while in background mode (same as above).
TFFCA: Timer Fast Flag Clear All
Step 2: Set any timer prescaling as desired on TSCR2 (Timer interrupt mask register 2)
Timer System Control Register 2 (TSCR2)
TOI = Timer overflow interrupt enable (1 enables interrupt when timer overflow flag is set)
PR2, PR1, PR0 = Timer prescaler select bits prescale the module clock to achieve the main timer
counter according to the following table
1
TCRE: Timer counter resent enable (0, counter reset is inhibited and TCNT free runs, 1, TCNT
is reset to $0000 when a successful output compare occurs on timer channel 7)
Step 3: Clear the timer overflow flag in TFLG2 (Timer interrupt flag 2) register (if needed)
TFLG2 -- $008F – Timer Interrupt Flag 2
Bit 7
TOF
Reset 0
6
0
0
5
0
0
4
0
0
3
0
0
2
0
0
1
0
0
bit 0
0
0
TOF: Timer Overflow Flag. This bit is set when the TCNT register count goes from $FFFF to
$0000. The timer overlow bit is reset by writing a one to bit-7 of TFLG2.
Step 4: Read the current time (contained in TCNT, timer count register), or count timer
overflows (contained in TFLG2 register).
TCNT -- $0084:0085 – Timer Count Register
Bit 7
15
7
Reset 0
6
14
6
0
5
13
5
0
4
12
4
0
3
11
3
0
2
10
2
0
1
9
1
0
bit 0
8
0
0
Notes:
1) When timing via counting overflow flags, the TOF can be observed with polling or
interrupts. Once a TOF is counted, be sure to reset it by writing to this bit (bit 7 in
TFLG2).
2) If no prescale is used, then a TOF occurs every 8.19 ms (with 8MHz clock)
2
Real Time Interrupt
CRGINT –CRG Interrupt Enable Register
Bit 7
RTIE
Reset 0
6
0
0
5
0
0
4
LockiE
0
3
0
0
2
0
0
1
SCMIE
0
bit 0
0
0
2
RTR2
0
1
RTR1
0
bit 0
RTR0
0
RTIE – Real Time Interrupt Enable
0 = Interrupt request from RTI are disabled
1 = Interrupt will be requested whenever RTIF is set
RTICTL –CRG RTI Control Register
Bit 7
0
Reset 0
6
RTR6
0
5
RTR5
0
4
RTR4
0
3
RTR3
0
3
system clock;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
10
4.26667E-05
8.53333E-05
0.000128
0.000170667
0.000213333
0.000256
0.000298667
0.000341333
0.000384
0.000426667
0.000469333
0.000512
0.000554667
0.000597333
0.00064
0.000682667
11
8.53E-05
0.000171
0.000256
0.000341
0.000427
0.000512
0.000597
0.000683
0.000768
0.000853
0.000939
0.001024
0.001109
0.001195
0.00128
0.001365
24000000
In Seconds
12
0.000171
0.000341
0.000512
0.000683
0.000853
0.001024
0.001195
0.001365
0.001536
0.001707
0.001877
0.002048
0.002219
0.002389
0.00256
0.002731
13
0.000341
0.000683
0.001024
0.001365
0.001707
0.002048
0.002389
0.002731
0.003072
0.003413
0.003755
0.004096
0.004437
0.004779
0.00512
0.005461
14
0.000683
0.001365
0.002048
0.002731
0.003413
0.004096
0.004779
0.005461
0.006144
0.006827
0.007509
0.008192
0.008875
0.009557
0.01024
0.010923
15
0.001365
0.002731
0.004096
0.005461
0.006827
0.008192
0.009557
0.010923
0.012288
0.013653
0.015019
0.016384
0.017749
0.019115
0.02048
0.021845
16
0.002731
0.005461
0.008192
0.010923
0.013653
0.016384
0.019115
0.021845
0.024576
0.027307
0.030037
0.032768
0.035499
0.038229
0.04096
0.043691
13
2929.688
1464.844
976.5625
732.4219
585.9375
488.2813
418.5268
366.2109
325.5208
292.9688
266.3352
244.1406
225.3606
209.2634
195.3125
183.1055
14
1464.844
732.4219
488.2813
366.2109
292.9688
244.1406
209.2634
183.1055
162.7604
146.4844
133.1676
122.0703
112.6803
104.6317
97.65625
91.55273
15
732.4219
366.2109
244.1406
183.1055
146.4844
122.0703
104.6317
91.55273
81.38021
73.24219
66.58381
61.03516
56.34014
52.31585
48.82813
45.77637
16
366.2109
183.1055
122.0703
91.55273
73.24219
61.03516
52.31585
45.77637
40.6901
36.62109
33.2919
30.51758
28.17007
26.15792
24.41406
22.88818
In Hz:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
10
23437.5
11718.75
7812.5
5859.375
4687.5
3906.25
3348.214286
2929.6875
2604.166667
2343.75
2130.681818
1953.125
1802.884615
1674.107143
1562.5
1464.84375
11
11718.75
5859.375
3906.25
2929.688
2343.75
1953.125
1674.107
1464.844
1302.083
1171.875
1065.341
976.5625
901.4423
837.0536
781.25
732.4219
12
5859.375
2929.688
1953.125
1464.844
1171.875
976.5625
837.0536
732.4219
651.0417
585.9375
532.6705
488.2813
450.7212
418.5268
390.625
366.2109
4
#include <hidef.h>
/* common defines and macros */
#include <mc9s12dp256.h>
/* derivative information */
#include <stdio.h>
#include "lcd.h"
#pragma LINK_INFO DERIVATIVE "mc9s12dp256b"
/***************************************************************
* Function prototypes
****************************************************************/
__interrupt void RealTimeInterrupt( void );
volatile int delay; //counter for interrupt
volatile int d1, d2; //array index of which number to output on display
volatile int counter;
int counting; //0=timer stopped, 1=timer running
void main( void )
{
char string[17];
//initialize global variables
counting = 0; //0=timer stopped, 1=timer running
counter = 0;
delay = 0; //set counter for interrupt to 0
//setup data direction port
DDRH = 0; //allow input from pushbuttons
LCD_init();
//setup realtime interrupt
RTICTL = 0x28; //8MHz / (9 * 2^11) = 434.02778 MHz or 2.304 ms
CRGINT |= 0x80; // enable RTI interrupt
EnableInterrupts; /* Enable global interrupts */
while(PTH & 0x08); //wait for input from pushbutton 1 (sw2)
counting = 1; //start timer
while(1) //loop forever
{
if ((PTH & 0x04) == 0) //pushbutton 2(sw3) is pressed
{
counting = 0; //stop timer
}
else if ((PTH & 0x08) == 0) //pushbutton 1(sw2) is pressed
{
counting = 1; //start timer
}
sprintf(string,"%16d", counter);
writeLine(string, 1);
}
}
__interrupt void RealTimeInterrupt( void )
{
5
if (counting && delay < 434) //one second has not passed yet
{
delay++; //update one second delay counter
}
else if (counting) //update counter variable
{
delay = 0; //reset one second delay counter
counter++;
}
CRGFLG = 0x80;
/* clear rti flag */
}
6
Download