You are on page 1of 76

The HCS12/MC9S12 Microcontroller

Chapter 4: Advanced Assembly Programming

The HCS12 Microcontroller

Han-Way Huang
Minnesota State University, Mankato

September 2009

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐1


The HCS12/MC9S12 Microcontroller

Chapter Summery

ƒ The same sequence of instructions often need to be executed


in several places of the program.
ƒ The subroutine mechanism enables the programmer to group the
common instruction sequence into a subroutine.
ƒ A subroutine can be called from many places.
ƒ The processor saves the return address in the stack during a
subroutine call.
ƒ The subroutine restores the return address from the stack before it
returns to the caller.
ƒ The subroutine can receive parameters from the caller to perform
operations and may return result to the caller.
ƒ Top-down
Top do n design with ith hierarchical refinement is
i the
th mostt effective
ff ti
and popular software development methodology.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐2


The HCS12/MC9S12 Microcontroller

Introduction
- Program = data structures + algorithm
- Data structures to be discussed
1. stacks: a last-in-first-out data structure
2. arrays: a set of elements of the same type
3. strings: a sequence of characters terminated by a special character

Stack

Low address Top element SP

Hi h address
High dd B tt
Bottom element
l t

Figure 4.1 Diagram of the HCS12 stack

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐3


The HCS12/MC9S12 Microcontroller

HCS12 Support for the Stack Data Structure


- A 16-bit stack pointer (SP)
- Instructions and addressing mode

Table 4.1 HCS12 push and pull instructions and their


equivalent load and store instructions
Mnemonic Function Equivalent instruction
psha push A into the stack staa 1, -SP
pshb push B into the stack stab 1, -SP
pshc push CCR into the stack none
pshd push D into stack std 2, -SP
pshx push X into the stack stx 2, -SP
pshy
h push h Y into
i t th
the stack
t k sty 2,
2 -SP
SP
pula pull A from the stack ldaa 1, SP+
pulb pull B from the stack ldab 1, SP+
pulc pull CCR from the stack none
puld pull D from the stack ldd 2, SP+
pulx pull X from the stack ldx 2, SP+
puly
l pullll Y from
f the
th stack
t k ldy 2,
2 SP+

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐4


The HCS12/MC9S12 Microcontroller

Example 4.1
4 1 Derive the stack contents after the execution of the following instruction
Sequence:
lds #$15C0
ldaa #$20
psha
ldab #40
pshb
ldx #0
pshx
Solution:

0 SP (= $14FC)
0
$28
$20

Figure 4.2 The contents of the HCS 12 stack

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐5


The HCS12/MC9S12 Microcontroller

What is a Subroutine?
ƒ A sequence of instructions that can be called from many places of the program
ƒ The program flow during a subroutine call is shown in Figure 4.3.
ƒ Saving and restoring return address is the key for the subroutine mechanism
t work.
to k
.
caller .
.
<call> subroutine _x
.
.
.
subroutine _x .
.
.
<return >
Figure 4.3 Program flow during a subroutine call

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐6


The HCS12/MC9S12 Microcontroller

Instructions that Support


pp Subroutine Call
ƒ bsr <sub>: branch subroutine
<sub> is specified in relative addressing mode and is in the range
of -128 to +127 bytes from the instruction immediately after the
bsr <sub> instruction.
instruction The return address is pushed into the stack.
stack
ƒ jsr <sub>: jump subroutine
<sub> is specified in direct, extended, indexed, and indexed indirect
mode. The subroutine being called can be within the range of 64 kB.
The return address is pushed into the stack.
ƒ call <sub>: call subroutine
The <sub> field specifies the page number and the address of the
subroutine within the page to be called.
called The page number is to be
loaded into the PPAGE register.
ƒ rts: return from subroutine
restrieve the return address from the stack and return to the caller.
ƒ rtc: return from
f call
ll
This instruction retrieve the page number and the return address from
the stack.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐7


The HCS12/MC9S12 Microcontroller

Examplep 4.2 Write a subroutine that converts a 16-bit binaryy number into a BCD ASCII
string. The 16-bit number is passed in D and the pointer to the buffer to hold the string
is passed in Y.
Solution:
Let num, ptr, quo, and rem represent the number to be converted pointer, quotient,
and remainder. The procedure is as follows:
Step 1
Push a 0 into the stack. quo ← num.
Step 2
rem ← quo % 10; quo ← quo / 10.
Step 3
Push the sum of $30 and rem into the stack.
Step 4
If (quo == 0) goto Step 5; else goto step 2.
Step 5
Pull a byte from stack and save it in the location pointed to by ptr.
Step 6
ptr ← ptr + 1.
Step 7
If the byte pulled in Step 5 is NULL, stop; else goto Step 5.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐8


The HCS12/MC9S12 Microcontroller

bin2dec pshx
h ; save X iin stack
t k
movb #0,1,-SP ; push NULL character into stack
divloop ldx #10 ; divide the number by 10
idiv ; “
addb #$30 ; convert
con ert the remainder to ASCII code
pshb ; push it into the stack
xgdx ; swap quotient to D
cpd #0 ; if quotient is 0, then prepare to pull out
beq revloop ; the decimal digit characters
bra divloop ; quotient is not 0, continue to perform divide-by-10
revloop pula ; start to reverse the string from stack
staa 1,y+ ; save ASCII string in the buffer
cmpa #0 ; reach the NULL pushed previously?
beq done ; if yes, then done
bra revloop ; continue to pup
done pulx ; restore the index register X
rts

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐9


The HCS12/MC9S12 Microcontroller

Issues related to Subroutine Calls

1. Parameter Passing
• Use CPU registers
g
• Use stack
• Use global memory

2 Result Returning
2.
• Use CPU registers
• Use stack
• Use global memory

3. Local Variable Allocation


• Allocated in the stack
• Use the instruction leas -n,SP to allocate n bytes of space in stack
• Use the instruction leas n, SP to deallocate n bytes from stack

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐10


The HCS12/MC9S12 Microcontroller

Saving
g CPU Registers
g in Stack
ƒ The subroutine may use some CPU registers that were used by its caller.
ƒ The subroutine must save these registers in order to make sure the caller program
can obtain correct result
ƒ The subroutine must restore the saved registers
g before returning
g to the caller.
ƒ The order of register restoration must be reversed to that to which registers are
saved.

if the savingg order is

pshx
pshy
p
pshd

then the restoring order is

ppuld
puly
pulx

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐11


The HCS12/MC9S12 Microcontroller

Stack Frame

- The region in the stack that holds incoming parameters, the subroutine return
address, local variables, and saved registers is referred to as stack frame.
- The stack frame is also called activation record.

SP
Local variables

Saved registers

Return address

Incoming parameters

Figure 4.9 Structure of the 68HC12 stack frame

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐12


The HCS12/MC9S12 Microcontroller

Example 4.3
4 3 Draw the stack frame for the following program segment after the
leas –10,sp instruction is executed:

ldd #$1234
pshd
ldx #$4000
pshx
SP
jsr sub_xyz 10 bytes for local
… variables
sub_xyz pshd
pshx [Y]
pshy $4000
leas -10
10,sp
sp $1234
… return address
Solution: The stack frame is shown $4000
Figure 4.10.
$1234

