You are on page 1of 15

The HCS12 Timer System

These notes pertain specifically to the MC9S12DP256B derivative of the


family of HCS12 Microcontrollers

The HCS12 has a standard timer module (TIM) that consists of:

Eight channels of multiplexed input capture and output compare functions.


16-bit pulse accumulator A
16-bit timer counter

The TIM block diagram is shown in the diagram. The Bus Clock for the MC9S12DP256B runs at 24 MHz

Timer Functions allow for the following applications to be implemented


Time delay creation and measurement
Period and pulse width measurement
Frequency measurement
Event counting
Arrival time comparison
Time-of-day tracking
Periodic interrupt generation
Waveform generation
Components of the Timer Module (TIM)
Eight channels that can be configured for Input Capture or Output Compare applications - IOCx
The TIM shares the eight Port T pins with IOC0IOC7. Each Port pin can be used as a general I/O pin
when timer functions are not selected. Pin 7 can be used for Input Capture, Output Compare and pulse
accumulator input. To use a Port pin as a general I/O pin its direction must be configured by the DDRT
register.
The Bus Clock for the TIM is the HCS12 system clock for the MC9S12DP256B this is 24 MHz
Timer Counter Register (TCNT) - address $0044. This is a 16 bit free running counter clocked by the
Timer System clock which runs at the Bus clock frequency of 24 MHz or pre-scaled versions of this clock.
Required for Input Capture and Output Compare functions
Must be accessed in one 16-bit operation in order to obtain the correct value order
There are numerous other registers related to the operation of the TCNT: TIOS, TIE, TSCR1,
TSCR2, TFLG1, TFLG2, TCLT3, TCLT4.
Registers that must be programmed to control the desired functions
TIM System Registers
When a value of TCNT is read for a particular channel the counter value is automatically copied in to a
register - TC0 to TC7.
TC0 - Timer Input Capture/Output Compare Register 0
TC1 - Timer Input Capture/Output Compare Register 1
...

- address $0050
- address $0052

TC7 - Timer Input Capture/Output Compare Register 7

- address $005E

Timer System Control Register 1 (TSCR1) - address $0046


The main use of this register is to enable or disable the timer

Setting and clearing bit 7 (TEN) of TSCR1 will also start and stop the counting of the TCNT counter.
Setting bit 4 (TFFCA) will enable fast timer flag clear function. If this bit is clear, then the user must write
a one to a timer flag in order to clear it.
TEN Timer Enable bit
0 - disable timer - can be used to save power
1 - enable timer
TSWAI - timer stops while in wait mode
0 - allows timer to continue running during wait mode
1 - disables timer when HCS12 is in wait mode
TSFRZ - timer and modulus counter stop while in freeze mode
0 - allows timer and modulus counter to continue running during freeze mode
1 - disables timer and modulus counter when HCS12 is in freeze mode
TFFCA - timer fast flag clear all bit
0 - allows timer flag clearing to work normally
1 - for TFLG1, a read from an input capture or a write to the output compare channel causes
the corresponding channel flag, CnF, to be cleared. For TFLG2, any access to the TCNT
register clears the TOF flag. Any access to the PACN3 and PACN2 registers clears the PAOVF
and PAIF flags in the PAFLG register. Any access to the PACN1 and PACN0 registers clears
the PBOVF flag in the PBFLG register.
Timer System Control Register 2 (TSCR2) - address $004D
The main use of this register is to set the pre-scale value for the timer clock frequency

TOI - timer overflow interrupt enable bit


0 - disable interrupt
1 - enable interrupt when TOF flag is set
3

TCRE - timer counter reset enable bit


0 - counter reset disabled counter runs free
1 - counter reset by a successful
output compare 7
PR2, PR1, and PR0 set the pre-scale values for
dividing the Bus clock

Pre-Scale Computations
The Timer function of the HCS12 microcontroller uses a 16 bit free-running counter called TCNT. The
maximum count is 216 -1 with a total of 216 = 65,536 counts (0 to 65535 counts).
The MC9S12DP256B microcontroller has an E Clock of 24 MHz. The longest time that can be measured
with this clock and a pre-scale value of 1 is thus:
Tlongest = 65,536/24Mhz = 2.74 msec.
The use of a pre-scale factor larger than 1 is necessary if measuring longer times. Pre-scale values range
from 1 to 128 in binary multiples. If the pre-scale value is 2, then the value of the pre-scaled Timer clock
is
Pre-scaled clock = 24 MHz /2 = 12 MHz
The Table shows the choice of possible pre-scale values
Pre-scale value

E Clock

Pre-scaled clock

Max time delay

24 MHz

12 MHz

2.74 msec

24 MHz

6 MHz

10.9 msec

