Transcript CSE22MAL

ELE22MIC Lecture 18
• Writing 68HC11 software
• 68HC11 Main Timer System
– Output Compare
– What is different about TOC1?
Writing 68HC11 software
Use Functional Decomposition
i.e. Break down complex functions into several
simpler functions or subroutines.
For example a long time delay cannot be created using just
one 16 bit counter, so break the time delay into two parts.
1. A short time delay subroutine
2. A long time delay subroutine that calls the short time
delay routine many times.
Software Time Delays
Wait_a_sec:
LDX #1000
Delay_lots:
JSR Wait_a_bit
* wait 10 ms
* Subroutine Wait_a_bit is on next page
DEX
BNE Delay_lots
RTS
* ReTurn from Subroutine
; 3 cycles
; 6 for jsr
;
;3
;3
;5
Software Time Delays
* 1 us = 2 cycles, so 1ms = 2000 cycles.
* 10 cycles per delay_more loop.
* 29 cycles in wait_a_sec/jsr/pshx/setup/rts overhead...
Wait_a_bit:
PSHX
; save x on stack
4
LDX #1971
; X = 2000-29
3
Delay_More:
NOP
; waste some time
2
NOP
;
2
DEX
;X--;
3
BNE Delay_More ; Is (X = 0)?
3
PULX
; recover x
5
RTS
; ReTurn from Subroutine 5
68HC11 Timer - PreScaler
• An E-Clock PreScaler divides by 1, 4, 8 or 16
• This value is selected by writing to Bits PR0,
PR1 of the TMSK2 register (at $1024).
• In normal modes the pre-scale rate may only be
changed once within the first 64 bus cycles after
reset.
68HC11 Timer - PreScaler
• Crystal Frequency vs clock Pre-Scaler
Free Running Counter - TCNT (1)
• The pre-scaled clock clocks a free-running
counter, TCNT (= $100E..$100F)
• The TCNT Count Value can be read using
the instructions:
LDD
$100E Reads all 16 Bits in one instruction.
The Timer value is frozen during this instruction sequence.
DONT read the timer with the following instruction sequence:
LDAA $100E
LDAB $100F
as the counter will be incremented between the instructions
68HC11 Timer System (1)
• The HC11 Timer System is based on a freerunning 16 bit counter with a four stage
programmable pre-scaler. Assuming PR0=0
and PR1 = 0 => TCNT counts at frequency of
divide E by 1
•
(8MHz crystal -> 2MHZ E clock -> 0.5us per count).
• Five Output Compare functions are included
for generating software timing delays or output
signals on pins OC1, OC2, OC3, OC4 and OC5
• OC2..OC5 work in exactly the same manner.
68HC11 Timer System (2)
• Timer Register Summary:
– TCNT - 2-byte Free Running Timer Counter Value
– TOCx/TICx - 8 x 2-byte TIC/TOC count registers
• 5 for Timer Ouput Compare & 4 Timer Input Capture (One shared TIC/TOC)
–
–
–
–
–
–
TMSK1 - 1 byte - Timer Interrupt Enables
TMSK2 - $1024 - PR0/PR1/RTI
OPTION - $1039 - CR0/CR1 - Clock Pre-scaler
CFORC - 1 x byte port for Force output compare
TCTL2 - 1 x byte register for output port control OMx/OLx
TFLG1 - 1 x byte flag register indicating state of comparisons
Timer Output Compare - TOC (1)
• The five Output Compare pins can be used
independently to create precise timing for
time delays or external logic pulses.
• Each Output Compare Register is compared
to the value in the 16 bit counter, and if
equal, triggers its Timer Output Compare
(TOCn) function.
Timer Output Compare (2)
• The output compare hardware can ensure
that intervals and waveforms are not subject
to jitter due to interrupt servicing routines
Timer Output Compare (3)
• TCTL2 $1020, OM2 & OL2 - select the
relationship of Output Compare to Output
Port Pin
OMx OLx where x = 2..5
0
0
No Change
0
1
Toggle Pin state
1
0
Force Pin to 0
1
1
Force Pin to 1
TOC2 code (4)
REGBAS EQU $1000
PORTB EQU $04
TCNT EQU $0E
TOC2 EQU $18
TCTL1 EQU $20
TCTL2 EQU $21
* Starting address for register block
* Output port B
* Free running counter (16 bit)
* OC2 register (16 bit)
* OM2,OL2,OM3,OL3;OM4,OL4,OM5,OL5
* -,-,EDGlB,EDGlA,EDG2B,EDG2A,EDG3B,
* EDG3A
TMSK1 EQU $22
* OC1I,OC2I,OC3I,OC4I;OC51,IC1I,IC2I,IC3I
TFLG1 EQU $23
*OC1F,OC2F,OC3F,OC4F;OC5F,IC1F,IC2F,IC3F
TMSK2 EQU $24
* TOI,RTII,PAOVI,PAII;-,-,PR1,PR0
TFLG2 EQU $25
* TOF,RTIF,PAOVF,PAIF;-,-,-,*** EVB Routine Addresses & Pseudo Vector Equates
PVOC2 EQU $00DC
EVB Pseudo Vector for OC2
ORG $2000 Start variables in RAM (upper half)
HDLY RMB 2
Half-cycle delay (in 0.5mS increments)
TOC2 code (5)
TOP5
LDS #$0047
* Top of User’s Stack area on EVB
LDAA #$7E
* Jump (extended) Opcode
STAA PVOC2
* Pseudo Vector see manual text
LDX #SV5OC2
* Address of OC2 service routine
STX PVOC2+1
* Finish jump instruc to TOF svc
LDX #REGBAS
* Point to register block
LDAA #%01000000 * OM2:OL2 = 0:1
STAA TCTL1,X
* Set OC2 for toggle, on compare
STAA TFLG1,X
* Clear any pending,OC2F
STAA TMSK1,X * Enable OC2 interrupts
CLI
* Enable Interrupts
BRA *
* Interrupt driven; sit here
* Try varying hdly
TOC2 code (6)
***
* SV5OC2 - Output Compare 2 Interrupt Service Routine (ISR)
*
* Called at each OC2 interrupt.
***
SV5OC2 LDD HDLY
* Get delay time for 1/2 cycle
ADDD TOC2,X
* Add HDLY to last compare value
STD TOC2,X
* Update OC2 (schedule next edge)
BCLR TFLG1,X $BF * Clear OC2F
RTI
** Return from OC2 service **
TOC1 Differences
• TOC1 is the same as TOC2..5 in the way we
program the Timer register, interrupts and
Flags.
• TOC1 is different in that it does not use OMx,
OLx to control the output pins.
• i.e. TCNTL2 is used for TOC2..TOC5 only.
TOC1 Output Controls
• TOC1 has much greater flexibility in that it
can control all 5 output pins at once, forcing
any combination of outputs high or low TOC1
• OC1M - Output Compare 1 Mask
• Setting a bit in this mask enables the Data in OC1D
to be forced onto the output pin.
• OC1D - Output Compare 1 Data
• Data to be forced onto pin
TOC1 Output Control Registers
Time Delay using TOC1 (1)
If you base your subroutine, delayms, on
the TOC1 timer, then the time delay should
be independent of other CPU activity as
the TOC timers tick at a uniform rate
unaffected by other CPU activity
The first time you call delayms, you need
to read the value of TCNT, the free
running timer counter, then add the delay
for the number of milliseconds to delay,
write that back to the TOC1 count
register, and wait until the TCNT count
and TOC1 count matches.
At this time TOC1 flag is set
Time Delay using TOC1 (2)
* We want a subroutine to provide accurate
* time delays:
*
* usage example: wait 10ms
startHere
ldd #10
jsr delayms
swi
; # of milliseconds
; delay # of ms
; return to BUFFALO
Time Delay using TOC1 (3)
When the TOC1 count matches TCNT, a flag
is set OC1F.
If your loop waits for the TOC1 flag to be
set then you can stop waiting at this
point. The BRCLR instruction can be used
here. Eg: brclr TFLG1,X #%10000000 *
Branch if bits in mask are clear to *
(branch back to current instruction)
Time Delay using TOC1 (4)
msDelayCount equ
2000
* Toc1 is at $1016
REGBAS equ
$1000
TOC1
equ
$16
TMSK1 equ
$22
* Timer Interrupt Mask 1 Register
* TMSK1 BITS 7
6
5
4
3
2
1
0
*
INTS
OC1I OC2I OC3I OC4I OC5I IC1I IC2I IC3I
TFLG1 equ
$23
*
* TGFLG1 BITS: 7
*
Flags:
IC3F
*
6
5
4
3
2
1
0
OC1F OC2F OC3F OC4F OC5F IC1F IC2F
Time Delay using TOC1 (5)
TCNT equ $0E
delayms
* Save number of ms delay in D - on stack
psha
pshb
* disable TIC & TOC interrupts,
* else this code will not work well at all!
ldx #REGBAS
ldaa #0
staa TMSK1,x
Time Delay using TOC1 (6)
ldd TCNT,x
addd #(msDelayCount-67)
std TOC1,x
* clear the OC1F flag
* BIT 7 in TFLG1 register
bclr TFLG1,x #%01111111
morems
* Branch if (bit TFLG1 = 0) to *
brclr TFLG1,x #%10000000 *
* wait here whilst the TOC1 flag is not set
* when flag is set, drop through to test
* for more ms delays...
Time Delay using TOC1 (7)
*
Get D again
pulb
pula
* Decrement ms delay count
subd #1
* is (D == 0) ?
beq doneDelay
* Yes, then done delaying
* else save D back on stack again, and
delay another ms
psha
pshb
Time Delay using TOC1 (8)
ldd TOC1,x
* add 20000 clocks
addd msDelayCount
std TOC1,x
*
delay another ms
bra morems
doneDelay
rts
Acknowledgments
• Images of the configuration registers, and
some source code examples, are derived
from the Motorola M68HC11 Reference
Manual 11rm.pdf or 11a8td.pdf