Figure 4.5 Stack frame of Example 4.3

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐13


The HCS12/MC9S12 Microcontroller

Subroutines with Local Variables


Example 4.4 Write a subroutine that can convert a BCD ASCII string to a binary number
and leave the result in double accumulator D. The ASCII string represents a number in
the range of -215 ~ 215 – 1. A pointer to the string is passed to this subroutine in X.
Solution:
The subroutine will return an error indication using the CY flag of the CCR register.
Let in_ptr, sign, error, and number represent the pointer to the BCD string, sign flag,
error flag, and the number represented by the BCD string.
The algorithm is:
Step 1
sign ← 0; error ← 0; number ← 0.
Step 2
If the character pointed to by in_ptr is the NULL character, then go to step 4.
else if the character is not a BCD digit, then:
error ← 1;
go to step 4;
else
number ← number × 10 + m[in_ptr] - $30;
in_ptr ← in_ptr + 1;
go to step 3;

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐14


The HCS12/MC9S12 Microcontroller

Step 4
St
If sign = 1 and error = 0, then
number ¬ two’s complement of number;
else
stop;
t

This subroutine allows local variables in the stack and its stack is shown in Figure
4.6.

1 dummy SP
pdVal Present digit value
2
4 val The binary value of the BCD string
5 sign Sign of the number
err Error flag
Y
Ret_addr

Figure 4.6 Stack frame of Example 4.4

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐15


The HCS12/MC9S12 Microcontroller

#include "c:\miniide\hcs12.inc"
minus equ $2D ; ASCII code of minus sign
dummy equ 0 ; offset of dummy to hold a 0
pdVal equ 1 ; offset of present digit value from SP in stack
val equ
q 2 ; offset of the 2-byte
y binary y value of the BCD string
g
; from SP in stack
sign equ 4 ; offset of the sign from SP in stack
err equ 5 ; offset of error flag from SP in stack
locVar equ
q 6
org $1000
StrBuf dc.b "-9889",0 ; input ASCII to be converted
result ds.w 1
org $1500
start lds #$1500
ldx #StrBuf
jsr bcd2bin
std result
swi
; -----------------------------------------------------------------------------------------------------------
; This subroutine converts a BCD string into its equivalent binary value and also uses the
; CY flag to indicate error condition. The CY flag is set to 1 to indicate error.
; ------------------------------------------------------------------------------------------------------------

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐16


The HCS12/MC9S12 Microcontroller

bcd2bin pshy
leas -locVar,SP ; allocate 4 bytes for local variables
movw #0,val,SP ; initialize accumulated value to 0
movb #0,dummy,SP
movb #0,sign,SP ; initialize sign to positive
movb #0,err,SP ; clear error flag initially
ldaa 0,x ; check the first character
cmpa #minus ; is the first character a minus sign?
bne GEZero ; branch if not minus
movb #1,sign,SP ; set the sign to 1
inx ; move the pointer
GEZero ldab 1,x+ ; is the current character a NULL character?
lbeq done ; yes, we reach the end of the string
cmpbb #$30
$ ; is
i the
h character
h not between
b 0 to 9?
blo inErr ;"
cmpb #$39 ;"
bhi inErr ;"
subb
bb #$30 ; convert to theh BCDC digit
di i value
l
stab pdVal,SP ; save the current digit value
ldd val,SP ; get the accumulated value
ldy #10
emull ; perform
f 16
16-bit
bi by
b 16-bit
16 bi multiplication
l i li i

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐17


The HCS12/MC9S12 Microcontroller

addd dummy,SP ; add the current digit value


std val SP
val,SP ; save the sum
bra GEZero
inErr movb #1,err,SP ; set the error flag to indicate error
bra chkout
done ldaa sign SP
sign,SP ; check to see if the original number is negative
beq chkout
ldd #$FFFF ; convert to two's complement format
subd val,SP ; if the number is negative
addd #1 ;"
std val,SP ;"
chkout ldaa err,SP ; check the error flag
beq clrErr ; go to clear CY flag before return
sec ; clear the C flag
bra dealloc
clrErr clc ; set the C flag
dealloc ldd val,SP
leas locVar SP
locVar,SP ; deallocate local variables
puly ; restore Y
rts
; org $FFFE ; uncomment these two lines for CodeWarrior
; dc w
dc.w start ;“
end

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐18


The HCS12/MC9S12 Microcontroller

Bubble Sort
ƒ Sorting is useful for improving the searching speed when an array or a file needs to be
searched many times.
ƒ Bubble sort is a simple but inefficient sorting method.

Example 4.13 Write a subroutine to implement the bubble sort algorithm and a sequence
of instructions for testing the subroutine.
Solution: The algorithm of bubble sort is shown in Figure 4.7.
The bubble sort subroutine uses the following local variables:

Buf: a buffer for swapping elements


InOrder: a flag indicating whether the array is in order
Inner: no of comparisons remained to be performed in the current iteration
Iteration: number of iterations remained to be performed

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐19


The HCS12/MC9S12 Microcontroller
S ta rt

ite ra tio n ⎯ N -1

in _o rd e r ⎯ 1
in n e r ⎯ ite ra tio n
i⎯ 0

no
a rra y [i] > array [i+ 1 ]?

yes
sw a p a rray [i] & a rra y [i+ 1 ]
in _o rd e r ⎯ 0

in n e r ⎯ inn e r - 1
i ⎯ i + 1

no
in n e r = 0 ?

y es
yes
in _o rd e r = 1 ?

no
I te ratio n ⎯ ite ratio n - 1

no
ite ra tio n = 0 ?
yes
S to p

F ig u re 4 .7 L o g ic flo w o f b u b ble so rt

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐20


The HCS12/MC9S12 Microcontroller

S
Stack Frame ffor bubble S
Sort

iteration SP
SP+1 inner
SP+2 inOrder
SP+3 buf
X
Y
A
B
return
t address
dd
SP+12 N
SP+13 arrayX

Figure 4.8 Stack frame for bubble sort

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐21


The HCS12/MC9S12 Microcontroller

arr equ 13 ; distance of the variable arrayX from stack top


arcnt equ 12 ; distance of the variable arcnt from stack top
buf equ 3 ; distance of local variable buf from stack top
inOrder equ 2 ; distance of local variable inOrder from stack top
inner equ 1 ; distance of local variable inner from stack top
i
iteration
i equ 0 ; distance
di off local
l l variable
i bl iteration
i i from
f stackk top
true equ 1
false equ 0
n equ 30 ; array count
l l
local equ 4 ; number
b off bytes
b usedd by
b local
l l variables
i bl
org $1000 ; test data
arrayX dc.b 3,29,10,98,54,9,100,104,200,92,87,48,27,22,71
dc.b 1,62,67,83,89,101,190,187,167,134,121,20,31,34,54
org $1500
start lds #$1500 ; initialize stack pointer
ldx #arrayX
pshx
ld
ldaa #
#n
psha
jsr bubble
leas 3,sp ; deallocate space used by outgoing parameters
; b
bra $ ; uncomment this
hi instruction
i i under
d CodeWarrior
C d W i
swi ; break to D-Bug12 monitor

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐22


The HCS12/MC9S12 Microcontroller