24 MHz

3 MHz

21.8 msec

16

24 MHz

1.5 MHz

43.7 msec

32

24 MHz

750 kHz

87.4 msec

64

24 MHz

375 kHz

175 msec

128

24 MHz

187.5 kHz

350 msec

Questions
What pre-scale value is needed to measure a time delay of 100 msec?

What pre-scale value is needed to measure a time delay of 500 msec?

Timer Interrupt Flag Register 2 (TFLG2) - address $004F


7

TOF

Only bit 7 is used. Bit 7 will be set when overflow of TCNT occurs
Timer Function Applications

Input Capture Function


The HCS12 has eight Input Capture channels. Each channel has a 16-bit capture register, an input pin,
edge-detection logic, and interrupt generation logic. Input Capture channels share most of the circuit
with Output Compare channels so they cannot be enabled simultaneously for anyone channel.
The selection of Input Capture or Output Compare for a channel is done by programming the TIOS
register.
When an Input Capture event occurs the current value of the 16 bit counter TCNT is
copied into the corresponding Timer Input Capture/Output Compare Register - TCx.
TIOS Register address $0040
This register is used to select the Input Capture or Output Compare functions for each channel.

Example: The command movb #$F0, TIOS will enable channels 0 to 3 as Input Capture and channels
4 to 7 as Output Compare.
Use of Input Capture
Physical time is often represented by the contents of the main timer. The occurrence of an event is
represented by a rising or falling edge of a signal waveform. The time when an event occurs can be
recorded by latching the count of the main timer into a register when a signal edge arrives as illustrated
in the diagram.

Timer Control Registers 3 and 4 (TCTL3 and TCTL4) - address $004A and $004B
The signal edge to be captured is specified by TCTL3 and TCTL4 and can be a rising edge, a falling edge or
both edges.

Timer Interrupt Flag Register 1 (TFLG1) - address $004E


7

C7F

C6F

C5F

C4F

C3F

C2F

C1F

C0F

As the counter TCNT counts up it is compared with the appropriate TCx register after each count. If they
match the corresponding bit for that channel is set to a 1. In appropriate applications such as Input
Capture, this would indicate that an edge has been detected.
To clear a bit in TFLG1, write a 1 to the appropriate bit. Alternately setting the TFFCA bit in the TRSC1
register allows the clearing of a flag by reading the corresponding Input Capture register or writing a
value to the Output Capture register.
Applications of Input Capture
Input Capture can be used as an Event Arrival Time Recording mechanism. The period of a waveform
can be measured by capturing the TCNT timer value for two corresponding rising or falling edges.
Measurement of Period

Measurement of Pulse Width


The pulse width of a waveform can be measured by capturing consecutive rising and falling edges.

If period and pulse width have both been measured then the Duty Cycle of a waveform can be
determined.
Calculation of Duty Cycle

Programming with the Input Capture Function


The following Flow Chart and program code illustrate how to use the Input Capture function to measure
the period of a TTL level square wave connected to channel 0. The program initially is configured to
capture a rising edge of the wave form on channel 0, the pre-scale factor is set to 16, the C0F flag is
cleared and then the timer counter is enabled. The code waits for the first rising edge to arrive, stores
the TCNT value in memory, clears the C0F flag again, captures the next rising edge, computes the
difference in the 2 stored values of TCNT and stores this value in memory.

When an Edge Arrives


When a selected edge arrives at the input capture pin, the corresponding flag in TFLG1 is set. To
proceed in the code the flag must be cleared. To clear a flag in the TFLG1 register, write a 1 to it. As an
alternative if the TFFCA bit (bit 4) of the TSCR1 register is set then the required flag can be set by simply
reading the corresponding input capture register or writing a new value to the output compare register.
Assembler Code

; Uses Input Capture Channel 0

TIOS:
equ
TSCR1:
equ
TSCR2:
equ
TCTL4:
equ
TFLG1:
equ
TC0:
equ
;mask values
IOS0:
equ
C0F:
equ
edge1:
edge2:
period:

$40
$46
$4D
$4B
$4E
$50

;address
;address
;address
;address
;address

$01
$01

;mask to select channel 0 as Input capture


;mask to clear channel 0

TIOS register
TSCR1 register
TSCR2 register
TCTL4 register
TFLG1 register

ds.b 2 ; memory to hold the first edge


ds.b 2 ; memory to hold the second edge
ds.b 2 ; memory to store the period

readPeriod:
movb #$90,TSCR1
bclr TIOS,IOS0
movb #$04,TSCR2
movb #$01,TCTL4
movb #C0F,TFLG1
brclr TFLG1,C0F,*
ldd
TC0
std
edge1
brclr TFLG1,C0F,*
ldd
TC0
std
edge2
subd edge1
std
period
swi

