Title: chapter one transparency
1Chapter 8 68HC11 Timer Functions
The 68HC11 Microcontroller
Han-Way Huang
Minnesota State University, Mankato
2Applications that Requires a Dedicated Timer
System - time delay creation and
measurement - period measurement - event
counting - time-of-day tracking - periodic
interrupt generation to remind the processor to
perform routine tasks - waveform generation - etc.
- A Summary of the 68HC11 Timer Functions
- 1. Main timer
- 16-bit non-stop timer
- read-only after reset
- 2. Input capture function
- three channels -- 1 to 3
- each channel has a 16-bit latch, edge-detection
logic, flag bit, and interrupt logic - will load the current main timer value into the
input capture register when the selected - signal edge is detected
- can be used to measure the signal frequency,
period, and pulse width and as time reference
3- 3. Output compare functions
- A (E) series members have five (four/five)
channels (OC1OC5) - each channel has a 16-bit comparator, 16-bit
register, action pin, interrupt request circuit, - forced-compare function
- continuously compare the value of the 16-bit
compare register with that of the main timer - and may optionally trigger an action on a pin,
generate an interrupt - is often used to create a time delay and
generate a waveform - 4. Real-time interrupt
- generates periodic interrupts when enabled
- interrupt period is programmable
-
- 5. Computer operating properly (COP)
- discussed in Chapter 6
- 6. Pulse accumulator
4The Free-Running Main Timer (TCNT) - The main
timer is cleared to 0 on reset and is read-only
except in test mode. - The timer counter register
is meant to be read by a 16-bit read instruction
such as LDD or LDX. - The block diagram is
shown in Figure 8.1.
5- Registers related to Main Timer
- Timer counter TCNT
- Timer flag register 2 TFLG2
- Timer mask register 2 TMSK2
- Those bits related to main timer operation in
TFLG2 and TMSK2 are in boldface. - Timer counter is meant to be read using a
double-byte read instruction such as LDD or LDX. - If the user accesses TCNT with two 8-bit reads,
the result might not be correct, because the - lower byte of TCNT would be incremented when the
upper byte is accessed.
6The prescale factor for the main timer is
selected by bits 1 and 0 of the timer mask
register 2 as shown in Table 8.1.
Example 7.1 What values will be in A and B after
execution of the following three instructions if
TCNT contains 5EFE when the upper byte is
accessed ? Assume the bits PR1 and PR0 of TMSK2
are 00. regbas equ 1000 TCNTH equ
0E TCNTL equ 0F ldx regbas ldaa
TCNTH,X read the upper byte of TCNT ldaa
TCNTL,X read the lower byte of TCNT
7Solution - The main timer prescale factor is 1
and hence the E clock is the clock input to
TCNT. - The instruction LDAA TCNTH,X loads the
upper byte (value is 5E) of TCNT into A. - The
instruction LDAB TCNTL,L takes 4 E clock cycles
to execute. Therefore, TCNT will have been
incremented by 4 to 5F02. The accumulator B
will receive the value 02. This is not what we
expect. If the instruction LDD TCNT,X is
executed, then A and B will contain 5E and FE
respectively.
8Input Capture Functions - Physical time is
often represented by the contents of the main
timer. - The occurrence of an event is
represented by a signal edge (rising or falling
edge). - The time when an event occurs can be
recorded by latching the count of the main
timer when a signal arrives.
- The 68HC11 has three input capture channels
(IC1, IC2, IC3) to implement this
operation. - Each input capture channel has a
16-bit input capture register, a flag,
edge-detection logic, and interrupt request
circuit.
9- The edge to be captured is selected by
programming the register TCTL2.
For example, the following instruction sequence
captures the rising edge of the signal applied at
PA0 (IC3) regbas equ 1000 TCTL2 equ 21
offset of TCTL2 from regbas ldx
regbas bclr TCTL2,X 00000010 clear bit 1
to 0 bset TCTL2,X 00000001 set bit 0 to 1
10Registers related to input capture
- the lowest three bits (bits 2 to 0) of this
register enable/disable the interrupt from the
proper input capture channel - the upper five
bits (bits 7 to 3) of this register
enable/disable the interrupt from
the corresponding output compare channels
2. timer flag register 1 (TFLG1)
- the lowest three bits (bits 2 to 0) of this
register are input capture flags - the arrival of
a signal edge will set one of the input capture
flags - the upper five bits (bits 7 to 3) of this
register are output compare flags
11How to clear a timer flag bit? write a 1 to the
flag bit to be cleared Method 1. use the BCLR
instruction with a 0 at the bit position (s)
corresponding to the flag (s) to be cleared. For
example, BCLR TFLG1,X FE will clear the
IC3F flag. (Assume the index register contains
1000 and TFLG1 23) Method 2. load an
accumulator with a mask that has a 1 (or 1s) in
the bit (s) corresponding to the flag (s) to be
cleared then write this value to TFLG1 or TFLG2.
For example, LDAA 01 STAA TFLG1,X will
clear the IC3F flag.
12Applications of Input Capture function - Event
arrival time recording - Period measurement the
input capture function captures the main timer
values corresponding to two consecutive rising
or falling edges
- Pulse width measurement capture the rising and
falling edges
13- Interrupt generation three input capture
functions can be used as three edge-sensitive int
errupt sources. - Event counting by counting the
number of signal edges arrived during a period
- Time reference often used in combination with
an output compare function
14Duty Cycle Measurement
Phase Difference Measurement
15- Example 8.3 Use the input capture channel IC1 to
measure the period of an unknown - signal. The period is known to be shorter than
32 ms. Write a program to set up IC1 - to measure its period.
- Solution
- two versions are available.
- The polling method is shown
- in Figure 8.15.
16Assembly Program for Period Measurement (Polling
Method) REGBAS EQU 1000 TLFG1 EQU 23 TIC1 EQU
10 TCTL2 EQU 21 IC1rise EQU 10 ORG 00 edge1 RM
B 2 period RMB 2 ORG C000 LDX REGBAS BCLR TFL
G1,X FB clear IC1F flag LDAA IC1rise STAA TC
TL2,X capture rising edge BRCLR TFLG1,X 04
wait for the first rising edge LDD TIC1,X ST
D edge1 save the first edge BCLR TFLG1,X FB
clear IC1F flag BRCLR TFLG1,X 04 wait for
the second edge LDD TIC1,X SUBD edge1 STD perio
d save the period END
17C Program for Period Measurement (Polling
method) include lthc11.hgt include
ltstdio.hgt main ( ) unsigned int edge1,
period TFLG1 0x04 / clear IC1F
flag TCTL2 0x10 / configure to capture
rising edge / while (!(TFLG1 0x04)) / wait
for the arrival of the first rising edge
/ edge1 TIC1 / save the arrival time of
the first rising edge / TFLG1 0x04 while
(!(TFLG1 0x04)) / wait for the arrival of
the second rising edge / period TIC1
edge1 printf(\n The period of the signal is d
E clock cycles. \n, period) return 0
18Interrupt-driven Method for Period Measurement
19REGBAS EQU 1000 base address of the I/O
register block TFLG1 EQU 23 offset of TFLG1
from regbas TMSK1 EQU 22 offset of TMSK1
from regbas TIC1 EQU 10 offset of TIC1 from
regbas TCTL2 EQU 21 offset of TCTL2 from
regbas IC1rise EQU 10 value to select the
rising edge of IC1 to capture IC1I EQU 04
mask to select the IC1 bit in TMSK1 IC1FM EQU
FB mask to clear IC1F using the BCLR
instruction ORG 0000 edge_cnt RMB 1 edge
count edge1 RMB 2 captured first
edge period RMB 2 period in number of E clock
cycles ORG E8 IC1 interrupt jump table
entry on the EVB JMP IC1_ISR ORG
C000 starting address of the main
program LDS DFFF set up stack pointer LDX
REGBAS LDAA IC1rise select to capture
the rising edge of IC1 STAA TCTL2,X BCLR
TFLG1,X IC1FM clear the IC1F flag LDAA 2
20 STAA edge_cnt initialize edge count to
2 BSET TMSK1,X IC1I enable IC1
interrupt CLI enable interrupt to the
68HC11 wait TST edge_cnt edge_cnt 0? BNE
wait LDD TIC1,X get the second edge
time SUBD edge1 take the difference of edge
1 and 2 STD period save the
period . . . IC1 interrupt service routine
in the following IC1_ISR LDX regbas BCLR
TFLG1,X IC1FM clear the IC1F flag DEC
edge_cnt BEQ skip is this the second
edge? LDD TIC1,X save the first edge time in
memory STD edge1 skip RTI END
21C Language Program for Period Measurement
(Interrupt-Driven Method) include
lthc11.hgt include ltstdio.hgt int
edge_cnt unsigned int edge1, period void IC1_ISR
( ) main ( ) (unsigned char )0xe8
0x7E / 7E is the opcode of JMP / (void
()())0xe9 ICI_ISR / set up pseudo vector
entry of IC1 / TFLG1 0x04 / clear IC1F
flag edge_cnt 2 TCTL2 0x10 / prepare
to capture the rising edge / TMSK1
0x04 / enable IC1 interrupt locally
/ INTR_ON ( ) / enable interrupt globally
/ while (edge_cnt) period TIC1
edge1 printf(\n The period is d E clock
cycles. \n, period) return 0
22pragma interrupt_handler IC1_ISR ( ) void
IC1_ISR ( ) TFLG1 0x04 / clear IC1F flag
/ if (edge_cnt 2) edge1 TIC1 / save
the first edge / -- edge_cnt
23Example 8.4 Write a subroutine to measure the
pulse width of an unknown signal connected to the
IC1 pin. Return the pulse width in D. The main
timer prescale factor is 1. The pulse width of
the unknown signal is known to be shorter than
32.67 ms. Solution - capture the rising edge on
the IC1 pin - capture the falling edge on the IC1
pin - take the difference of two captured
values regbas EQU 1000 base address of the
I/O register block TFLG1 EQU 23 offset of
TFLG1 from regbas TIC1 EQU 10 offset of TIC1
from regbas TCTL2 EQU 21 offset of TCTL2
from regbas IC1rise EQU 10 value to select
the rising edge of IC1 IC1fall EQU 20 value
to select the falling edge of IC1 IC1F EQU
04 a mask to select the IC1F
flag temp EQU 00 offset of temp from the top
of the stack pul_width PSHX PSHY DES
allocate two bytes for local variable
temp DES TSY LDX regbas
24 LDAA IC1rise configure TCTL2 to capture the
rising edge of IC1 STAA TCTL2,X LDAA
IC1F clear IC1F flag STAA
TFLG1,X rise BRCLR TFLG1,X IC1F rise wait
for the arrival of the rising edge LDD
TIC1,X save the first edge STD
temp,Y LDAA IC1fall configure to
capture the falling edge of IC1 STAA
TCTL2,X LDAA IC1F clear IC1F
flag STAA TFLG1,X fall BRCLR TFLG1,X IC1F
fall wait for the arrival of the falling
edge LDD TIC1,X get the captured time of the
second edge SUBD temp,Y INS INS PULY PULX
RTS
25Measuring the period or pulse width of a slow
signal (longer than 32.76 ms) We need to keep
track of the number of times that main timer
overflows. Let ovcnt main timer overflow
count diff difference of two edges edge1
the captured time of the first edge edge2
the captured time of the second edge Case
1 edge2 ³ edge1 period (or pulse width)
ovcnt 216 diff Case 2 edge2 lt
edge1 period (or pulse width) (ovcnt - 1)
216 diff The main timer overflows at least
once in this case.
26Example 8.5 Write a program to measure the
period of an unknown signal, which may be longer
than 216 E cycles using the IC1 input capture
channel. Solution The logic flow of the program
is shown in Figure 8.17.
27(No Transcript)
28regbas EQU 1000 base address of I/O register
block TFLG1 EQU 23 offset of TFLG1 from
regbas TIC1 EQU 10 offset of TIC1 from
regbas TCTL2 EQU 21 offset of TCTL2 from
regbas TMSK1 EQU 22 offset of TMSK1 from
regbas TMSK2 EQU 24 offset of TMSK2 from
regbas IC1rise EQU 10 value to select the
rising edge of IC1 ORG 0000 edge1 RMB 2
captured time of the first edge ov_cnt RMB 2
main timer overflow count period RMB 2 period
of the unknown signal ORG 00D0 setup timer
overflow interrupt vector jump table entry JMP
tov_ISR on EVB ORG C000 LDS DFFF set
up stack pointer SEI disable all maskable
interrupts to the 68HC11 CLR ov_cnt
initialize overflow count to 0 CLR
ov_cnt1 LDX regbas
29 LDAA IC1rise select to capture the rising
edge STAA TCTL2,X BCLR TFLG1,X FB
clear IC1F flag BCLR TMSK1,X FF disable all
input capture and output compare
interrupts BRCLR TFLG1,X FB wait for the
arrival of the first edge BCLR TFLG2,X 7F
clear TOF flag BSET TMSK2,X 80 enable timer
overflow interrupt CLI enable interrupt to
the 68HC11 LDD TIC1,X save the captured time
of the first edge STD edge1 BCLR
TFLG1,X FB clear IC1F flag BRCLR TFLG1,X
04 wait for the arrival of the second
edge LDD TIC1,X compute the difference of
edge2 and SUBD edge1 edge1
30 STD period BCC next is second edge
smaller? LDD ov_cnt decrement overflow
count if second edge is smaller SUBD
1 STD ov_cnt next tov_ISR LDX
regbas BCLR TFLG2,X 7F clear TOF
flag LDD ov_cnt increment timer overflow
count ADDD 1 STD ov_cnt RTI END
31C Program for Measuring the Period of a Slow
Signal include lthc11.hgt include
ltstdio.hgt unsigned edge1, overflow unsigned long
period void TOV_ISR ( ) main ( ) (unsigned
char )0xd0 0x7E (void() ( ))0xd1
TOV_ISR / set up TOV pseudo vector entry
/ INTR_OFF ( ) overflow 0 TFLG1
0xFF / clear all output-compare and
input-capture flags / TFLG2 0x80 / clear
TOF flag / TCTL2 0x10 / configure to
capture IC1s rising edge / TMSK1 0x00 /
disable all input capture and output compare
interrupts / while (!(TFLG1 0x04)) / wait
for the arrival of first rising edge on IC1
/ TFLG1 0x04 edge1 TIC1 / save the
first rising edge /
32 TMSK2 0x80 / enable timer overflow
interrupt / INTR_ON ( ) / / while
(!(TFLG1 0x04)) / wait for the second rising
edge / if (TIC1 lt edge1) / if the second edge
is smaller, then overflow -- / decrement the
overflow count / period overflow 65536 /
combine the result / period TIC1 - edge1 /
/ printf(\n The period is d E clock
cycles. \n, period) return 0 pragma
interrupt_handler TOC_ISR ( ) void TOV_ISR (
) TFLG2 0x80 / clear TOF flag
/ overflow
33Output Compare Functions - five output compare
channels OC1-OC5 - port A pins PA7-PA3 are
associated with output compare channels OC1-OC5
respectively - Each output compare channel
consists of 1. a 16-bit comparator 2. a 16-bit
compare register (TOCx, x 1,,5) 3. an output
action pin 4. an interrupt request circuit 5.
a forced-compare function (FOCx, x 1,,5) 6.
control logic
34- To use an output compare function, 1. make a
copy of the main timer 2. add to this copy a
value equal to the desired delay 3. store the
sum onto an output-compare register - The
actions that can be activated on an output
compare pin include 1. pull up to high 2.
pull down to low 3. toggle The action is
determined by the timer control register 1
(TCTL1)
35Example 8.6 Generate a 1KHz digital waveform with
40 duty cycle from output compare pin OC2. Use
the polling method to check the success of the
compare operation. The frequency of the E clock
is 2 MHz and the prescale factor to the main
timer is 1. Solution
A 1KHz digital with 40 duty cycle has 400 ms
high and 600 ms low in one period. The flowchart
to generate this waveform is shown in Figure
8.20.
36regbas equ 1000 base address of I/O register
block PORTA equ 00 offset of PORTA from
regbas TOC2 equ 18 offset of TOC2 from
regbas TCNT equ 0E offset of TCNT from
regbas TFLG1 equ 23 offset of TFLG1 from
regbas toggle equ 40 value to select the
toggle action lotime equ 1200 value to set
low time to 600 ms hitime equ 800 value to
set high time to 400 ms org C000 ldx
regbas bset PORTA,X 40 set OC2 pint to
high bclr TFLG1,X BF clear OC2F
flag ldaa toggle select output compare
action to be staa TCTL1,X toggle ldd
TCNT,X start an OC2 operation which toggles
the OC2 pin addd hitime with a delay of 800
E clock cycles std TOC2,X high brclr
TFLG1,X 40 high wait until OC2F is set to
1 bclr TFLG1,X BF clear OC2F flag ldd
TOC2,X start another OC2 operation which
toggles the OC2 pin addd lotime with a
delay of 1200 E cycles std TOC2,X
37low brclr TFLG1,X 40 low wait until OC2F is
set to 1 bclr TFLG1,X BF clear OC2F
flag ldd TOC2,X start another OC2 operation
which toggles the OC2 pin addd hitime with
a delay of 800 E cycles std TOC2,X bra
high end
38In C language, include lthc11.hgt main (
) PORTA 0x40 / set OC2 pint to high
/ TCTL1 0x40 / select toggle as the OC2
pin action / TOC2 TCNT 800 / start an OC2
operation with 800 E cycles as the delay
/ TFLG1 0x40 / clear OC2F flag / while
(1) while (!(TFLG1 0x40)) / wait for 400
ms / TFLG1 0x40 TOC2 1200 / start
next OC2 operation with 1200 E cycles as delay
/ while (!(TFLG1 0x40)) / wait for 600 ms
/ TFLG1 0x40 TOC2 800 return 0
39Example 8.7 Write a function to generate one
second delay using the OC2 function. The E
clock is 2 MHz and the prescale factor to the
main timer is 1. Solution
A one-second delay can be created by performing
40 OC2 output compare operations. Each OC2
compare operation creates 25 ms delay. A
memory location is allocated to keep track of
the number of OC2 operations that have
been performed.
40regbas EQU 1000 base address of I/O register
block TOC2 EQU 18 offset of TOC2 from
regbas TCNT EQU 0E offset of TCNT from
regbas TFLG1 EQU 23 offset of TFLG1 from
regbas dly25ms EQU 50000 the number of E
cycles to generate 25 ms delay onesec EQU 40
number of OC2 operations to be performed oc2_cnt E
QU 0 offset of oc2_cnt from the top of the
stack delay_1s PSHX PSHY DES TSY LDX
regbas BCLR TFLG1,X BF clear OC2F
flag LDAA 40 STAA oc2_cnt,Y
initialize oc2_cnt LDD TCNT,X wait ADDD
dly25ms STD TOC2,X start an OC2 operation
with 25 ms delay BRCLR TFLG1,X 40 wait
until OC2F flag is set BCLR TFLG1,X BF
clear OC2F flag DEC oc2_cnt,Y
41 BEQ exit LDD TOC2,X BRA
wait exit INS PULY PULX RTS C function
to generate one second delay, void delay_1s (
) unsigned char oc2_cnt oc2_cnt 100 /
prepare to perform 100 OC2 operation / TFLG1
0x40 / clear OC2F flag / TOC2 TCNT
20000 / start an OC2 operation with 20000 E
cycles as the delay / while (oc2_cnt)
while(!(TFLG1 0x40)) / wait for 10 ms
/ TFLG1 0x40 -- oc2_cnt TOC2
20000 / start the next OC2 operation /
42Example 8.8 Suppose an alarm device is already
connected properly and the subroutine to turn on
the alarm is also available. Write a program to
implement the alarm timer--it should call the
given alarm subroutine when the alarm time is
reached. Solution
- Use OC2 to create the delay. - Perform OC2
operations with a delay of 20 ms - Perform 3000
such operations to create a delay of 1
minute. - Check the alarm time every
second. - Call the alarm routine if the alarm
time is reached. - Enable OC2 interrupt
43regbas equ 1000 TOC2 equ 18 TCNT equ
0E TFLG1 equ 23 TMSK1 equ 22 dly20ms equ
40000 number of E cycles equivalent to 20 ms
delay one_min equ 3000 number of OC2
operations to be created to generate 1
minute delay org 0000 hours rmb
1 minutes rmb 1 ticks rmb 2 alarm rmb
2 routine fdb start_alarm starting address
of the alarm routine org 00DC interrupt
jump table entry for OC2 on EVB jmp
oc2_ISR org C000 lds DFFF set up
stack pointer sei disable interrupt before
setup is done ldd one_min initialize the
OC2 count to generate std ticks one minute
delay
44 ldx regbas bclr TFLG1,X BF clear OC2F
flag bset TMSK1,X 04 enable OC2
interrupt ldd TCNT,X start an OC2 operation
with addd dly20ms 20 ms delay std
TOC2,X cli enable interrupt to the
68HC11 forever bra forever loop forever to
wait for interrupt oc2_ISR ldx regbas bclr
TFLG1,X BF clear OC2 flag ldd TOC2,X start
the next OC2 operation with addd dly20ms 20
ms delay std TOC2,X ldy ticks decrement
the minute count dey sty ticks bne
case2 is one minute expired? ldd one_min
reinitialize the one-minute counter std
ticks ldd hours load the hours and minutes
45 INCB CMPB 60 is it time to increment the
hour? BNE case1 no need to update hour
digits yet CLRB reset minutes to 0 INCA
increment the hour CMPA 24 it is time to
reset hours to 0? BNE case1 no need to
reset hour yet CLRA reset hours to
00 case1 STD hours save the current time in
memory CPD alarm reaches alarm time? BNE
case2 LDX routine JSR 0,X call the
alarm routine case2 RTI END
46Example 8.9 LED Flashing. Connect 8 LEDs to port
B and flash these LEDs in the following way 1.
Light all LEDs for ¼ seconds and turn them off
for ¼ secondsrepeat this pattern 4 times. 2.
Light one LED at a time for one secondfrom the
LED controlled by the most significant output
port pin to the LED controlled by the least
significant port pin. 3. Reverse the order of
display in step 2. 4. Turn off all of the LEDs.
47unsigned char flas_tab 252 0xFF, 25,
0x00, 25, 0xFF, 25 0x00, 25, 0xFF,
25, 0x00, 25, 0xFF, 25, 0x00, 25, 0x80,
100, 0x40, 100, 0x20, 100, 0x10,
100, 0x08,100, 0x04, 100, 0x02, 100,
0x01, 100, 0x01, 100, 0x02, 100, 0x04,
100, 0x08, 100, 0x10, 100, 0x20, 100,
0x40, 100, 0x80, 100, 0x00,100 void
delay (char k) void flash ( ) int i for (i
0 i lt 25 i) PORTB flash_tab
i0 delay (flash_tabi1) void
delay (char k) TFLG1 0x40 / clear OC2F
flag / TOC2 TCNT 20000 / start an OC2
operation / while (k) while (!(TFLG1
0x40)) TFLG1 0x40 -- k TOC2
20000 / start a new OC2 operation /
48Using OC1 to Control Multiple OC Functions - OC1
can control up to five OC pins - Specify the OC
pins to be controlled by OC1 using the register
OC1M. - Specify the value that any OCx (x
1,,5) pin to assume when the value of TOC1
equals TCNT using the OC1D register. - When a
successful OC1 compare is made, each affected pin
assumes the value of the corresponding bit of
OC1D. - The OC1 (PA7) pin is bidirectional. For
this pin to be controlled by OC1 function, it
must be configured for output. The direction of
PA7 pin is controlled by the bit 7 of the
PACTL register. Set bit 7 of PACTL to 1 to
configure PA7 pin for output.
49Example 8.9 Write values into OC1M and OC1D so
that OC2 and OC3 pins will assume the values of
0 and 1 when the OC1 compare operation
succeeds. Solution - Set bits 6 and 5 of OC1M
to 11 - Set bits 6 and 5 of OC1D to
01 regbas EQU 1000 OC1M EQU 0C OC1D EQU
0D LDX regbas LDAA 01100000 STAA
OC1M,X LDAA 00100000 STD OC1D In C
language OC1M 0x60 OC1D 0x20
50Example 8.11 An application requires control of
five valves. The first, third, fifth
valves should be opened for five seconds and then
closed for five seconds. When these three
valves are closed, the second and fourth valves
are opened, and vise versa. This process is
repeated forever. Pins OC1,,OC5 are used to
control these five valves. When the OCx pin is
high, the corresponding valve will be opened.
Write a program to perform the operation. Solution
- The OC1 pin (same as PA7) is bi-directional,
to use it to control a valve, it must be
configured for output. Set the bit 7 of the
PACTL register to 1. - Write the value 11111000
into OC1M so that OC1 function can control all
five OC pins. - Write the value 10101000 into
OC1D to open only valves 1,3,and 5. - Write the
value 01010000 into OC1D to open only valves 2
and 4. - Perform 200 OC1 output compare
operations with each operation creating 25 ms
delay. regbas EQU 1000 PACTL EQU
26 OC1D EQU 0D OC1M EQU 0C TOC1 EQU
16 TCNT EQU 0E TFLG1 EQU 23 oc1m_in EQU
F8 value to initialize OC1M oc1d_in1 EQU
A8 value to initialize OC1D to open valves 1,
3, and 5
51oc1d_in2 equ 50 value to initialize OC1D to
open valves 2 and 4 five_sec equ 200 number
of OC1 operations to be performed dly25ms equ
50000 the number of E clock cycles equivalent
to 25 ms ORG 0000 oc1_cnt rmb 1 number
of OC1 operations remained to be performed ORG
C000 ldx regbas bset PACTL,X 80
configure PA7 pin for output ldaa oc1m_in
allow OC1 function to control all OC pins staa
OC1M,X bclr TFLG1,X 7F clear OC1F
flag ldaa five_sec staa oc1_cnt ldaa
oc1d_in1 set pins OC1, OC3, and OC5 to high
after 25 ms staa OC1D,X ldd TCNT,X start
an OC1 operation with 25 ms delay repeat1 addd
dly25ms std TOC1,X brclr TFLG1,X
80 wait for 25 ms bclr TFLG1,X 7F
clear OC1F flag
52 dec oc1_cnt decrement the output compare
count beq change at the end of 5 seconds
change the valves setting ldd TOC1,X prepare
to perform the next OC1 operation bra
repeat1 change ldaa oc1d_in2 set to open
valves 2 and 4 staa OC1D,X ldaa
five_sec reinitialize the output compare
count staa oc1_cnt repeat2 ldd TOC1,X
start the next OC1 operation with the same addd
dly25ms delay std TOC1,X brclr
TFLG1,X 80 wait until OC1F flag is set to
1 bclr TFLG1,X 7F clear OC1F flag dec
oc1_cnt beq switch five seconds expired,
switch the valve setting bra repeat2 switch ld
aa five_sec reinitialize the OC1 count staa
oc1_cnt ldaa oc1d_in1 change the valve
setting staa OC1D,X ldd TOC1,X prepare
to start the next OC1 operation bra
repeat1 end
53include lthc11.hgt main () unsigned int
oc1_cnt PACTL 0x80 / configure PA7 for
output / OC1M 0xF8 / allow OC1 to control
OC1-OC5 pins / TFLG1 0x80 / clear OC1F
flag / TOC1 TCNT 20000 / start an OC1
operation with 10 ms delay / while (1) OC1D
0xA8 / prepare to set PA7, PA5, and PA3 to
high / oc1_cnt 500 / number of OC1
operations to create 5 s delay / while
(oc1_cnt) while (!(TFLG1 0x80)) TFLG1
0x80 / clear OC1F flag / TOC1
20000 / start the next OC1 operation
/ oc1_cnt -- OC1D 0x50 / value to
pull PA6 and PA4 to high / oc1_cnt
500 while (oc1_cnt) while (!(TFLG1
0x80)) TFLG1 0x80 / clear OC1F flag
/ TOC1 20000 / start the next OC1
operation / oc1_cnt --
54OC1 function can control an output compare pin
that has been controlled by another output
compare function. This allows two output compare
functions to control the same pin. Example 8.12
Use OC1 and OC2 together to generate a 5KHz
digital waveform with 40 duty cycle.
Solution - Use OC1 function to pull OC2 pin to
high every 200 ms. - Use OC2 function to pull OC2
pin to low 80 ms later. - Enable both OC1 and OC2
interrupts - The interrupt service routines of
OC1 and OC2 clear the flag and then start their
associated output compare operations with 200 ms
delay.
55regbas equ 1000 TMSK1 equ 22 PORTA equ
00 OC1D equ 0D OC1M equ 0C TOC1 equ
16 TOC2 equ 18 TCTL1 equ 20 TFLG1 equ
23 tctl1_in equ 80 value to set the OC2
action to be pull the OC2 pin to low oc1m_in equ
40 value to allow OC1 function to control OC2
pin oc1d_in equ 40 value to be written into
OC1D to pull OC2 to high fiveKHz equ 400
timer count for 5 KHz (2 MHz E clock
cycles) diff equ 160 the count difference of
two output compare functions org 00DC jmp
oc2_ISR interrupt vector jump table entry for
OC2 jmp oc1_ISR interrupt vector jump table
entry for OC1 org C000 lds DFFF ldx
regbas bclr TFLG1,X 3F clear OC1F and
OC2F flags
56 ldaa tctl1_in define OC2 action to pull OC2
pin to low staa TCTL1,X ldaa oc1d_in
define OC1 action to pull OC2 pin to high staa
OC1D,X ldaa oc1m_in allow OC1 function
to control OC2 pin staa OC1M,X bset
TMSK1,X C0 enable OC1 and OC2
interrupts bclr PORTA,X 40 pull OC2 pin to
low ldd TCNT,X start the OC1 operation with
a delay of 200 ms addd fiveKHz std
TOC1,X addd diff start the OC2
operation std TOC2,X cli enable
interrupt to the 68HC11 loop bra loop
infinite loop to wait for OC1 and OC2 interrupts
57 The OC1 interrupt service routine is in the
following oc1_ISR bclr TFLG1,X 7F clear OC1
flag ldd TOC1,X start the next OC1 operation
with a delay of 200 ms addd
fiveKHz std TOC1,X rti The OC2
interrupt service routine is in the
following oc2_ISR bclr TFLG1,X BF clear OC2
flag ldd TOC2,X start the next OC2 operation
with a delay of 200 ms addd
fiveKHz std TOC2,X rti end
58C Language Program Using OC1 OC2 to generate a
waveform include lthc11.hgt void OC1_ISR (
) void OC2_ISR ( ) main ( ) (unsigned char
)0xdf 0x7E (void ()())0xe0 OC1_ISR (
) (unsigned char )0xdc 0x7E (void
()())0xdd OC2_ISR ( ) OC1M 0x40 /
allow OC1 to control OC2 pin / OC1D 0x40 /
configure OC1 to pull OC2 to high / TCTL1
0x80 / configure OC2 to pull OC2 pin to low
/ PORTA 0xBF / pull OC2 pin to low
/ TOC1 TCNT 400 / start an OC1 operation
with 400 E cycles as delay / TOC2 TOC1
160 / start OC2 operation that succeed 160 E
cycles later / TMSK1 0xC0 / enable OC1 and
OC2 interrupts / INTR_ON ( ) while (1) /
infinite loop / return 0
59pragma interrupt_handler OC1_ISR ( ) void
OC1_ISR ( ) TFLG1 0x80 TOC1 400 /
start the next OC1 operation / pragma
interrupt_handler OC2_ISR ( ) void OC2_ISR (
) TFLG1 0x40 TOC2 400 / start the
next OC2 operation /
60Forced Output Compare - Useful when the user
requires the output compare to succeed
immediately after being started - Write a 1 to
the corresponding bit of the CFORC register to
force an output compare operation - The forced
output compare operation only causes pin action.
Neither the flag is set to 1 nor the interrupt
is generated.
61Example 8.13 Suppose that the contents of the
TCTL1 register are 10011000. What would occur
on pins PA6-PA3 on the next clock cycle if the
value 01111000 is written into the CFORC
register? Solution The contents of TCTL1
configure the output compare actions in Table 8.5
- CFORC specifies that OC2-OC5 are to be
forced. - Pin PA6 will be pulled low - Pin PA5
will be toggled - Pin PA4 will be pulled
low - Pin PA3 will not be affected
62Real-Time Interrupt (RTI) - Will generate
periodic interrupts if enabled. - The RTI
interrupt period is programmable by programming
the bits 1 and 0 of the PACTL register (see
table 8.6). - RTI interrupt is enabled by setting
the bit 6 of the TMSK2 register - The bit 6 of
the TFLG2 register will be set to 1 on a RTI
interrupt
Example 8.14 Use the RTI function to create a
delay of 10 seconds. Solution - Select the
prescale factor of 8 that will set the interrupt
period to 32.67 ms - Need to enable RTI
interrupt - 305 RTI interrupts will roughly
create a delay of 10 seconds
63regbas EQU 1000 TMSK2 EQU 24 TFLG2 EQU
25 PACTL EQU 26 tensec EQU 305 total RTI
interrupts in 10 s RTIF EQU 40 mask to
select the RTIF flag ORG 0000 rti_cnt RMB
2 remaining RTI interrupts to be
generated ORG 00EB RTI interrupt vector
jump table entry JMP rti_hnd ORG
C000 LDS DFFF initialize stack
pointer LDX regbas LDD tensec STD
rti_cnt BSET PACTL,X 03 select RTI clock
prescale factor to 8 LDAA RTIF STAA
TFLG2,X clear RTIF flag STAA TMSK2,X
enable RTI function CLI enable interrupt to
the 68HC11 loop LDD rti_cnt wait until
rti_cnt becomes 0 BNE loop SWI
64RTI service routine is as follows rti_hnd
LDX regbas BCLR TFLG2,X BF LDX
rti_cnt DEX STX rti_cnt RTI
65C Function that Uses RTI To Create 10-Second
Delay int rti_cnt / number of RTI interrupts
remained / void delay_10s ( ) rti_cnt
305 PACTL 0x03 / set RTI clock prescale
factor to 8 / TFLG2 0x40 / clear RTIF flag
/ TMSK2 0x40 / enable RTI interrupt
/ INTR_ON ( ) / / while
(rti_cnt) TMSK2 0xBF / disable RTI
interrupt / pragma interrupt_handler RTI_ISR
( ) void RTI_ISR ( ) TFLG2 0x40 / clear
RTIF flag / rti_cnt --
66The Pulse Accumulator - 8-bit pulse accumulator
(PACNT) - two operation modes event counting and
gated accumulation modes - PACNT is clocked by
the PAI input in event counting mode - PACNT is
clocked by the E-divided-by-64 clock in gated
accumulation mode - The PAI pin (PA7 pin) must be
configured for input to enable pulse
accumulator - There are two interrupt sources
PAI pin edge and the rollover of PACNT from FF
to 00 - Four registers are related to the
operation of the PACNT TMSK2, TFLG2, PACTL, PACNT
67- The bits 5 and 4 of TMSK2 enables/disables
PACNT overflow and PAI edge interrupt
respectively. - The bits 5 and 4 of TFLG2 are
pulse accumulator overflow and PAI edge flag
respectively.
Pulse Accumulator Control Register (PACTL) - bit
7 (DDRA7) 0 -- configure PA7 pin for input 1
-- configure PA7 for output - bit 6 (PAEN) 0 --
disable PA function 1 -- enable PA
function - bit 5 (PAMOD) 0 -- select
event-counting mode 1 -- select gated
accumulation mode - bit 4 (PEDGE) its meaning
depends on bit 5
68Example 8.15 Interrupt after N events. Events
are converted into signal edges and are connected
to the PAI pin. N is smaller than 255. Write a
program to interrupt the 68HC11 after N
event. Solution regbas EQU 1000 TMSK2 EQU
24 TFLG2 EQU 25 PACTL EQU 26 PACNT EQU
27 PA_INI EQU 50 value to enable PA,
select event-counting mode, falling edge
active N EQU . event count ORG
C000 LDX regbas BCLR TFLG2,X DF clear
the PAOVF flag LDAA N NEGA complement
N STAA PACNT,X initialize PACNT to -N LDAA
PA_INI STAA PACTL,X BSET TMSK2,X 20
enable the PACNT overflow interrupt CLI
enable interrupt to the 68HC11 END
69C Program that Interrupts After N
Events include lthc11.hgt void PAOV_ISR ( ) main
( ) (unsigned char )oxcd 0x7E (void
()())0xce PAOV_ISR PACNT N 1 / place
-N in PACNT / PACTL 0x50 / configure PA
function / TMSK2 0x20 / enable PAOV
interrupt / INTR_on ( ) pragma
interrupt_handler PAOV_ISR ( ) void PAOV_ISR (
)
70Use the PA function to measure frequency - Set
up pulse accumulator to operate in event-counting
mode - Connect the unknown signal to the PAI
pin - Select the active edge (rising or
falling) - Use one of the output compare function
to create a delay of one second - Use a memory
location to keep track of the number of active
edges arrived in one second. - Enable pulse
accumulator interrupt on active edge. The PA
interrupt service routine increments the signal
count by 1. - Disable the pulse accumulator
interrupt at the end of one second. Example 8.16
Write a program to measure the frequency of an
unknown signal connected to the PAI
pin. Solution - use OC2 function to perform 40
operations to create a delay of one second - each
OC2 operation creates a delay of 25 ms - enable
PAI edge interrupt - on a PAI edge interrupt,
increment the frequency count by 1
71regbas EQU 1000 TCNT EQU 0E TOC2 EQU
18 TFLG1 EQU 23 TMSK2 EQU 24 TFLG2 EQU
25 PACTL EQU 26 PACNT EQU 27 oc2dly EQU
50000 output compare count for 25 ms
delay pa_in EQU 50 value to enable PA,
select event-counting mode, rising edge as
active edge, and set PA pin for
input onesec EQU 40 number of OC2 operations
to be performed stop EQU 10 value to
disable the PA interrupt ORG
0000 oc2_cnt RMB 1 freqcy RMB 2 active
edge count in one second ORG CA interrupt
vector jump table entry for PAI edge JMP
pa_ISR
72 ORG C000 LDS DFFF LDX regbas LDAA
onesec STAA oc2_cnt initialize OC2
count LDD 0 STD freqcy initialize
frequency counter to 0 LDAA pa_in
initialize the PA function STAA PACTL,X
BCLR TFLG2,X EF clear the PAIF
flag BSET TMSK2,X 10 enable the PAI edge
interrupt CLI enable interrupt to the
68HC11 LDD TCNT,X start an OC2 operation
with a delay sec_loop ADDD oc2dly of 25
ms STD TOC2,X BCLR TFLG1,X BF clear
OC2F flag BRCLR TFLG1,X 40 wait for 25 ms
LDD TOC2,X DEC oc2_cnt BNE sec_loop
if 1 second is not expired, continue. LDAA
stop disable PAI edge interrupt STAA
TMSK2,X SWI return to BUFFALO monitor
73pa_ISR LDX regbas BCLR TFLG2,X EF clear
the PAIF flag LDX freqcy increment frequency
counter INX STX freqcy RTI END
74C Program that Uses PAI to Measure the
Frequency include lthc11.hgt include
ltstdio.hgt void PAI_ISR ( ) unsigned int
frequency main ( ) unsigned int
oc2_cnt (unsigned char )0xca 0x7E (void
()())0xcb PAI_ISR frequency 0 PACTL
0x50 TFLG2 0x10 / clear PAIF flag
/ oc2_cnt 100 / total OC2 operations to
be performed / TOC2 TCNT 20000 / start an
OC2 operation with 20000 E cycles as delay
/ TFLG1 0x40 / clear OC2F flag / TMSK2
0x10 / enable PAI interrupt / INTR_ON (
) / / while (oc2_cnt)
75 while (!(TFLG1 0x40)) / wait for 20000 E
cycles / TFLG1 0X40 TOC2
20000 oc2_cnt -- TMSK2 0xEF /
disable PAI interrupt / INTR_OFF ( ) /
/ printf(\n The frequency of the unknown
signal is d \n, frequency) return
0 pragma interrupt_handler PAI_ISR (
) PAI_ISR ( ) TFLG2 0x10 / clear PAIF
flag / frequency Drawback of Using PAI
interrupt - interrupt handling overhead is too
high - can only measure frequency up to about
43KHz.
76Using the PA function to measure the duration of
an unknown signal - The gated accumulation mode
can be used to measure the duration of an unknown
signal. - Initialize PACNT to 0. - Select the
falling edge of the PAI signal as the active
edge. An interrupt will be generated on the
falling edge. - Enable the PAI interrupt and wait
for the arrival of the PAI active edge - Stop the
PA function when the interrupt occurs. - The
number of times that PACNT overflows should be
kept track of in order to measure a very slow
signal. pulse width (28 paov_cnt pacnt)
64 TE where, paov_cnt is the PACNT
overflow count, pacnt is the contents of the
PACNT counter when interrupt occurs. Example
8.17 Write a program to measure the duration of
an unknown signal connected to the PAI
pin. Solution
77regbas equ 1000 TCNT equ 0E TMSK2 equ
24 TFLG2 equ 25 PACTL equ 26 PACNT equ
27 stop equ 00 value to stop the pulse
accumulator pa_in equ 01100000 value to be
written into PACTL to enable PA, select
gated accumulation mode, and set PAI to be
active high org 00 paov_cnt rmb 2 keep
track of PACNT overflow count pa_cnt rmb 1
holds the contents of the PACNT at the end of
measurement edge rmb 1 PAI edge interrupt
count org 00CA set up interrupt vector
jump table entries for PAOV and PAI jmp
pai_hnd jmp paov_hnd
78 ORG C000 LDS DFFF LDX regbas LDD
0 STD paov_cnt initialize the PACNT overflow
count to 0 LDAA 1 STAA edge initialize
PAI signal edge count to 1 BCLR TFLG2,X CF
clear PAOVF and PAIF flags to 0 LDAA
pa_in STAA PACTL,X initialize the PA
function CLR PACNT,X reset the PACNT counter
to 0 BSET TMSK2,X 30 enable the PAOV and PAI
edge interrupts CLI enable interrupt to the
68HC11 wait TST edge wait for the arrival of
PAI falling edge BNE wait BCLR PACTL,X
40 disable the PA function LDAA PACNT,X
make a copy of PACNT STAA pa_cnt SWI
79 the PAI interrupt service routine is in the
following pai_hnd BCLR TFLG2,X EF clear the
PAIF flag DEC edge reset the edge flag to
0 RTI The PAOV interrupt service routine is
in the following paov_hnd BCLR TFLG2,X DF
clear the PAOVF flag LDD paov_cnt increment
the PAOV count ADDD 1 STD paov_cnt
RTI END
80C Program for Measuring Pulse Width Using PA
Gated Accumulation Mode include
lthc11.hgt include ltstdio.hgt void PAI_ISR (
) void PAOV_ISR ( ) unsigned int paov_cnt,
pai_cnt, edge main ( ) unsigned long
pulse_width (unsigned char )0xca
0x7E (void ()())oxcb PAI_ISR (unsigned
char )0xcd 0x7E (void ()())0xce
PAOV_ISR paov_cnt 0 edge 1 TFLG2
0x30 / clear PAIF and PAOVF flags / PACTL
0x60 PACNT 0 TMSK2 0x30 / enable PAI
and PAOV interrupts /
81 INTR_ON ( ) while (edge) PACTL 0xBF /
disable PA function / pulse_width paov_cnt ltlt
8 PACNT printf(\n The pulse width of the
signal is d \n, pulse_width) return
0 pragma interrupt_handler PAI_ISR ( ) void
PAI_ISR ( ) TFLG2 0x10 / clear PAIF flag
/ edge -- pragma interrupt_handler PAOV_ISR
( ) void PAOV_ISR ( ) TFLG2 0x20 / clear
PAOVF flag / paov_cnt