bubble pshd
pshy
h
pshx
leas -local,sp ; allocate space for local variables
ldaa arcnt,sp ; compute the number of iterations to be performed
d
deca ; "
staa iteration,sp; "
ploop ldaa #true ; set array inOrder flag to true before any iteration
staa inOrder,sp ; "
ld
ldx arr,sp ; use index
i d register
i t X as the
th array pointer
i t
ldaa iteration,sp; initialize inner loop count for each iteration
staa inner,sp ; "
cloop ldaa 0,x ; compare two adjacent elements
cmpa 1
1,x ; "
bls looptst
; the following five instructions swap the two adjacent elements
staa buf,sp ; swap two adjacent elements
ld
ldaa 1
1,x ; "
staa 0,x ; "
ldaa buf,sp ; "
staa 1,x ; "
ldaa #false ; reset the inOrder flag
staa inOrder,sp ; "

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐23


The HCS12/MC9S12 Microcontroller

looptst inx
d
dec i
inner,sp
bne cloop
tst inOrder,sp ; test array inOrder flag after each iteration
bne done
d
dec it ti
iteration,sp
bne ploop
; the following instruction deallocates local variables
done leas local,sp ; de-allocate local variables
pulxl
puly
puld
rts
; org $FFFE ; uncommentt this
thi line
li for
f CodeWarrior
C d W i
; dc.w start ; uncomment this line for CodeWarrior
end

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐24


The HCS12/MC9S12 Microcontroller

BinaryySSearch S Subroutine
ƒ Divide the array into three parts: upper half, middle element, and
lower half.
ƒ Let min, man, mean be the minimum, maximum, and middle indices
of the subarray to be searched.
searched
ƒ The algorithm of binary search is as follows:

Step 1
min <-
< 0; max = n – 1;
Step 2
If (max < min), stop.
Step 3
Mean <-< (min + max)/2
Step 4
If (key == arr[mean]), then key is found and exit.
Step 5
If (key < arr[mean])
arr[mean]), then set max to mean – 1 and go to Step 2.
2
Step 6
if (key < arr[mean]), then set min to mean + 1 and go to Step 2.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐25


The HCS12/MC9S12 Microcontroller

mean SP
min SP+1
max SP+2
X
B
ret_address
key SP+8
arrCnt SP+9
arrBase SP+10

Figure 4.9 Stack frame for binary search

n equ 30 ; array count


srch equ 69 ; key to be searched
mean equ 0 ; stack offset for local variable mean
min equ 1 ; stack offset for local variable min
max equ 2 ; stack offset for local variable max
key equ 8 ; stack offset for local variable key
arrCnt equ 9 ; stack offset for local variable arrCnt
arrBas equ 10 ; stack offset for local variable arrBas
locvar equ 3 ; number of bytes for local variables
org $1000
result ds.b 1 ; search result

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐26


The HCS12/MC9S12 Microcontroller

org $1500
lds #$1500
movw #arr,2,-SP ; pass array base address
movb #n,1,-SP ; pass array count
movb #srch,1,-SP ; pass key for search
jsr binsearch
leas 4,SP ; de-allocate space used in passing parameters
staa result
; bra $ ; uncomment this instruction for CodeWarrior
swi

binSearch pshx ; save X in the stack


pshb ; save B in the stack
leas -locVar,SP ; allocate space for locVar variables
movb #0,min,SP ; initialize min to 0
ldaa arrCnt,SP ; initialize max to arCnt - 1
deca ;"
staa max,SP ;"
ldx arrBas,SP ; use X as the pointer to the array
loop ldab min,SP ; is search over yet?
cmpb max,SP ;"
lbhi notfound ; if min > max, then not found (unsigned comparison)

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐27


The HCS12/MC9S12 Microcontroller

addb max,SP ; compute mean


lsrb ; "
stab mean,SP ; save mean
ldaa b,x ; get a copy of the element arr[mean]
cmpa key,SP ; compare key with array[mean]
beq found ; found it?
bhi searchLO ; continue to search in lower half
ldaa mean,SP ; prepare to search in upper half
inca ; "
staa min,SP ; "
bra loop
searchLO ldaa mean,SP ; set up indices range for searching in the
deca ; lower half
staa max,SP ; "
bra loop
found ldaa #1
bra exit
notfound ldaa #0
exit leas locVar,SP
pulb
pulx
rts

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐28


The HCS12/MC9S12 Microcontroller

arr db 1,3,6,9,11,20,30,45,48,60
db 61,63,64,65,67,69,72,74,76,79
db 80,83,85,88,90,110,113,114,120,123
; org $FFFE ; uncomment this line for CodeWarrior
; dc.w start ; uncomment this line for CodeWarrior
end

Subroutine that perform 32-bit division

msb lsb
R register Q register
C 32-bit 32-bit set lsb
shift left
write R

Controller
ALU

P register
32 bit
32-bit
Figure 4.10 Conceptual hardware for implementing the repeated subtraction method

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐29


The HCS12/MC9S12 Microcontroller

Algorithm for Multi-byte Division


Step 1
icnt Å n; R Å 0; Q Å dividend; P Å divisor.
Step 2
Shift the register pair (R, Q) one bit to the left.
Step 3
Subtract P from R, put the result back to R if the result is nonnegative.
Step 4
If the result of Step 2 is negative, then set the lsb of Q to 0. Otherwise, set the lsb to 1.
Step 5
icnt Å icnt – 1.
Step 6
If (icnt == 0) then stop; else go to Step 2

Example 4.7 Write a subroutine to implement the division algorithm using the repeated
subtraction method for a 32-bit unsigned dividend and divisor. The caller of the
subroutine allocate space in the stack for this subroutine to return the quotient and
remainder and then push the dividend and divisor into the stack before calling this
subroutine.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐30


The HCS12/MC9S12 Microcontroller

SP
buf
SP+4 i
SP+5 R
SP+9 Q
[y]
[[x]]
[D]
return address
SP+21 divisor
SP+25 dividend
SP+29 quotient
SP+33 remainder

Figure 4.11 Stack frame for Example 4.7

buff
b equ
eq 0 ; distance of buf
b f from the top of the stack
i equ 4 ; distance of i from the top of the stack
R equ 5 ; distance of R from the top of the stack
Q equ 9 ; distance of Q from the top of the stack
divisor equ 21 ; distance of divisor from the top of the stack
dividend equ 25 ; distance of dividend from the top of the stack
quo equ 29 ; distance of quo from the top of the stack
rem equ 33 ; distance of rem from the top of the stack
locVar equ 13 ; number of bytes for local variables

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐31


The HCS12/MC9S12 Microcontroller

dvdendHI equ $42 ; dividend to be tested


dvdendLO equ $4c15 ; "
dvsorHI equ $0 ; divisor to be tested
dvsorLO equ $64 ; "
org $1000
quotient ds.b 4 ; memory locations to hold the quo
remain ds.b 4 ; memory locations to hold the remainder
org $1500 ; starting address of the program
start lds #$1500 ; initialize stack pointer
leas -8,SP ; make a hole of 8 bytes to hold the result
ldd #dvdendLO
pshd
ldd #dvdendHI
pshd
ldd #dvsorLO
pshd
ldd #dvsorHI
pshd
jsr div32 ; call the divide subroutine
leas 8,SP ; de-allocate space used by dividend & divisor
movw 2,sp+,quotient ; pull upper half of quotient
movw 2,sp+,quotient+2 ; pull lower half of quotient

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐32