C Code

of
of
of
of
of

;enable timer counter & fast timer flags clear


;enable input-capture 0
;disable TCNT overflow interrupt, prescaler to 16
;capture the rising edge of PT0 signal
;clear the C0F flag
;wait for the arrival of the first rising edge
;save the first edge and clear the C0F flag
;store first edge in memory
;wait for the arrival of the second edge
;save the second edge and clear the C0F flag
;store first edge in memory
;compute the period

// Uses Input Capture Channel 0


#include <hidef.h>
#include "derivative.h"

/* common defines and macros */


/* derivative-specific definitions */

void main(void) {
unsigned int edge1, period;
TSCR1 = 0x90;
/* enable timer counter */
TIOS &= ~IOS0;
/*enable Input Capture 0 */
TSCR2 = 0x04;
/*set pre-scale to 16 */
TCTL4 = 0x01;
/* capture rising edge of wave form at PT0 */
TFLG1 = 0x01;
/* clear C0F flag */
while (!(TFLG1 & C0F));
/* wait for first rising edge */
st
edge1 = TC0;
/* save 1 captured edge and clear C0F flag */
while (!(TFLG1 & C0F));
/* wait for 2nd rising edge */
period = TC0 - edge1;
asm(swi);
}

Sample Data Values and Calculations


The 16 bit TCNT counter can be represented as circle where the counter starts at 0000 and counts in a
clockwise direction until it reaches FFFF and then resets back to 0000.
The first diagram represents the case where the value of edge2 is greater than the value of edge1.
Edge1 value = 0226

Edge2 value = 0514

The Edge2 value - Edge2 value = 02EE

This value of 02EE represents the unscaled period of the waveform.


In the second diagram the value of edge2 is less than the value of edge1.
Edge1 value = FE16

Edge2 value = 0104

The Edge2 value - Edge2 value = FD12

Taking the 2s compliment of FD12 gives the value of 02EE. Fortunately for us the software takes into
account when edge1 is less or greater than edge2 and gives the correct result.
TCNT Counter Circular Pictorial
Edge2 > Edge1
Reset point
Edge1

Edge2

Edge2 < Edge1


Reset point
Edge1

Edge2

10

Output Compare Function


The HCS12 has eight Output Compare functions. Each Output Compare channel consists of
a 16-bit comparator
a 16-bit output compare register TCx (also used as input capture register)
an output action pin (PTx, can be pulled high, pulled low, or toggled)
an interrupt request circuit
a forced-compare function (CFOCx)
control logic
The Output Compare function uses many of the same registers as Input Capture.
One of the uses of the output-compare function is to trigger an action at a specific time in the future. To
use the output-compare function, the user makes a copy of the current contents of the TCNT register,
adds to this a value equal to the desired delay and stores the sum into an output-compare register TCx
(TC0 to TC7). The value to be added depends on the pre scaled value of TCNT.
The actions that can be activated on an Output Compare pin include
Pull the pin up to high
Pull the pin down to low
Toggle the pin
These actions are controlled by the Timer Control Registers 1 and 2
Timer Control Registers 1 and 2 (TCTL1 & TCTL2) at addresses $0048 and $0049

11

The value stored in TCx (the future event) will be compared to the current value of TCNT in every clock
cycle. If they are equal (a successful compare has occurred) the corresponding flag bit in theTFLG1
register will be set.
Applications of the Output Compare Function
Generating a Square Wave
The Output Compare function can be used to generate wave forms by adding calculated values
(representing the high and low times for a square wave for example) to a copy of the free running
counter TCNT.
Create an active high square wave at 1 kHz with a 30 % duty cycle. Use a pre-scale value of 8.
Period T = 1/1 kHz = 1 msec

THIGH = 0.3 msec = 300 sec

TCNT Pre-scale Clock = 24 MHz /8 = 3 MHz


Hi Time parameter value = 300 sec x 3 MHz = 900
Low Time parameter value = 700 sec x 3 MHz = 2100
Programming Flow Chart for Output Compare on channel 0

12

TLOW = 0.7 msec = 700 sec

Assembler Code
TCNT:
TIOS:
TSCR1:
TSCR2:
TCTL2:
TFLG1:
TC0:
OC0:
C0F:
hi_time:
lo_time:

equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ

Uses Input Capture Channel 0

$44
$40
$46
$4D
$49
$4E
$50
$01
$01
900
2100

ORG
$2000
movb #$90,TSCR1
movb #$03,TSCR2
bset TIOS,OC0
movb #$03,TCTL2
ldd TCNT
repeat:
addd #lo_time
std TC0
brclr TFLG1,C0F,*
movb #$02,TCTL2
ldd TC0
addd #hi_time
std TC0
brclr TFLG1,C0F,*
movb #$03,TCTL2
ldd TC0
bra repeat
swi
end

