Chapter 8: 68HC11 Timer Functions The 68HC11 Microcontroller

advertisement
The 68HC11 Microcontroller
The 68HC11 Microcontroller
3. Output compare functions
Chapter 8: 68HC11 Timer Functions
The 68HC11 Microcontroller
• A (E) series members have five (four/five) channels (OC1…OC5)
• 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
Han-Way Huang
• generates periodic interrupts when enabled
• interrupt period is programmable
Minnesota State University, Mankato
5. Computer operating properly (COP)
discussed in Chapter 6
6. Pulse accumulator
• has an 8-bit counter
• has two operation modes
• can be used to measure events, frequency, or the duration of a pulse width
The 68HC11 Microcontroller
The 68HC11 Microcontroller
Applications 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
The 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.
TOI
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
TOF
MCU
E clock
Prescaler
divide by
1, 4, 8, or 16
TCNT(H) TCNT(L)
16-bit free-running
counter
16-bit timer bus
Figure 8.1 68HC11 main timer system
Taps for RTI, COP
watchdog, and
pulse accumulator
Interrupt
request
The 68HC11 Microcontroller
The 68HC11 Microcontroller
Registers related to Main Timer
Solution:
1. Timer counter: TCNT
2. Timer flag register 2: TFLG2
3. Timer mask register 2: TMSK2
- 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.
- 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.
value after
reset
7
6
5
4
3
2
1
0
TOI
RTII
PAOII
PAII
0
0
PR1
PR0
0
0
0
0
0
0
0
0
6
5
4
3
2
1
0
0
0
0
0
7
value after
reset
TOF
0
RTIF PAOVF
0
0
PAIF
0
This is not what we expect. If the instruction LDD TCNT,X is executed, then A and B
will contain $5E and $FE respectively.
TMSK2
at $1024
TFLG2
at $1025
Figure 8.2 TMSK2 and TFLG2 registers
The 68HC11 Microcontroller
The 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.
Overflow period
PR1
PR0
Prescale
factor
2 MHz
E clock
1 MHz
E clock
0
0
1
1
0
1
0
1
1
4
8
16
32.77 ms
131.1 ms
262.1.ms
524.3 ms
65.54 ms
262.1 ms
524.3 ms
1.049 ms
The 68HC11 Microcontroller
Input 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.
Rising edge
Falling edge
or
Table 8.1 Main timer clock frequency vs. PR1 and PR0
Figure 8.3 Events represented by signal edges
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
TCNTH
TCNTL
equ $1000
equ $0E
equ $0F
ldx #regbas
ldaa TCNTH,X
ldaa TCNTL,X
- 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.
ICxI
; read the upper byte of TCNT
; read the lower byte of TCNT
16-bittimer
bus
16-bitlatch
TICx
ICxF
Edge-detection
logic
Figure 8.4 Input-capture function block diagram
Interrupt
request
ICx pin
The 68HC11 Microcontroller
- The edge to be captured is selected by programming the register TCTL2.
TCTL2
EDG1B EDG1A EDG2B EDG2A EDG3B EDG3A at $1021
value after
reset
0
0
0
0
0
0
1
0
1
BCLR TFLG1,X $FE
Figure 8.5 Contents of TCTL2
will clear the IC3F flag. (Assume the index register contains $1000 and TFLG1 = $23)
For example, the following instruction sequence captures the rising edge of the signal applied
at PA0 (IC3):
equ $1000
equ $21
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,
capture disabled
capture on rising edge
capture on falling edge
capture on both edges
x = 1,...,3
regbas
TCTL2
How to clear a timer flag bit?
0
EDGxB ED GxA
0
0
1
1
The 68HC11 Microcontroller
; 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
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.
The 68HC11 Microcontroller
Applications of Input Capture function
Registers related to input capture
1. timer mask register 1 (TMSK1):
7
OC1I
6
OC2I
0
0
5
OC3I
4
OC4I
0
The 68HC11 Microcontroller
0
3
OC5I
2
IC1I
1
IC2I
0
IC3I
0
0
0
0
- 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
- Event arrival time recording
- Period measurement: the input capture function captures the main timer values
corresponding to two consecutive rising or falling edges
one period
(a) Capture two rising edges
one period
2. timer flag register 1 (TFLG1):
value after
reset
7
6
5
4
3
2
1
0
OC1F
OC2F
OC3F
OC4F
OC5F
IC1F
IC2F
IC3F
0
0
0
0
0
0
0
0
(b) Capture two falling edges
TFLG1
at $1023
Figure 8.8 Period measurement by capturing two consecutive edges
- Pulse width measurement: capture the rising and falling edges
Figure 8.6 The contents of the TFLG1 register
- 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
Pulse width
Rising edge
Falling edge
Figure 8.9 Pulse-width measurement using input capture
The 68HC11 Microcontroller
- Interrupt generation: three input capture functions can be used as three edge-sensitive
interrupt sources.
- Event counting: by counting the number of signal edges arrived during a period
e1 e2
e3
e4
...
ei
...
The 68HC11 Microcontroller
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.
Start
Solution:
Choose to capture the rising edge
ej
Start of
interval
End of
interval
- two versions are available.
- The polling method is shown
in Figure 8.15.
Clear the IC1F flag
no
Figure 8.10 Using an input-capture function for event counting
IC1F = 1?
yes
Save the captured value
of the first edge.
Clear the IC1F flag.
- Time reference: often used in combination with an output compare function
Time t 0
Time t0 + delay
no
IC1F = 1?
yes
Time ofreference
(set up by signal edge)
Take the difference
of the second and
the first edges.
Time to activate
output signal
(set up by output compare)
Figure 8.11 A time reference application
Stop
Figure 8.15 Logic flow of the period-measurement program (polling method)
The 68HC11 Microcontroller
The 68HC11 Microcontroller
Assembly Program for Period Measurement (Polling Method)
Duty Cycle Measurement
T
∆T
duty cycle =
∆T
T
* 100%
REGBAS
TLFG1
TIC1
TCTL2
IC1rise
Figure 8.12 Definition of duty cycle
edge1
period
Phase Difference Measurement
T
signal S1
∆T
signal S2
phase difference =
∆T
T
* 360o
Figure 8.13 Phase difference definition for two signals
EQU $1000
EQU $23
EQU $10
EQU $21
EQU $10
ORG $00
RMB 2
RMB 2
ORG $C000
LDX #REGBAS
BCLR TFLG1,X $FB
LDAA #IC1rise
STAA TCTL2,X
BRCLR TFLG1,X $04 *
LDD TIC1,X
STD edge1
BCLR TFLG1,X $FB
BRCLR TFLG1,X $04 *
LDD TIC1,X
SUBD edge1
STD period
END
; clear IC1F flag
; capture rising edge
; wait for the first rising edge
; save the first edge
; clear IC1F flag
; wait for the second edge
; save the period
The 68HC11 Microcontroller
C Program for Period Measurement (Polling method)
#include <hc11.h>
#include <stdio.h>
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;
}
The 68HC11 Microcontroller
Interrupt-driven Method for Period Measurement
Start
Select to capture the
rising edge of IC1
u pt
inte
rr
edge_cnt = 1?
yes
IC 1
edge_cnt
2
Clear IC1F flag
Clear IC1F flag
Decrement edge_cnt
Enable IC1 interrupt
no
edge_cnt = 0?
yes
Save the first edge
return from interrupt
Return
from inte
rrupt
period = edge2 - edge1
Stop
Figure 8.16 Interrupt-driven method for period measurement
no
The 68HC11 Microcontroller
REGBAS
TFLG1
TMSK1
TIC1
TCTL2
IC1rise
IC1I
IC1FM
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
$1000
$23
$22
$10
$21
$10
$04
$FB
; base address of the I/O register block
; offset of TFLG1 from regbas
; offset of TMSK1 from regbas
; offset of TIC1 from regbas
; offset of TCTL2 from regbas
; value to select the rising edge of IC1 to capture
; mask to select the IC1 bit in TMSK1
; mask to clear IC1F using the BCLR instruction
edge_cnt
edge1
period
ORG
RMB
RMB
RMB
$0000
1
2
2
; edge count
; captured first edge
; period in number of E clock cycles
ORG
JMP
$E8
IC1_ISR
; IC1 interrupt jump table entry on the EVB
;
“
ORG
LDS
LDX
LDAA
STAA
BCLR
LDAA
$C000
; starting address of the main program
#$DFFF
; set up stack pointer
#REGBAS
#IC1rise
; select to capture the rising edge of IC1
TCTL2,X
;
“
TFLG1,X IC1FM
; clear the IC1F flag
#2
The 68HC11 Microcontroller
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
The 68HC11 Microcontroller
C Language Program for Period Measurement (Interrupt-Driven Method)
#include <hc11.h>
#include <stdio.h>
int edge_cnt
unsigned int edge1, period;
void IC1_ISR ( );
The 68HC11 Microcontroller
Example 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
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;
}
regbas
TFLG1
TIC1
TCTL2
IC1rise
IC1fall
IC1F
temp
pul_width
EQU $1000
EQU $23
EQU $10
EQU $21
EQU $10
EQU $20
EQU $04
EQU $00
PSHX
PSHY
DES
DES
TSY
LDX #regbas
The 68HC11 Microcontroller
#pragma interrupt_handler IC1_ISR ( )
void IC1_ISR ( )
{
TFLG1 = 0x04;
/* clear IC1F flag */
if (edge_cnt == 2)
edge1 = TIC1;
/* save the first edge */
-- edge_cnt;
}
; base address of the I/O register block
; offset of TFLG1 from regbas
; offset of TIC1 from regbas
; offset of TCTL2 from regbas
; value to select the rising edge of IC1
; value to select the falling edge of IC1
; a mask to select the IC1F flag
; offset of temp from the top of the stack
; allocate two bytes for local variable temp
The 68HC11 Microcontroller
rise
fall
LDAA
STAA
LDAA
STAA
BRCLR
LDD
STD
LDAA
STAA
LDAA
STAA
BRCLR
LDD
SUBD
INS
INS
PULY
PULX
RTS
#IC1rise
; configure TCTL2 to capture the rising edge of IC1
TCTL2,X
;
“
#IC1F
; clear IC1F flag
TFLG1,X
;
“
TFLG1,X IC1F rise ; wait for the arrival of the rising edge
TIC1,X
; save the first edge
temp,Y
;
“
#IC1fall
; configure to capture the falling edge of IC1
TCTL2,X
;
“
#IC1F
; clear IC1F flag
TFLG1,X
;
“
TFLG1,X IC1F fall ; wait for the arrival of the falling edge
TIC1,X
; get the captured time of the second edge
temp,Y
The 68HC11 Microcontroller
The 68HC11 Microcontroller
Start
Measuring the period or pulse width of a slow signal (longer than 32.76 ms)
overflow
0
Set up to capture the rising edge.
Disable all interrupts.
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 2:
yes
+ diff
no
in
ter
ru
pt
R etu
IC1F = 1?
Clear TOF flag.
overflow
overflow + 1.
V
Clear IC1F flag.
Save the first captured edge.
216
Timer overflow interrupt
service routine
Clear timer overflow flag.
Enable main timer overflow interrupt.
edge2 ≥ edge1
period (or pulse width) = ovcnt ×
IC1F = 1?
TO
Case 1:
no
Execute the RTI instruction.
rn fr o
m in te
rr
up t
yes
edge2 < edge1
Compute the difference of two edges.
period (or pulse width) = (ovcnt - 1) × 216 + diff
no
The main timer overflows at least once in this case.
Is second edge smaller?
yes
overflow - 1
overflow
Combine the results.
Stop
Figure 8.17 Logic flow for measuring period of slow signals
The 68HC11 Microcontroller
Example 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.
The 68HC11 Microcontroller
regbas
TFLG1
TIC1
TCTL2
TMSK1
TMSK2
IC1rise
EQU
EQU
EQU
EQU
EQU
EQU
EQU
$1000
$23
$10
$21
$22
$24
$10
; base address of I/O register block
; offset of TFLG1 from regbas
; offset of TIC1 from regbas
; offset of TCTL2 from regbas
; offset of TMSK1 from regbas
; offset of TMSK2 from regbas
; value to select the rising edge of IC1
edge1
ov_cnt
period
ORG
RMB
RMB
RMB
$0000
2
2
2
; captured time of the first edge
; main timer overflow count
; period of the unknown signal
ORG
JMP
ORG
LDS
SEI
CLR
CLR
LDX
$00D0
tov_ISR
$C000
#$DFFF
ov_cnt
ov_cnt+1
#regbas
; setup timer overflow interrupt vector jump table entry
; on EVB
; set up stack pointer
; disable all maskable interrupts to the 68HC11
; initialize overflow count to 0
;
“
The 68HC11 Microcontroller
LDAA #IC1rise
STAA TCTL2,X
BCLR TFLG1,X $FB
BCLR TMSK1,X $FF
BRCLR TFLG1,X $FB *
; select to capture the rising edge
;
“
; clear IC1F flag
; disable all input capture and output compare interrupts
; wait for the arrival of the first edge
BCLR TFLG2,X $7F
BSET TMSK2,X $80
CLI
LDD TIC1,X
STD edge1
BCLR TFLG1,X $FB
BRCLR TFLG1,X $04 *
LDD TIC1,X
SUBD edge1
; clear TOF flag
; enable timer overflow interrupt
; enable interrupt to the 68HC11
; save the captured time of the first edge
;
“
; clear IC1F flag
; wait for the arrival of the second edge
; compute the difference of edge2 and
; edge1
The 68HC11 Microcontroller
C Program for Measuring the Period of a Slow Signal
#include <hc11.h>
#include <stdio.h>
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 IC1’s 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 */
The 68HC11 Microcontroller
next
tov_ISR
STD
BCC
LDD
SUBD
STD
…
period
next
ov_cnt
#1
ov_cnt
;
“
; is second edge smaller?
; decrement overflow count if second edge is smaller
;
“
;
“
LDX
BCLR
LDD
ADDD
STD
RTI
END
#regbas
TFLG2,X $7F
ov_cnt
#1
ov_cnt
; clear TOF flag
; increment timer overflow count
;
“
;
“
The 68HC11 Microcontroller
TMSK2 = 0x80;
/* enable timer overflow interrupt */
INTR_ON ( );
/*
“ */
while (!(TFLG1 & 0x04)); /* wait for the second rising edge */
if (TIC1 < 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 ++;
}
The 68HC11 Microcontroller
Output 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
OCxI
The 68HC11 Microcontroller
Example 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:
Start
A 1KHz digital with 40% duty
cycle has 400 µs high and 600
µs low in one period. The
flowchart to generate this
waveform is shown in
Figure 8.20.
Set OC2 pin to high
Set OC2 action to toggle
Clear OC2F flag
Start OC2 output compare
with a delay of 400 µs
no
Interrupt request
OC2F = 1?
yes
16-bit comparator
Clear OC2F flag
Start OC2 output compare
with a delay of 600 µs
OCxF
TOCx
x = 1,...,5
Pin
control
logic
FOCx
no
OCx Pin
yes
Figure 8.20 The program logic flow for digital waveform generation
Figure 8.18 Output-compare function block diagram
The 68HC11 Microcontroller
- 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
The 68HC11 Microcontroller
regbas
PORTA
TOC2
TCNT
TFLG1
toggle
lotime
hitime
1. pull up to high
2. pull down to low
3. toggle
The action is determined by the timer control register 1 (TCTL1):
value after
reset
OC2F = 1?
OM2
OL2
OM3
OL3
OM4
OL4
OM5
OL5
0
0
0
0
0
0
0
0
TCTL1
at $1020
OMx OLx
0
0 OCx does not afftect pin
0
1 Toggle OCx pin on successful compare
1
0 Clear OCx on successful compare
1
1 Set OCx pin on successful compare
Figure 8.19 The contents of the TCTL1 register (Reprinted with permission of Motorola)
high
equ
equ
equ
equ
equ
equ
equ
equ
$1000
$00
$18
$0E
$23
$40
1200
800
; base address of I/O register block
; offset of PORTA from regbas
; offset of TOC2 from regbas
; offset of TCNT from regbas
; offset of TFLG1 from regbas
; value to select the toggle action
; value to set low time to 600 µs
; value to set high time to 400 µs
org
ldx
bset
bclr
ldaa
staa
ldd
addd
std
brclr
bclr
ldd
addd
std
$C000
#regbas
PORTA,X $40 ; set OC2 pint to high
TFLG1,X $BF ; clear OC2F flag
#toggle
; select output compare action to be
TCTL1,X
; toggle
TCNT,X
; start an OC2 operation which toggles the OC2 pin
#hitime
; with a delay of 800 E clock cycles
TOC2,X
;
“
TFLG1,X $40 high
; wait until OC2F is set to 1
TFLG1,X $BF ; clear OC2F flag
TOC2,X
; start another OC2 operation which toggles the OC2 pin
#lotime
; with a delay of 1200 E cycles
TOC2,X
;
“
The 68HC11 Microcontroller
low
brclr
bclr
ldd
addd
std
bra
end
TFLG1,X $40 low
; wait until OC2F is set to 1
TFLG1,X $BF ; clear OC2F flag
TOC2,X
; start another OC2 operation which toggles the OC2 pin
#hitime
; with a delay of 800 E cycles
TOC2,X
;
“
high
The 68HC11 Microcontroller
Example 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.
The 68HC11 Microcontroller
In C language,
#include <hc11.h>
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 µs */
TFLG1 = 0x40;
TOC2 += 1200;
/* start next OC2 operation with 1200 E cycles as delay */
while (!(TFLG1 & 0x40)); /* wait for 600 µs */
TFLG1 = 0x40;
TOC2 += 800;
}
return 0;
}
The 68HC11 Microcontroller
regbas
TOC2
TCNT
TFLG1
dly25ms
onesec
oc2_cnt
EQU
EQU
EQU
EQU
EQU
EQU
EQU
$1000
$18
$0E
$23
50000
40
0
; base address of I/O register block
; offset of TOC2 from regbas
; offset of TCNT from regbas
; offset of TFLG1 from regbas
; the number of E cycles to generate 25 ms delay
; number of OC2 operations to be performed
; 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
The 68HC11 Microcontroller
exit
The 68HC11 Microcontroller
regbas
TOC2
TCNT
TFLG1
TMSK1
dly20ms
one_min
*
BEQ exit
LDD TOC2,X
BRA wait
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 */
}
}
hours
minutes
ticks
alarm
routine
equ
equ
equ
equ
equ
equ
equ
$1000
$18
$0E
$23
$22
40000
3000
org
rmb
rmb
rmb
rmb
fdb
$0000
1
1
2
2
start_alarm
org
jmp
$00DC
oc2_ISR
org
lds
sei
ldd
std
$C000
#$DFFF
#one_min
ticks
The 68HC11 Microcontroller
; starting address of the alarm routine
; interrupt jump table entry for OC2 on EVB
; set up stack pointer
; disable interrupt before setup is done
; initialize the OC2 count to generate
; one minute delay
The 68HC11 Microcontroller
Example 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
; number of E cycles equivalent to 20 ms delay
; number of OC2 operations to be created to
; generate 1 minute delay
forever
oc2_ISR
ldx #regbas
bclr TFLG1,X $BF
bset TMSK1,X $04
ldd TCNT,X
addd #dly20ms
std TOC2,X
cli
bra forever
; clear OC2F flag
; enable OC2 interrupt
; start an OC2 operation with
; 20 ms delay
;
“
; enable interrupt to the 68HC11
; loop forever to wait for interrupt
ldx #regbas
bclr TFLG1,X $BF
ldd TOC2,X
addd #dly20ms
std TOC2,X
ldy ticks
dey
sty ticks
bne case2
ldd #one_min
std ticks
ldd hours
; clear OC2 flag
; start the next OC2 operation with
; 20 ms delay
;
“
; decrement the minute count
;
“
;
“
; is one minute expired?
; reinitialize the one-minute counter
;
“
; load the hours and minutes
The 68HC11 Microcontroller
case1
case2
INCB
CMPB
BNE
CLRB
INCA
CMPA
BNE
CLRA
STD
CPD
BNE
LDX
JSR
RTI
END
#60
case1
#24
case1
hours
alarm
case2
routine
0,X
; is it time to increment the hour?
; no need to update hour digits yet
; reset minutes to 0
; increment the hour
; it is time to reset hours to 0?
; no need to reset hour yet
; reset hours to 00
; save the current time in memory
; reaches alarm time?
; call the alarm routine
The 68HC11 Microcontroller
unsigned char flas_tab [25][2] = {{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 < 25; i++) {
PORTB = flash_tab [i][0];
delay (flash_tab[i][1]);
}
}
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 */
}
}
The 68HC11 Microcontroller
Example 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 ¼ seconds—repeat this pattern 4 times.
2. Light one LED at a time for one second—from 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.
5V
68H C11A8
The 68HC11 Microcontroller
Using 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.
74LS04 100 Ω
PB7
value after
reset
PB6
PB5
PB4
PB3
PB2
value after
reset
PB1
PB0
7
6
5
4
3
2
1
0
M7
M6
M5
M4
M3
0
0
0
0
0
0
0
0
0
0
0
PA7
OC2
OC3
OC4
OC5
7
6
5
4
3
2
1
0
D7
D6
D5
D4
D3
0
0
0
0
0
0
0
0
0
0
0
pin controlled
Figure 8.22 Contents of the OC1M and OC1D registers (Reprinted
with permission of Motorola)
Figure 8.21 An LED-flashing circuit driven by port B
OC1M
at $100C
OC1D
at $100D
The 68HC11 Microcontroller
The 68HC11 Microcontroller
Example 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:
oc1d_in2 equ
five_sec equ
dly25ms equ
- Set bits 6 and 5 of OC1M to 11
- Set bits 6 and 5 of OC1D to 01
oc1_cnt
regbas
OC1M
OC1D
EQU
EQU
EQU
$1000
$0C
$0D
LDX
LDAA
STAA
LDAA
STD
…
In C language
#regbas
#%01100000
OC1M,X
#%00100000
OC1D
repeat1
OC1M = 0x60;
OC1D = 0x20;
ORG
rmb
ORG
ldx
bset
ldaa
staa
bclr
ldaa
staa
ldaa
staa
ldd
addd
std
brclr
bclr
$50
200
50000
$0000
1
; number of OC1 operations remained to be performed
$C000
#regbas
PACTL,X $80 ; configure PA7 pin for output
#oc1m_in
; allow OC1 function to control all OC pins
OC1M,X
;
“
TFLG1,X $7F ; clear OC1F flag
#five_sec
oc1_cnt
#oc1d_in1
; set pins OC1, OC3, and OC5 to high after 25 ms
OC1D,X
TCNT,X
; start an OC1 operation with 25 ms delay
#dly25ms
;
“
TOC1,X
;
“
TFLG1,X $80 * ; wait for 25 ms
TFLG1,X $7F ; clear OC1F flag
The 68HC11 Microcontroller
Example 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
PACTL
OC1D
OC1M
TOC1
TCNT
TFLG1
oc1m_in
oc1d_in1
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
$1000
$26
$0D
$0C
$16
$0E
$23
$F8
$A8
The 68HC11 Microcontroller
change
repeat2
switch
; value to initialize OC1M
; value to initialize OC1D to open valves 1, 3, and 5
; value to initialize OC1D to open valves 2 and 4
; number of OC1 operations to be performed
; the number of E clock cycles equivalent to 25 ms
dec
beq
ldd
bra
ldaa
staa
ldaa
staa
ldd
addd
std
brclr
bclr
dec
oc1_cnt
change
TOC1,X
repeat1
#oc1d_in2
OC1D,X
#five_sec
oc1_cnt
TOC1,X
#dly25ms
TOC1,X
TFLG1,X $80 *
TFLG1,X $7F
oc1_cnt
beq
bra
ldaa
staa
ldaa
staa
ldd
bra
end
switch
repeat2
#five_sec
oc1_cnt
#oc1d_in1
OC1D,X
TOC1,X
repeat1
; decrement the output compare count
; at the end of 5 seconds change the valves setting
; prepare to perform the next OC1 operation
; set to open valves 2 and 4
;
“
; reinitialize the output compare count
;
“
; start the next OC1 operation with the same
; delay
;
“
; wait until OC1F flag is set to 1
; clear OC1F flag
; five seconds expired, switch the valve setting
; reinitialize the OC1 count
;
“
; change the valve setting
;
; prepare to start the next OC1 operation
The 68HC11 Microcontroller
#include <hc11.h>
main ()
{
unsigned int oc1_cnt;
PACTL |= 0x80;
OC1M = 0xF8;
TFLG1 = 0x80;
TOC1 = TCNT + 20000;
while (1) {
OC1D = 0xA8;
oc1_cnt = 500;
while (oc1_cnt) {
while (!(TFLG1 &
TFLG1 = 0x80;
TOC1 += 20000;
oc1_cnt --;
}
OC1D = 0x50;
oc1_cnt = 500;
while (oc1_cnt) {
while (!(TFLG1 &
TFLG1 = 0x80;
TOC1 += 20000;
oc1_cnt --;
}
}
}
/* configure PA7 for output */
/* allow OC1 to control OC1-OC5 pins */
/* clear OC1F flag */
/* start an OC1 operation with 10 ms delay */
/* prepare to set PA7, PA5, and PA3 to high */
/* number of OC1 operations to create 5 s delay */
0x80));
/* clear OC1F flag */
/* start the next OC1 operation */
The 68HC11 Microcontroller
regbas
TMSK1
PORTA
OC1D
OC1M
TOC1
TOC2
TCTL1
TFLG1
tctl1_in
oc1m_in
oc1d_in
fiveKHz
diff
/* value to pull PA6 and PA4 to high */
0x80));
/* clear OC1F flag */
/* start the next OC1 operation */
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
$1000
$22
$00
$0D
$0C
$16
$18
$20
$23
$80
$40
$40
400
160
; value to set the OC2 action to be pull the OC2 pin to low
; value to allow OC1 function to control OC2 pin
; value to be written into OC1D to pull OC2 to high
; timer count for 5 KHz (2 MHz E clock cycles)
; the count difference of two output compare functions
org
jmp
jmp
$00DC
oc2_ISR
oc1_ISR
; interrupt vector jump table entry for OC2
; interrupt vector jump table entry for OC1
org
lds
ldx
bclr
$C000
#$DFFF
#regbas
TFLG1,X $3F ; clear OC1F and OC2F flags
The 68HC11 Microcontroller
The 68HC11 Microcontroller
OC1 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 µs.
Use OC2 function to pull OC2 pin to low 80 µs 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 µs delay.
loop
68HC11
80µs
OC2
120µs
Figure 8.23 Using OC1 and OC2 to generate a 40% duty cycle waveform
ldaa
staa
ldaa
staa
ldaa
staa
bset
bclr
ldd
addd
std
addd
std
cli
bra
#tctl1_in
TCTL1,X
#oc1d_in
OC1D,X
#oc1m_in
OC1M,X
TMSK1,X $C0
PORTA,X $40
TCNT,X
#fiveKHz
TOC1,X
#diff
TOC2,X
loop
; define OC2 action to pull OC2 pin to low
;
“
; define OC1 action to pull OC2 pin to high
;
“
; allow OC1 function to control OC2 pin
;
“
; enable OC1 and OC2 interrupts
; pull OC2 pin to low
; start the OC1 operation with a delay of 200 µs
;
“
;
“
; start the OC2 operation
;
“
; enable interrupt to the 68HC11
; infinite loop to wait for OC1 and OC2 interrupts
The 68HC11 Microcontroller
* 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 µs
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 µs
addd #fiveKHz
;
“
std
TOC2,X
;
“
rti
end
The 68HC11 Microcontroller
#pragma 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 */
}
The 68HC11 Microcontroller
The 68HC11 Microcontroller
C Language Program Using OC1 & OC2 to generate a waveform
Forced Output Compare
#include <hc11.h>
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;
}
- 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.
7
value after
reset
6
5
4
3
FORC1 FORC2 FORC3 FORC4 FORC5
0
0
0
0
0
2
1
0
0
0
0
0
0
0
CFORC
at $100B
Figure 8.24 Contents of the CFORC register (Redrawn with permission of Motorola)
The 68HC11 Microcontroller
Example 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
Bit positions
7
5
3
1
6
4
2
0
Value
Action to be triggered
10
01
10
00
clear OC2 pin
toggle OC3 pin
clear OC4 pin
no effect on OC5 pin
The 68HC11 Microcontroller
regbas
TMSK2
TFLG2
PACTL
tensec
RTIF
rti_cnt
Table 8.5 Pin actions on OC2-OC5 pins
-
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
loop
EQU
EQU
EQU
EQU
EQU
EQU
ORG
RMB
ORG
JMP
ORG
LDS
LDX
LDD
STD
BSET
LDAA
STAA
STAA
CLI
LDD
BNE
SWI
$1000
$24
$25
$26
305
$40
$0000
2
$00EB
rti_hnd
$C000
#$DFFF
#regbas
#tensec
rti_cnt
PACTL,X $03
#RTIF
TFLG2,X
TMSK2,X
rti_cnt
loop
; total RTI interrupts in 10 s
; mask to select the RTIF flag
; remaining RTI interrupts to be generated
; RTI interrupt vector jump table entry
;
“
; initialize stack pointer
; select RTI clock prescale factor to 8
; clear RTIF flag
; enable RTI function
; enable interrupt to the 68HC11
; wait until rti_cnt becomes 0
The 68HC11 Microcontroller
The 68HC11 Microcontroller
Real-Time Interrupt (RTI)
RTI service routine is as follows:
- 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
rti_hnd
RTR1
bit 1
RTR0
bit 0
(E/2 13) divided by
0
0
1
1
0
1
0
1
1
2
4
8
LDX
BCLR
LDX
DEX
STX
RTI
#regbas
TFLG2,X $BF
rti_cnt
rti_cnt
Start
Set RTI clock prescale factor to 8
RTI_cnt ← 305
Table 8.6 RTI clock source prescale factor
Clear RTIF flag in FLG2
Enable 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
I
RT
e rr
in t
t
up
Clear RTIF flag in TFLG2
RTI_cnt ← RTI_cnt - 1
Return from interrupt
RTI_cnt = 0?
Return
from
interru
pt
Stop
Figure 8.25 Using RTI to create a 10-second delay
The 68HC11 Microcontroller
C 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 --;
}
The 68HC11 Microcontroller
- 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):
bit 6 (PAEN):
bit 5 (PAMOD):
bit 4 (PEDGE):
-
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
Value after
reset
Value after
reset
Value after
reset
Value after
reset
7
6
5
4
3
2
1
0
TOI
RTII
PAOVI
PAII
0
0
PR1
PR0
0
0
0
0
0
0
0
0
TOF
RTIF
0
0
0
0
0
0
0
0
0
0
DDRA7
PAOVF PAIF
0
0
PAEN PAMOD PEDGE
0
0
RTR1
RTR0
0
0
0
0
0
0
0
0
bit 7
bit 6
bit 5
bit 4
bit 3
bit 2
bit 1
bit 0
-
-
-
-
-
-
-
-
TMSK2
at $1024
TFLG2
at $1025
PACTL
at $1026
PACNT
at $1027
Figure 8.26 Registers related to the pulse accumulator function (Redrawn with permission of
Motorola)
PAMOD
PEDGE
0
0
1
1
0
1
0
1
Action on clock
PAI falling edge increments the counter
PAI rising edge increments the counter
A 0 on PAI inhibits counting
A 1 on PAI inhibits counting
Table 8.7 Combinations of PAMOD and PEDGE bits
The 68HC11 Microcontroller
The Pulse Accumulator
0 -- configure PA7 pin for input; 1 -- configure PA7 for output
0 -- disable PA function;
1 -- enable PA function
0 -- select event-counting mode; 1 -- select gated accumulation mode
its meaning depends on bit 5
The 68HC11 Microcontroller
Example 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
LDX
BCLR
LDAA
NEGA
STAA
LDAA
STAA
BSET
CLI
END
$C000
#regbas
TFLG2,X $DF ; clear the PAOVF flag
#N
; complement N
PACNT,X
; initialize PACNT to -N
#PA_INI
PACTL,X
TMSK2,X $20 ; enable the PACNT overflow interrupt
; enable interrupt to the 68HC11
The 68HC11 Microcontroller
The 68HC11 Microcontroller
regbas
TCNT
TOC2
TFLG1
TMSK2
TFLG2
PACTL
PACNT
oc2dly
pa_in
*
*
onesec
stop
C Program that Interrupts After N Events
#include <hc11.h>
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 ( )
{
…
}
oc2_cnt
freqcy
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
EQU
$1000
$0E
$18
$23
$24
$25
$26
$27
50000
$50
EQU
EQU
40
$10
; output compare count for 25 ms delay
; value to enable PA, select event-counting mode, rising
; edge as active edge,
; and set PA pin for input
; number of OC2 operations to be performed
; value to disable the PA interrupt
ORG
RMB
RMB
ORG
JMP
$0000
1
2
$CA
pa_ISR
; active edge count in one second
; interrupt vector jump table entry for PAI edge
;
“
The 68HC11 Microcontroller
Use 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
The 68HC11 Microcontroller
ORG
LDS
LDX
LDAA
STAA
LDD
STD
LDAA
STAA
BCLR
BSET
CLI
LDD
sec_loop ADDD
STD
BCLR
BRCLR
LDD
DEC
BNE
LDAA
STAA
SWI
$C000
#$DFFF
#regbas
#onesec
oc2_cnt
#0
freqcy
#pa_in
PACTL,X
TFLG2,X $EF
TMSK2,X $10
; initialize OC2 count
; initialize frequency counter to 0
; initialize the PA function
;
“
; clear the PAIF flag
; enable the PAI edge interrupt
; enable interrupt to the 68HC11
TCNT,X
; start an OC2 operation with a delay
#oc2dly
; of 25 ms
TOC2,X
;
“
TFLG1,X $BF ; clear OC2F flag
TFLG1,X $40 * ; wait for 25 ms
TOC2,X
oc2_cnt
sec_loop
; if 1 second is not expired, continue.
#stop
; disable PAI edge interrupt
TMSK2,X
;
“
; return to BUFFALO monitor
The 68HC11 Microcontroller
pa_ISR
LDX
BCLR
LDX
INX
STX
RTI
END
The 68HC11 Microcontroller
while (!(TFLG1 & 0x40));
TFLG1 = 0X40;
TOC2 += 20000;
oc2_cnt --;
#regbas
TFLG2,X $EF ; clear the PAIF flag
freqcy
; increment frequency counter
;
“
freqcy
;
“
/* wait for 20000 E cycles */
}
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.
The 68HC11 Microcontroller
The 68HC11 Microcontroller
C Program that Uses PAI to Measure the Frequency
Using the PA function to measure the duration of an unknown signal
#include <hc11.h>
#include <stdio.h>
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) {
- 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:
The 68HC11 Microcontroller
regbas
TCNT
TMSK2
TFLG2
PACTL
PACNT
stop
pa_in
*
paov_cnt
pa_cnt
edge
equ
equ
equ
equ
equ
equ
equ
equ
$1000
$0E
$24
$25
$26
$27
$00
%01100000
org
rmb
rmb
rmb
$00
2
1
1
; keep track of PACNT overflow count
; holds the contents of the PACNT at the end of measurement
; PAI edge interrupt count
org
jmp
jmp
$00CA
pai_hnd
paov_hnd
; set up interrupt vector jump table entries for PAOV and PAI
;
“
;
“
The 68HC11 Microcontroller
* 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
; value to stop the pulse accumulator
; value to be written into PACTL to enable PA, select gated
; accumulation mode, and set PAI to be active high
* 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
The 68HC11 Microcontroller
wait
ORG
LDS
LDX
LDD
STD
LDAA
STAA
BCLR
LDAA
STAA
CLR
BSET
CLI
TST
BNE
BCLR
LDAA
STAA
SWI
$C000
#$DFFF
#regbas
#0
paov_cnt
#1
edge
TFLG2,X $CF
#pa_in
PACTL,X
PACNT,X
TMSK2,X $30
The 68HC11 Microcontroller
C Program for Measuring Pulse Width Using PA Gated Accumulation Mode
; initialize the PACNT overflow count to 0
; initialize PAI signal edge count to 1
; clear PAOVF and PAIF flags to 0
; initialize the PA function
; reset the PACNT counter to 0
; enable the PAOV and PAI edge interrupts
; enable interrupt to the 68HC11
edge
; wait for the arrival of PAI falling edge
wait
;
“
PACTL,X $40 ; disable the PA function
PACNT,X
; make a copy of PACNT
pa_cnt
;
“
#include <hc11.h>
#include <stdio.h>
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 */
The 68HC11 Microcontroller
INTR_ON ( );
while (edge);
PACTL &= 0xBF;
/* disable PA function */
pulse_width = paov_cnt << 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 ++;
}
Download