The HCS12/MC9S12 Microcontroller

movw 2,sp+, quotient ; pull upper half of the quotient from the stack
movw 2 sp+ quotient+2 ; pull lower half of the quotient from the stack
2,sp+,
bra $
div32 pshd
pshx
pshy
leas -locVar,sp ; allocate space for local variables
ldd #0
std R,sp ; initialize R to 0
std R+2 sp
R+2,sp ; “
ldd dividend,sp ; place dividend in register Q
std Q,sp
ldd dividend+2,sp
std Q+2 sp
Q+2,sp
movb #32,i,sp ; initialize loop count
dloop lsl Q+3,sp ; shift (R,Q) to the left by 1 bit
rol Q+2,sp ; “
rol Q+1 sp
Q+1,sp ; “
rol Q,sp ; “
rol R+3,sp ; “
rol R+2,sp ; “
rol R+1 sp
R+1,sp ; “
rol R,sp ; “

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐33


The HCS12/MC9S12 Microcontroller

ldd R+2,sp
subd divisor+2,sp
std buf+2,sp
ldaa R+1,sp
sbca divisor+1,sp
staa buf+1,sp
ldaa R,sp
sbca divisor,sp
bcs smaller
; the following six instructions store the difference back to R register
staa R,sp
ldaa buf+1,sp
staa R+1,sp
ldd buf+2,sp
std R+2,sp
bset Q+3,sp,$01 ; set the least significant bit of Q register to 1
bra looptest
smaller bclr Q+3,sp,$01 ; set the least significant bit of Q register to 0
looptest dec i,sp
lbne loop
; the following four instructions copy the remainder into the hole in the stack
ldd R,sp
std rem,sp

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐34


The HCS12/MC9S12 Microcontroller

ldd R+2,sp
std rem+2,sp
; the following four instructions copy the quotient into the hole in the stack
ldd Q,sp
std quo,sp
ldd Q+2,sp
std quo+2,sp
leas locVar,sp ; deallocate local variables
puly
pulx
puld
rts
; org $FFFE ; uncomment this line for CodeWarrior
; dc.w start ; uncomment this line for CodeWarrior
end

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐35


The HCS12/MC9S12 Microcontroller

Finding
g the Square
q Root
The successive approximation method can be used to find the square root of an integer.

Step 1
sar Å 0; mask
sa as Å $8000; lpcnt
pc Å 16; e p Å 0.
6; temp
Step 2
temp Å sar OR mask
Step 3
If ((
((temp p) ≤ num))
p * temp)
sar ← temp;
Step 4
mask Å mask >> 1 (shift right one bit)
Stepp5
lpcnt Å lpcnt – 1
Step 6
If (lpcnt == 0) then stop; else go to Step 2.

Example 4.8 Write a subroutine that implements the successive approximation method
to find the square root of a 32-bit integer.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐36


The HCS12/MC9S12 Microcontroller

m ask SP

sar SP+2

tem p SP+4

lpcnt SP+6

y
x
return address
q_hi SP+13

q _lo SP+15

Figure 4.13 Stack fram e of Exam ple 4.8

#include "c:\miniide\hcs12.inc"
mask equ 0 ; stack offset of the variable mask from SP
sar equ 2 ; stackk offset
ff off the
h variable
i bl sar from
f SP
S
temp equ 4 ; stack offset of the variable temp from SP
lpcnt equ 6 ; stack offset of one-byte loop count from SP
q_hi equ 13 ; stack offset of the upper and lower halves of the
q_lo
l equ 15 ; number
b Q we want to fi find
d the
h square root ffrom SP
locVar equ 7
testHi equ $00 ; upper half of the test number (q)
testLo equ $7BC4 ; lower half of the test number (q)
org $1000
sqroot ds.w 1 ; square root

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐37


The HCS12/MC9S12 Microcontroller

org $1500
start lds #$1500
movw #testLo,2,-SP ; push testHi into stack
movw #testHi,2,-SP ; push testLo into stack
jsr findsqr
std sqroot ; save the returned square root
leas 4,SP ; de-allocate the space used in passing parameters
; bra $ ; uncomment this line for CodeWarrior
swi
; ------------------------------------------------------------------------------------------------------
findsqr pshx
pshy
leas -locVar,SP ; allocate space for local variables
movw #0,sar,SP ; initialize SAR to 0
movw #$8000,mask,SP ; initialize mask to $8000
movb #16,lpcnt,SP ; initialize loop count to 16
iloop ldd mask,SP ; get the mask
oraa sar,SP ; set a bit in SAR to 1
orab sar+1,SP ; "
std temp,SP ; save a copy of your guess
tfr D,Y ; compute sar * sar
emul ; "

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐38


The HCS12/MC9S12 Microcontroller

cpy q_hi,SP ; is our guess correct?


bhi nextb ;"
cpd q_lo,SP ;"
bhi nextb ;"
ldd temp,SP ; yes, our guess is correct
std sar,SP ; so, transfer temp to SAR
nextb lsr mask,SP ; shift mask to the right one place
ror mask+1,SP ;"
dec lpcnt,SP
bne iloop
ldd sar,SP ; put sar in D as the approximated square root
leas locVar,SP ; de-allocate local variables
puly
pulx
rts
; org $FFFE ; uncomment this line for CodeWarrior
; dc.w start ; uncomment this line for CodeWarrior
end

The square root computed using this method tends to be smaller than the actual square
root and hence may not be the closet approximation and the user should compare (sar + 1)
and sar to find the closest approximation.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐39


The HCS12/MC9S12 Microcontroller

Subroutine for Prime Testing


g
ƒ The most efficient method for testing whether an integer is a prime is to divide the
given number by all the prime numbers from 2 to the square root of the given number.
ƒ Since the prime numbers from 2 to the square root of the given number are not
available,, we can test divide the given
g number by
y all the numbers from 2 to its square
q
root.

Example 4.9 Write a subroutine that can test whether an unsigned integer is a prime
number.
Solution:
test_hi equ $0638 ; number to be tested for prime
test_lo equ $F227 ; "
orgg $1000
isprime ds.b 1
org $1500
start lds #$1500 ; set up stack pointer
movw #test_lo,2,-SP
, , ; push
p the lower half of the test number
movw #test_hi,2,-SP ; push the upper half of the test number
jsr PrimeTest
staa isprime
; bra $ ; uncomment this line for CodeWarrior
swi

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐40


The HCS12/MC9S12 Microcontroller

ii equ 0 ; stack offset from SP of loop index