C Code

;counter address
;Input/output compare select address
;TSCR1 address
;TSCR2 address
;Timer control register 2 address
;Timer interrupt flag register address
;address of PORT T, PTO (TC0)
;enable OC0 mask
;clear C0F flag mask
;hi_time value
;lo_time value

;enable TCNT with fast timer flag clear


;disable TCNT interrupt, set prescaler to 8
;enable output compare at OC0
;select pull high as pin action
;copy TCNT counter to Reg D
;add required lo_time value
;send to TC0
;wait until OC0 pin goes high
;select pull low as pin action
;copy TCNT counter to Reg D
;add required lo_time value
;send to TC0
;wait until OC0 pin goes low
;select pull high as pin action

Uses Input Capture Channel 0

#include <hidef.h>
#include "derivative.h"
#define hi_time 900
#define lo_time 2100
#define OC0 0x01
#define C0F 0x01

/* common defines and macros */


/* derivative-specific definitions */

void main (void)


{
TSCR1 = 0x90;
/* enable TCNT and fast timer flag clear */
TIOS |= OC0;
/* enable OC0 function */
TSCR2 = 0x03;
/* disable TCNT interrupt, set prescaler to 8 */
TCTL2 = 0x03;
/* set OC0 action to be pull high */
TC0 = TCNT + lo_time;
/* add lo-time value to TCO */
while(1) {
while(!(TFLG1 & C0F)); /* wait for PT0 to go high */
TCTL2 = 0x02;
/* set OC0 pin action to pull low */
TC0 += hi_time;
/* add lo-time value to TCO */
while(!(TFLG1 & C0F)); /* wait for PT0 pin to go low */
TCTL2 = 0x03;
/* set OC0 pin action to pull high */
TC0 += lo_time;
/* start a new OC0 operation */
}
asm("swi");
/* code never reaches here
*/
}

13

Creating a Time Delay


Prior to learning about the Output Compare Function of the HC9S12, creating a time delay was done by
the use of a time delay software loop with its corresponding calculations. According to the notes, the
Output Compare function has the ability to trigger an action at a specific time in the future this can
cause a simple time delay.
Assembly Code Fragment produces a 20 s delay
Delay:
movb #$90,TSCR1 ;enable TCNT and fast time flag clear
movb #0,TSCR2
;set TCNT prescaler to 1
bset TIOS,$01
;enable OC0
ldd TCNT
;start OC0
addd #480
;set delay value - 480 cycles at 24MHz = 20 s
std TC0
brclr TFLG1,C0F,* ;wait until count expires
rts
The delay value is calculated as: delay value = delay time x clock freq = 20 sec x 24 MHz = 480
Calculate the delay value to produce a 10 msec time delay.
delay value = delay time x clock freq = 10 msec x 24 MHz = 240,000
Is this a problem? What is the maximum value allowed in Register D?
What is the maximum delay time with a pre-scale set to 1?
Time delay, max = 65,535/24 MHz = 2.73 msec
Determine a value of the pre-scale factor and delay value needed to produce a 10 msec time delay.
Set the pre- scale factor to 32. The pre-scaled clock frequency is 24 MHz/32 = 750 kHz
delay value = delay time x clock freq = 10 msec x 750 kHz = 7,500
Modified Code for time delay of 10 msec
Delay:
movb #$90,TSCR1 ;enable TCNT and fast time flag clear
movb #05,TSCR2 ;set TCNT pre scaler to 32
bset TIOS,$01
;enable OC0
ldd TCNT
;start OC0
addd #7500
;7500 cycles at 750 kHz = 10 ms
std TC0
brclr TFLG1,C0F,* ;wait
rts
14

C Code Implementation
This application is particularly useful as it is very difficult to calculate from theory the delay value
needed for a for loop delay subroutine in C code. Using the Output Compare timer function
makes it easy.
// Creates a 200 sec delay
Void Delay (void) {
TSCR1 = 0x90;
TSCR2 = 0x01;
TIOS |= 0x01;
TC0 = TCNT + 2400;
while(!(TFLG1 & 0x01));

/* enable TCNT and fast timer flag clear */


/* disable TCNT interrupt, set prescaler to 2 */
/* enable OC0 function */
/* start an OC0 operation */
/* wait for PT0 to go high */

}
Pre- scale factor set to 2. The pre-scaled clock frequency is 24 MHz/2 = 12 MHz
delay value = delay time x clock freq = 100 sec x 12 MHz = 2400

Application Note
Written by David Lloyd
Computer Engineering Program
Humber College

15

You might also like