tli it
tlimit equ 2 ; stack
t k offset
ff t from
f SP off ttestt limit
li it
pNumHi equ 10 ; stack offset from SP of upper half of test number
pNumLo equ 12 ; stack offset from SP of lower half of test number
pLocal equ 4 ; number of bytes used by local variables
primeTest
i T t pshx
h
pshy
leas -pLocal,SP ; allocate space for local variables
ldaa pNumLo+1,SP ; check if the number is even (if bit 0 is 0)
anda
d #$01 ; "
beq nonPRI ; "
ldd pNumHi,SP
cpd #0
b
bne t tPR
testPR ; upper half
h lf nonzero, then
th entert normall test
t t
ldd pNumLo,SP ; if upper half is 0, then test lower half
cpd #0 ; is lower half equal to 0?
beq nonPri ; 0 is not a prime
cpd #1 ; is lo
lower
er half eq
equal
al to 1
beq nonPri ; 1 is not a prime
testPR ldd pNumLo,SP ; find the square root of Num
ldx pNumHi,SP ; “
pshd ; “
pshx ; “

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐41


The HCS12/MC9S12 Microcontroller

jsr findsqr ;“
l
leas 4 SP
4,SP ; de-allocate
d ll t space for f passing
i parameters
t
std tlimit,SP ; save returned value as the prime test limit
movw #2,ii,SP ; initialize test divide number to 3
divLoop ldd ii,SP
cpdd tli it SP ; has
tlimit,SP h test
t t divided
di id d all
ll numbers
b up to t tlimit?
tli it?
bhi isPRI ; the number is prime
ldd pNumLo,SP; divide Num by ii
ldx pNumHi,SP ; “
ld
ldy ii SP
ii,SP ;“
leas -8,SP ;“
pshd ; “ (push pNumLo)
pshx ; “ (push pNumHi)
pshy
h ; “ (push
( h ii)
movw #0,2,-SP ; “ (push 0 to the stack)
jsr div32 ; “ (call the divide subroutine)
leas 14,SP ; de-allocate the space used by outgoing parameters
p ld
puld ; get the lower
lo er two
t o bytes
b tes of the remainder
cpd #0 ; is remainder equal to 0?
beq nonPRI ; If remainder equals 0, then Num is not a prime
ldd ii,SP ; test divide the next higher integer
addd #1 ;“
std ii,SP ;“

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐42


The HCS12/MC9S12 Microcontroller

bra divLoop
isPRI ldaa #1
bra exitPT
nonPRI ldaa #0
exitPT leas pLocal,SP
puly
pulx
rts
#include "c:\miniide\findsqr.asm"
#include "c:\miniide\div32.asm"
; org $FFFE ; uncomment this line for CodeWarrior
; dc.w start ; uncomment this line for CodeWarrior
end

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐43


The HCS12/MC9S12 Microcontroller

Using the D-Bug12


D Bug12 Functions to Perform I/O Operations

Table 4.2 D-Bug12 monitor (version 4.x.x) routines


pointer
Subroutine Function
address
dd
far main ( ) Start of D -Bug12 $EE80
getchar ( ) Get a character from SCI 0 or SCI1 $EE84
putchar ( ) Send a character out to SCI 0 or SCI1 $EE86
printf ( ) Formatted string output -translates binary values to string $EE88
far GetCmdLine ( ) Get a line of input from the user $EE8A
far sscanhex ( ) Convert ASCII hex string to a binary integer $EE8E
isxdigit ( ) Check if a character (in B ) is a hex digit $EE92
toupper ( ) Convert lowercase characters to uppercase $EE94
isalpha ( ) Check if a character is alphabetic $EE96
strlen ( ) g of a NULL -terminated string
Returns the length g $EE98
$
strcpy ( ) Copy a NULL-terminated string $EE9A
far out 2hex ( ) Output 8-bit number as two ASCII hex characters $EE9C
far out 4hex ( ) Output a 16-bit number as four ASCII hex characters $EEA0
SetUserVector ( ) Set up a vector to a user 's interrupt service routine $EEA4
far WriteEEByte ( ) Write a byte to the on -chip EEPROM memory $EEA6
f EraseEE
far E EE ( ) B lk erase th
Bulk the on -chip
hi EEPROM memory $EEAA
far ReadMem ( ) Read data from the HCS 12 memory map $EEAE
far WriteMem ( ) Write data to the HCS 12 memory map $EEB 2

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐44


The HCS12/MC9S12 Microcontroller

- All functions listed in Table 4.2


4 2 are written in C language.
language
- The first parameter to the function is passed in accumulator D. The remaining
parameters are pushed onto the stack in the reverse order they are listed in the
function declaration.
- Parameters of type char will occupy the lower order byte of a word pushed onto the
stack.
- Parameters pushed onto the stack before the function is called remain on the stack
when
h the
h ffunction
i returns. It is
i the
h responsibility
ibili off the
h caller
ll to remove passedd
parameters from the stack.
- All 8- and 16-bit values are returned in accumulator D. A returned value of type char is
returned in accumulator B.

int getchar (void)


Pointer address: $EE84
Returned value: 8-bit character in accumulator B

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐45


The HCS12/MC9S12 Microcontroller

Adding the following instruction sequence will read a character from SCI0 port:

getchar equ $EE84



jsr [getchar,PCR]

int putchar(int)
Pointer address: $EE86
Incoming parameter: character to be output in accumulator B
Returnedd vale:
l the
h character
h that
h was sent (in
(i B))

- This function outputs a character to serial communication port SCI0.


- The character to be output should be placed in accumulator B.
- The
h following
f ll i instruction
i i sequence will ill output the
h character
h A to serial
i l port SCI0
SC 0 when
h
the program is running on the Dragon12 demo board.

putchar equ $EE86



ldab #$41 ; place the ASCII code of A in accumulator B
jsr [putchar,PCR]

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐46


The HCS12/MC9S12 Microcontroller

int p
printf(char
( *format,…)
, )
Pointer address: $EE88
Incoming parameters: zero or more integer data to be output on the stack, D contains the
address of the format string. The format string must be terminated
with a zero.
Returned value: number of characters printed in D.

- This function is used to convert, format, and print its argument as standard output under
the control of the format stringg pointed
p to byy fformat.
- All except floating-point data types are supported.
- The format string contains two basic types of objects:

1. ASCII characters which will be copied


p directly y to the display
p y device.
2. Conversion specifications. Each conversion specification begins with a percent sign
(%).
3. Optional formatting characters may appear between the percent sign and ends with a
single
g conversion character in the followingg order:

[-][<FieldWidth>][.][<Precision>][h | l]

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐47


The HCS12/MC9S12 Microcontroller

The Meaning of Optional Characters

Table 4 3 Optional formatting characters


Table 4.3 Optional formatting characters
Character Description
‐(minus sign) Left justifies the converted argument.
FieldWidth Integer number that specifies the minimum field width for the converted 
arguemnt. The argument will be displayed in a field at least this wide . 
The displayed argument will be padded on the left or right if necessary.
. (period) Separates the field width from the precision.
Precision Integer number that specifies the maximum number of characters to 
di l f
display from a string or the minimum number of digits for an intger. 
i h i i b f di i f i
h To have an integer displayed as a short .
l(letter ell) To have an integer displayed as a long .

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐48


The HCS12/MC9S12 Microcontroller

Formattingg Characters Supported


pp by
y the pprintf()
f() ffunction:

Tab le 4.4 Prin tf() con v ersion characters


character A rg umen t type; d isplayed as
d, i int; sig ned d ecimal nu mb er
o int; u nsig n ed o ctal n u mb er(w ith ou t a leadin g zero)
x int; u nsig n ed h ex numb er u sing ab cdef for 1 0...15
X int; u nsig n ed h ex numb er u sing A B C D EF for 1 0...15
u int; u nsig n ed d ecimal n umber
c int; sin gle character
s ch ar *; d isp lay fro m the strin g u n til a '\0 ' (N U LL)
p vo id * ; p ointer (imp lementation- depend en t represen tatio n)
% no arg umen t is con verted; p rint a %

Example
E l for
f outputting
t tti a message (Flight
(Fli ht simulation):
i l ti )
CR equ $0D
LF equ $0A
printf equ $EE88

ldd #prompt
jsr [printf,PCR]

prompt db “Flight simulation”,CR,LF,0

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐49


The HCS12/MC9S12 Microcontroller

Example for outputting three numbers m, n, and gcd along with a message:

CR equ $0D
LF equ $0A
printf equ $F686

ldd gcd
pshd
ldd n
pshd
ldd m
pshd
ldd #prompt
jsr [printf,PCR]
leas 6,sp

prompt db “The greatest common divisor of %d and %d is %d”,CR,LF,0

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐50


The HCS12/MC9S12 Microcontroller

int far GetCmdLine(char *CmdLineStr


CmdLineStr, int CmdLineLen)
Pointer address: $EE8A
Incoming parameters: a pointer to the buffer where the input string is to be stored and
the maximum number of characters that will be accepted by this
function.
function

- This function is used to obtain a line of input from the user.


- The reception of an ASCII carriage return ($0D) terminates the reception of characters
from the user.
user
- The caller of this function normally would output a message so that the user knows to
enter a message. The example in the next page illustrates this interaction.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐51


The HCS12/MC9S12 Microcontroller

printf equ $EE88


GetCmdLine equ $EE8A
cmdlinelen equ 100
CR equ $0D
LF equ $0A

prompt db “Please enter a string: “,CR,LF,0

inbuf ds b
ds.b 100

ldd #prompt ; output a prompt to remind the user to
jsr [printf,PCR] ; enter a string
ldd #cmdlinelen ; push the CmdLineLen
pshd ; “
ldd #inbuf
call [GetCmdLine,PCR] ; read a string from the keyboard
puld ; clean up the stack

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐52


The HCS12/MC9S12 Microcontroller

Example 4.15
4 15 Write a program that invokes appropriate functions to find the prime number
between 1000 and 2000. Output eight prime numbers in one line. To do this, you will need to

1.-- write a subroutine to test if an integer is a prime.


2
2.-- invoke the printf() function to output the prime number.
number
3.-- write a loop to test all the integers between 1000 and 2000.

Solution: The logic structure of the program is

Step 1
Output the message “The prime numbers between 1000 and 2000 are as follows:”.
Step 2
For every number between 100 and 1000 do

1. - call the test_prime() function to see if it is a prime.


2. - output the number (call printf()) if it is a prime.
3 - if there are already eight prime numbers in the current line,
3. line then also output a carriage
return.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐53


The HCS12/MC9S12 Microcontroller

The algorithm of the test_prime()


St 1
Step
Let num, i, and isprime represent the number to be tested, the loop index, and the flag to
indicate if num is prime.
Step 2
i i ← 0;
isprime 0
Step 3
For i = 2 to num/2 do
if num % i = 0 then
return;
t
isprime ← 1;
return;

Th St
The Stackk frame
f off the
th function
f ti test_prime
t t i ():
()
SP
i
SP + 2
ilimit
SP + 4
prime_flag
[X]
return address
SP + 9
num

Figure 4.18 Stack frame for the prime test subroutine

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐54


The HCS12/MC9S12 Microcontroller

CR equ $0D
LF equ $0A
upper equ 2000 ; upper limit for testing prime
lower equ 1000 ; lower limit for testing prime
printf equ $EE88 ; location where the address of printf() is stored
org $1000
out_buf ds.b 10
PRIcnt ds.b 1 ; prime number count
k ds.b 2
tmp ds.b 2
org $1500
start ldx #upper
stx tmp
pshx
ldx #lower
stx k ; initialize k to 1000 for prime testing
pshx
ldd #form0
jsr [printf,PCR]
leas 4,sp
clr PRIcnt
again ldd k
cpd #upper

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐55


The HCS12/MC9S12 Microcontroller

bhi Pstop ; stop when k is greater than upper


pshd
ldd #0
pshd
jsr primetest ; test if k is prime
leas 4,sp ; de-allocate space used by outgoing parameters
tsta
beq next_k ; test next integer if k is not prime
inc PRIcnt ; increment the prime count
ldd k
pshd
ldd #form1
jsr [printf,PCR] ; output k
leas 2,sp
ldaa PRIcnt
cmpa #8 ; are there eight prime numbers in the current line?
blo next_k
; output a CR, LF if there are already eight prime numbers in the current line
ldd #form2
jsr [printf,PCR]
clr PRIcnt
next_k ldx k

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐56


The HCS12/MC9S12 Microcontroller

inx
stx k
lbra again
; Pstop bra $ ; uncomment this line for CodeWarrior
Pstop swi ; comment this line for CodeWarrior
#include "c:\miniide\primetest.asm"
#include "c:\miniide\div32.asm"
#include "c:\miniide\findsqr.asm"
form0 db CR,LF,"The prime numbers between %d and %d are as follows: "
db CR,LF,CR,LF,0
form1 db " %d ",0
form2 db " ",CR,LF,0
; org $FFFE ; uncomment this line for CodeWarrior
; dc.w start ; uncomment this line for CodeWarrior
end

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐57


The HCS12/MC9S12 Microcontroller

Program Execution Result

>g 1500
The prime numbers between 1000 and 2000 are as follows:
1009 1013 1019 1021 1031 1033 1039 1049
1051 1061 1063 1069 1087 1091 1093 1097
1103 1109 1117 1123 1129 1151 1153 1163
1171 1181 1187 1193 1201 1213 1217 1223
1229 1231 1237 1249 1259 1277 1279 1283
1289 1291 1297 1301 1303 1307 1319 1321
1327 1361 1367 1373 1381 1399 1409 1423
1427 1429 1433 1439 1447 1451 1453 1459
1471 1481 1483 1487 1489 1493 1499 1511
1523 1531 1543 1549 1553 1559 1567 1571
1579 1583 1597 1601 1607 1609 1613 1619
1621 1627 1637 1657 1663 1667 1669 1693
1697 1699 1709 1721 1723 1733 1741 1747
1753 1759 1777 1783 1787 1789 1801 1811
1823 1831 1847 1861 1867 1871 1873 1877
1879 1889 1901 1907 1913 1931 1933 1949
1951 1973 1979 1987 1993 1997 1999 User Bkpt Encountered
PP PC SP X Y D = A:B CCR = SXHI NZVC
30 1560 1500 07D1 15DE 07:D1 1001 0000
xx:1560 34 PSHX
>

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐58


The HCS12/MC9S12 Microcontroller

Subroutines for Creating


g Time Delays
y
Example 4.11 Write a subroutine that can create a time delay of 100 ms.
Solution:
Delay100mspshx
ldx #60000 ; 2 E cycles
iloop psha ; 2 E cycles
pula ; 3 E cycles
psha ; 2 E cycles
pula ; 3 E cycles
psha ; 2 E cycles
pula ; 3 E cycles
psha ; 2 E cycles
pula ; 3 E cycles
psha ; 2 E cycles
pulal ; 3 E cycles
l
psha ; 2 E cycles
pula ; 3 E cycles
psha ; 2 E cycles
pula
p ; 3 E cycles
y
nop ; 1 E cycle
nop ; 1 E cycle
dbne x,iloop
pulx
rts

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐59


The HCS12/MC9S12 Microcontroller

The previous subroutine can be modified to create a time delay that is a multiple of
100 ms as follows (the multiple is passed in Y):

delayby100ms pshx
eloop3 ldx #60000 ; 2 E cycles
il
iloop3
3 psha
h ; 2 E cycles
l
pula ; 3 E cycles
psha ; 2 E cycles
pula ; 3 E cycles
psha
p ; 2 E cycles
y
pula ; 3 E cycles
psha ; 2 E cycles
pula ; 3 E cycles
psha ; 2 E cycles
pula ; 3 E cycles
psha ; 2 E cycles
pula ; 3 E cycles
psha ; 2 E cycles
pula ; 3 E cycles
nop ; 1 E cycle
nop ; 1 E cycle
dbne x,iloop3 ; 3 E cycles
dbne y,eloop3 ; 3 E cycles
pulx
rts

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐60


The HCS12/MC9S12 Microcontroller

Introduction to Parallel I/O Port and Simple


p I/O Devices
ƒ A HCS12 device may have from 48 to 144 pins arranged in 3 to 12 I/O Ports.
ƒ An I/O port consists of a set of I/O pins and the registers required to control its operation.
ƒ An I/O pin can be configured for input or output.
ƒ An I/O
/O pin
p usually
usua y serves
se ves multiple
u p e functions.
u c o s. When
W e it iss noto used as a peripheral
pe p e a function,
u c o ,
it can be used as a general-purpose I/O pin.

Addressing the I/O Port Data Register


ƒ When inputting
p g or outputting
p g data from or to an I/O port,
p , the user read from or write to
the port data register.
ƒ Each I/O port register is assigned to an address in the HCS12 memory space. For example,
Port A data register is assigned to address 0, the next instruction output $35 to Port A:

movb #$35,0 ; address 0 is Port A data register

ƒ A name is also assigned to each register so that we can access a register by referring to
its name:
PTA equ 0
movb #$35,PTA ; output $35 to Port A

The name and address association is established byy including


g the HCS12.inc file to your
y
program using the “#include c:\...\hcs12.inc” statement.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐61


The HCS12/MC9S12 Microcontroller

Configuring
g g I/O Pin Direction
ƒ Each I/O port has a data direction register DDRx (x is the port name) that configures
the direction of each pin.
ƒ By setting a bit of the DDRx register to 1, the corresponding I/O pin is configured for
ou pu .
output.
ƒ By setting a bit of the DDRx register to 0, the corresponding I/O pin is configured for
input.

movb #$FF,DDRB
$ , ; configure
g Port A for output
p
movb #0,DDRB ; configure Port B for input
movb #$AA,DDRB ; configured Port A odd pins for output,
even pins for input

Input and Output Operations


movb #$FF,DDRB ; configure Port B for output
staa PTB ; output the contents of A to port B
movb #$67,PTB
$ , ; output
p the value $67
$ to Port B

movb #0,DDRC ; configure Port C for input


movb PTC,ibuf ; read the contents of Port C and save it at the memory
; location represented
p byy ibuf

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐62


The HCS12/MC9S12 Microcontroller

The HCS12 I/O ports and Pin Names


Table 4.5 N um ber of pins available in each paralle port
Port Nam e No. of Pins Pin Nam e
A 8 PA7~PA0
B 8 PB7~PB0
PB7 PB0
E 8 PE7~PE0
H 8 PH7~PH0
J 4 PJ7~PJ0
K 7 PK4~PK0
M 8 PM 7~PM0
P 8 PP7~PP0
PP7 PP0
S 8 PS3~PS0
T 8 PT7~PT0
PAD1, PAD0 16 PAD 15~PAD0
L 8 PL7~PL0
U 8 PU7~PU0
V 8 PV7~PV0
PV7 PV0
W 8 PW 7~PW0

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐63


The HCS12/MC9S12 Microcontroller

Interfacing
g with LEDs
ƒ An LED has an anode and cathode terminal.
ƒ The anode terminal must at a voltage at least 1.6 V above that of the cathode
terminal (forward biased) in order for the LED to be lighted.
ƒ Thee forward
o wa d current
cu e required
equ ed too light
g ana LED iss from
o a few
ew too more
o e than
a 100 mA..
ƒ The I/O pin can drive an LED using one of the circuits shown in Figure 4.15.
ƒ The resistors R1, R2, are R3 are called current-limiting resistors.

VCC VCC
Port R1
pin
R2
Port
pin
R3
74HC04
Port
(a) Positive direct drive (b) Inverse direct drive pin
(c) Buffered drive

Figure 4.15 An LED connected to a CMOS inverter through a current -limiting resistor .

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐64


The HCS12/MC9S12 Microcontroller

LED Circuit in the Draong12-Plus Demo Board


H C S1 2
1.5 K Ω
PB7

P B6

PB5

PB4

PB3

PB 2

PB 1

PB 0
PJ1

F igure 4 .1 6 C ircuit connection for Exam ple 4 .1 2

Example 4.12 Write a program to drive the LEDs shown in Figure 4.16 so that one LED is
lighted at a time from top to bottom and then from bottom to top with each LED lighted
for about 200 ms.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐65


The HCS12/MC9S12 Microcontroller

#include "C:\miniide\hcs12.inc"
org $1000
lpcnt ds.b 1
org $1500
start movb #$FF,DDRB ; configure port B for output
bset DDRJ,$02 ; configure PJ1 pin for output
bclr PTJ,$02 ; enable LEDs to light
forever movb #16,lpcnt ; initialize LED pattern count
ldx #led_tab ; Use X as the pointer to LED pattern table
led_lp movb 1,x+,PORTB ; turn on one LED
ldy #5 ; wait for half a second
jsr delayby100ms ; "
dec lpcnt ; reach the end of the table yet?
bne led_lp
bra forever ; start from beginning
led_tab dc.b $80,$40,$20,$10,$08,$04,$02,$01
dc.b $01,$02,$04,$08,$10,$20,$40,$80
#include "C:\miniide\delay.asm"
; org $FFFE ; uncomment this line for CodeWarrior
; dc.w start ; uncomment this line for CodeWarrior
end

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐66


The HCS12/MC9S12 Microcontroller

Interfacing
g with Seven-Segment
g Displays
p y
ƒ Seven-segment displays are mainly used to display decimal digits and a small set of
letters.
ƒ The HCS12 I/O port can drive a seven-segment display directly.
ƒ Buffer
u e chips
c ps are
a e used mainly
a y too save excessive
e cess ve current
cu e draw
d aw from
o thee HCS12.
CS .
ƒ A example circuit for interfacing with seven-segment display is shown in Figure 4.17.
ƒ Some people may use PB0 to PB6 to drive segment a to g instead.
ƒ The microcontroller must send an appropriate value to the output in order to display
a certain value.

H CS12 470 Ω each


a
PB6 a
PB5 b f
c b
PB4
74HC244

g
PB3 d
PB2 e e c
PB1 f d
PB0 g
com m on cathode

Figure 4.17 D riving a single seven -segm ent display

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐67


The HCS12/MC9S12 Microcontroller

Table 4.7 Decimal to seven -segment decoder


Decimal Segments Corresponding Hex Number
digit a b c d e f g Figure 4.17 circuit Dragon12 demo board

0 1 1 1 1 1 1 0 $7E $3F
1 0 1 1 0 0 0 0 $30 $06
2 1 1 0 1 1 0 1 $6D $5B
3 1 1 1 1 0 0 1 $79 $4F
4 0 1 1 0 0 1 1 $33 $66
5 1 0 1 1 0 1 1 $5B $6D
6 1 0 1 1 1 1 1 $5F $7D
7 1 1 1 0 0 0 0 $70 $07
8 1 1 1 1 1 1 1 $7F $7F
9 1 1 1 1 0 1 1 $7B $67

Displaying Multiple Seven-Segment Displays


ƒ A time-multiplexing technique is often used to display multiple digits
digits.
ƒ The circuit in Figure 4.18 can display up to six digits simultaneous using the time-
multiplexing technique.
ƒ The HCS12 lights one digit for a short period of time and then switches to the next digit.
ƒ Within one second,
second each digit is lighted in turn many times.
times Due to the
persistence of vision, all six digits appear to be lighted at the same time.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐68


The HCS12/MC9S12 Microcontroller

#0 #1 #5
800 Ω a a a
. . .
b b . . . b
.
. .
. 800 Ω g . g
. . . . g
74HC244 common common common
cathode cathode cathode

PB0
PB1

PB6
74HC367

PP0 A0 Y0

PP1 A1 Y1

PP2 A2 Y2 .
HCS12
PP3 A3 Y3 .
.
PP4 A4 Y4

PP5 A5 Y5

Figure 4.18 Port B and Port P together drive six seven -segment displays (MC9S12DG256)

To display 7 on the display #5

movb #$FF,DDRB ; configure Port B for output


movb #$3F,DDRP ; configure Port P for output
movb #$1F,PTP ; enable display #5 to be lighted
movb #$07 PTB ; send out the segment pattern of 7
#$07,PTB

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐69


The HCS12/MC9S12 Microcontroller

Example 4.14 Write a program to display 123456 on the six seven-segment displays
shown in Figure 4.18.
Solution: The values 1,2,3,4,5, and 6 are displayed on display #5, #4, …, #0, respectively.
A table is set up to control the pattern and digit selection as shown in Table 4.8.
Table 4.8
4 8 Table of display patterns for Exam ple 4.14
4 14
Seven-Segm ent Displayed
Port B Port P
Display BCD Digit
#5 1 $06 $1F
#4 2 $5B $2F
#3 3 $4F $37
#2 4 $66 $3B
#1 5 $6D $3D
#0 6 $7D $3E

#include
#i l d ""c:\miniide\hcs12.inc"
\ i iid \h 12 i "
org $1500
start lds #$1500
movb #$FF,DDRB
movbb #$3F DDRP
#$3F,DDRP
forever ldx #DispTab ; set X to point to the display table
loopi movb 1,x+,PTB ; output segment pattern
movb 1,x+,PTP ; output display select
ld
ldy #1
jsr delayby1ms ; wait for 1 ms

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐70


The HCS12/MC9S12 Microcontroller

cpx #DispTab+12 ; reach the end of the table?


bne loopi
bra forever
#include "c:\miniide\delay.asm"
DispTab dc.b $06,$1F
dc.b $5B,$2F
dc.b $4F,$37
dc.b $66,$3B
dc.b $6D,$3D
dc.b $7D,$3E
; org $FFFE ; uncomment this line for CodeWarrior
; dc.w start ; uncomment this line for CodeWarrior
end

Generating a Digital Waveform Using an I/O Pin


ƒ A square wave can be generated by pulling a pin to high for certain amount of time and
then ppull it to low for the same amount of time and repeat.
p
ƒ By connecting the pin to a speaker and making the frequency in the audible range, a
sound can be made.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐71


The HCS12/MC9S12 Microcontroller

Example 4.15 Write a program to generate a 1-kHz periodic square wave from the PT5 pin.
Solution:
#include "c:\miniide\hcs12.inc"
org $1500
start lds #$1500
bset DDRT,BIT5 ; configure PT5 pin for output
forever bset PTT,BIT5 ; pull PT5 pin to high
ldy #10 ; wait for 0.5 ms
jsr delayby50us ; “
bclr PTT,BIT5 ; pull PT5 pin to low
ldy #10 ; wait for 0.5 ms
jsr delayby50us ; “
bra forever
#include "c:\miniide\delay.asm"
; org $FFFE
; dc.w start
end

Example 4.16 Write a program to generate a two-tone siren that alternates between 250
Hz and 500 Hz with each tone lasting for half of a second.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐72


The HCS12/MC9S12 Microcontroller

#include "c:\miniide\hcs12.inc"
org $1500
start lds #$1500
bset DDRT,BIT5 ; configure PT5 pin for output
forever ldx #250 ; repeat 500 Hz waveform 250 times
tone1 bset PTT,BIT5 ; pull PT5 pin to high
ldy #1
jsr delayby1ms
bclr PTT,BIT5
ldy #1
jsr delayby1ms
dbne x,tone1
ldx #125 ; repeat 250 Hz waveform for 125 times
tone2 bset PTT,BIT5
ldy #2
jsr delayby1ms
bclr PTT,BIT5
ldy #2
jsr delayby1ms
dbne x,tone2
bra forever
#include "c:\miniide\delay.asm"
end

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐73


The HCS12/MC9S12 Microcontroller

I t f i with
Interfacing ith DIP S
Switches
it h
ƒ A dual-in-line package can be connected any port with 8 pins.
ƒ A set of pull-up resistors are needed to pull the voltage to high on one side of the DIP.
V CC

SW DIP-8 10 KΩ
HCS12
PA0
PA1
PA2
PA3
PA4
PA5
PA6
PA7

Figure 4.19 Connecting a set of eight DIP switches to Port A of the HCS 12

To read data into accumulator A

movb #0,DDRA ; configure port A for input


ldaa PTA ; read into accumulator A

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐74


The HCS12/MC9S12 Microcontroller

Tips
p for Program
g Debugging
gg g Involving
g Subroutine Calls

What to do when the program gets stuck?


Step 1
Find out which subroutine gets stuck by setting a breakpoint immediately after the jsr
or bsr instruction.
Step 2
Find out why the subroutine gets stuck.
- Forgetting to restore registers pushed onto the stack before return.
- Forgetting to deallocate local variables before return.
- There are some infinite loops in the subroutine.
- Calling other subroutines that do not return.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐75


The HCS12/MC9S12 Microcontroller

General Debugging
gg g Strategy
gy
1. Make sure all leaf subroutines work correctly by using the methods described in Section
2.9.
2. Debugg intermediate subroutines. Make sure no intermediate subroutines gget stuck.
3. Debug the top level program.

Copyright © 2010 Delmar Cengage Learning H. Huang Transparency No.4‐76

You might also like